Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Refactoring Perl #5 - Introduce Explaining Variable

by agianni (Hermit)
on Aug 02, 2007 at 18:21 UTC ( [id://630355]=perlmeditation: print w/replies, xml ) Need Help??

You have a complicated expression.

Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.

(Fowler, p. 124)

This refactoring pattern proves that context is the key refactoring decisions as it presents the exact opposite of the technique suggested in Inline Temp. Here's what it looks like using List::Util qw( min max ):

sub price{ my $self = shift; # price is base price - quantity discount + shipping return $self->{_quantity} * $self->{_item_price} - max( 0, $self->{_quantity} - 500) * $self->{_item_price} * 0.05 + min( $self->{_quantity} * $self->{_item_price} * 0.1, 100.0); }

becomes:

sub price{ my $self = shift; my $base_price = $self->{_quantity} * $self->{_item_price}; my $quantity_discount = max( 0, $self->{_quantity} - 500) * $self->{_item_price} * 0.05; my $shipping = min( $self->{_quantity} * $self->{_item_price} * 0.1, 100.0); return $base_price - $quantity_discount + $shipping; }

Get the code

Interestingly enough, Fowler immediately follows this example with the following disclaimer:
For this example, I usually wouldn't have done the explaining temps; I would prefer to do that with Extract Method (p. 126)

and he goes on to show the refactoring using that technique. Fowler suggests that the appropriate time to use this technique is when "Extract Method is more effort" (p. 127). Obviously it's up to the programmer to decide what "more effort" is, but in my mind it'll be much of the time. In other words, this will generally be a better option than Extract Method unless the temps would be useful if shared through a method.

Another nice side effect, if not one of the primary intended effects of this technique is that it makes your code self-documenting. The comment at the top of the original code is unnecessary in the refactored version, as the last line essentially says the same thing explicitly in Perl.

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));'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://630355]
Approved by FunkyMonk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-03-28 16:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found