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

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 }

Replies are listed 'Best First'.
Re^4: Refactoring Perl #7 - Remove Assignments to Parameters
by agianni (Hermit) on Aug 23, 2007 at 15:57 UTC

    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...