I'm porting CGI::Application to Perl6 as a way to learn about Perl6. I'm going to share some of these "real world" refactors here to demonstrate some Perl6 features.
Before:
We have a a typical Perl5 if/else chain. The dangling "if" and "die" and at the end should have really be part of the chain, but I did say this was real-world code...
sub _send_headers { my $self = shift; my $q = $self->query();
my $header_type = $self->header_type();
if ($header_type eq 'redirect') { return $q->redirect($self->header_props()); } elsif ($header_type eq 'header' ) { return $q->header($self->header_props()); }
# croak() if we have an unknown header type croak ("Invalid header_type '$header_type'") unless ($header_type eq "none");
# Do nothing if header type eq "none". return ""; }
method _send_headers { my $q = self.query; given self.header_type { when 'redirect' { return $q.redirect(self.header_props) } when 'header' { return $q.header(self.header_props) } when 'none' { return "" } default { die "Invalid header_type '$header_type'" } } }
sub _send_headers {
my $self = shift;
my $q = $self->query();
my $header_type = $self->header_type();
return
$header_type eq 'redirect' ? $q->redirect($self->header_props())
: $header_type eq 'header' ? $q->header($self->header_props())
: $header_type eq 'none' ? ''
: croak("Invalid header_type '$header_type'")
}
Re:A Perl5 refactoring (winner!)
markjugg on 2006-08-17T13:04:54
Thanks Chris, I like this refactor the best.
I commited a variation of this to the CGI::Application p5 source tree.Re:A Perl5 refactoring (winner!)
ChrisDolan on 2006-08-17T14:17:46
Thank Damian Conway. I picked up this hanging ternary style of indentation from his "Perl Best Practices" book. I use it instead of if/elsif/else whenever possible now.
Re:More perl 5 refactoring
reneeb on 2006-08-17T06:34:15
That's not correct in detail. The _default_ action will be executed if the headertype is undef or 0, but what about "illegal" headertypes - e.g. 'foo' ?
This would be better:
sub send_headers { my $self = shift; my $q = $self->query; my %actions = ( redirect => sub { $q->redirect( $self->header_props ) }, header => sub { $q->header($self->header_props()) }, none => sub { return '' }, _default_ => sub { croak "Invalid header_type " . $self->$header_type } );
my $headertype = exists $actions{$self->header_type} ? $self->header_type : '_default_'; return $actions{ $headertype }->(); }Re:More perl 5 refactoring
reneeb on 2006-08-17T06:37:14
Sorry, pushed the wrong button...sub send_headers {
my $self = shift;
my $q = $self->query;
my %actions = (
redirect => sub { $q->redirect( $self->header_props ) },
header => sub { $q->header($self->header_props()) },
none => sub { return '' },
_default_ => sub { croak "Invalid header_type " . $self->$header_type } );
my $headertype = exists $actions{$self->header_type} ? $self->header_type : '_default_';
return $actions{ $headertype }->();
}