Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

You have a code fragment that can be grouped together

Turn the fragment into a method whose name explains the purpose of the method

(Fowler, p.110)

Fowler's first refactoring pattern is probably the most intuitive and the one I use 90% of the time when I'm refactoring. That's part of the reason I'm going through these patterns, because I know there are plenty of other useful ones out there (there are 72 in the book after all).

Here is Fowler's example in Perl code:

sub print_owing{ my $self = shift; my $e = $self->{_orders}->elements(); my $outstanding = 0.0; # print banner print "**************************\n"; print "***** Customer Owes ******\n"; print "**************************\n"; # calculate outstanding while ( $e->has_more_elements() ){ my $each = $e->next_element(); $outstanding += $each->get_amount(); } # print details print 'name: ', $self->{_name}, "\n"; print "amount: $outstanding\n"; }


sub print_owing{ my $self = shift; $self->print_banner(); my $outstanding = $self->get_outstanding(); $self->print_details( $outstanding ); } sub print_banner{ my $self = shift; # print banner print "**************************\n"; print "***** Customer Owes ******\n"; print "**************************\n"; } sub print_details{ my $self = shift; my $outstanding = shift; print 'name: ', $self->{_name}, "\n"; print "amount: $outstanding\n"; } sub get_outstanding{ my $self = shift; my $e = $self->{_orders}->elements(); my $result = 0.0; # calculate outstanding while ( $e->has_more_elements() ){ my $each = $e->next_element(); $result += $each->get_amount(); } return $result; }

Fowler outlines the intricacies through example in three steps but I won't go into that much detail here because I think it's pretty straight forward. You should really buy the book if you're interested. The code with tests include the steps in the refactoring process so you can see the whole thing in Perl.

Instead, I'd like to discuss how I've written the unit tests for the example, as testing is an important part of the refactoring process and writing tests for the refactoring patterns will likely require some decent understanding of Perl unit testing methodologies.

There are three non-standard modules that I use in the tests for this code: Test::MockModule, Test::MockObject and Test::Output. The first two are very useful for working with tests for incomplete modules / classes -- which is the case here -- or situations where you don't want to do a great deal of setup of environmental factors just to test a single method / subroutine. Test::Output is very useful to testing code that generates STDOUT or STDERR as this code does. In order to run these tests, you'll need these three modules. I highly recommend Ian Langworth and chromatic's Perl Testing, A Developer's Notebook if you're not comfortable with writing and maintaining tests.

In the case of the test for Refactoring::ExtractMethod::*, I use Test::MockModule to mock up a new method rather than include it in the class itself. I also used Test::MockObject to put together a quick and dirty object for the _orders object variable. For the purpose of this example it may be overkill, but this is generally how I like to write my tests: isolate the test to the functionality of the method we are testing. Of course this will come back to bite me in the very next refactoring example, but we'll get to that later :)

For now I'll be keeping one tarball of all of the code and I'll update it when I have additional code to share. I'm not sure that's a good long term option, and I'm open to suggestions -- I might CPAN it if I can maintain momentum here.

I welcome comments and conversation on all aspects of this example: implementation of the example in Perl, testing methodology, tactics for maintaining this series of posts, what have you.

perl -e 'split//,q{john hurl, pest caretaker}and(map{print @_[$_]}(joi +n(q{},map{sprintf(qq{%010u},$_)}(2**2*307*4993,5*101*641*5261,7*59*79 +*36997,13*17*71*45131,3**2*67*89*167*181))=~/\d{2}/g));'

In reply to Refactoring Perl #1 - Extract Method by agianni

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others chanting in the Monastery: (7)
    As of 2018-05-23 08:06 GMT
    Find Nodes?
      Voting Booth?