Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of markjugg (792)

Wednesday August 16, 2006
08:52 PM

refactoring CGI::App for Perl6:'given' as a switch statement

[ #30663 ]
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 "";
}

After:
Of course, "my $self = shift" is gone, (Wahoo!), but notice now the new 'given' switch statement cleans things up nicely:

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'" }
    }
}

In total: 18 lines reduced to 9, with a clarity gained!

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Here's a way to refactor the code legibly in Perl5 without 'given':


            sub _send_headers {
                    my $self = shift;
                    my $q = $self->query();

                    my $header_type = $self->header_type();

                    return
                         
  • 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 '' },
                   
    • 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_ => s
      • 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 '' },