Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^2: Refactoring Perl #7 - Remove Assignments to Parameters

by agianni (Hermit)
on Aug 23, 2007 at 15:22 UTC ( #634667=note: print w/ replies, xml ) Need Help??


in reply to Re: Refactoring Perl #7 - Remove Assignments to Parameters
in thread Refactoring Perl #7 - Remove Assignments to Parameters

OK, so I am confused, what about this:

my $var = 'foo'; warn $var; # prints foo by_val( $var ); warn $var; # prints foo by_ref( \$var ); warn $var; # prints bar sub by_ref{ my $var_ref = shift; $$var_ref = 'bar'; } sub by_val{ my $var = shift; $var = 'bar'; }

My understanding was that this is PbV and PbR respectively. Your post suggests that Perl is always PbR, so does that mean that my pass by value example is just allowing me to fake PbV? Or is the difference more of a technical, low level detail?

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


Comment on Re^2: Refactoring Perl #7 - Remove Assignments to Parameters
Select or Download Code
Re^3: Refactoring Perl #7 - Remove Assignments to Parameters
by ikegami (Pope) on Aug 23, 2007 at 15:28 UTC

    by_val does not modify its parameter ($_[0]), it modifies a copy of its parameter ($var). Without realizing it, you've used the very refactoring tool you are trying to present to us (my $var = shift;).

    Using a temporary variable instead of assigning to (or even reading from) a parameter is standard practice in Perl!

    Update: Example:

    sub inc_original { $_[0]++; return $_[0]; } sub inc_refactored { my ($var) = @_; $var++; return $var; } { my $i = 3; my $j = inc_original($i); print("$i + 1 = $j\n"); # 4 + 1 = 4 } { my $i = 3; my $j = inc_refactored($i); print("$i + 1 = $j\n"); # 3 + 1 = 4 }

      Excellent! I guess this refactoring pattern maps nicely to TheDamian's Always unpack @_ first best practice (PBP, p. 178).

      Update: Actually, after thinking about it a bit, it doesn't map exactly. Consider:

      my $array_ref = [ qw( 1 4 9 10 15 23 34 84 100 ) ]; add_n_to_values_and_print( $array_ref, 15 ); sub add_n_to_values_and_print{ my ( $list, $add ) = @_; for my $value ( @$list ){ $value += $add; print $value; } }

      This follows Mr. Conway's admonition to unpack @_ but it doesn't accomplish the goal of avoding changes to the reference passed in that Fowler is after. What we really need to do is:

      my $array_ref = [ qw( 1 4 9 10 15 23 34 84 100 ) ]; add_n_to_values_and_print( $array_ref, 15 ); sub add_n_to_values_and_print{ my ( $list, $add ) = @_; # dereference and work with a local copy of the array my @local_list = @$list; for my $value ( @local_list ){ $value += $add; print $value; } }

      Truthfully, that's not a very good example, as I wouldn't generally write code that actually updates the value I would probably write print $value + $add, but for the sake of an example...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://634667]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2014-09-17 22:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (100 votes), past polls