in reply to Scalar and void subroutines
You could avoid some duplication by using the following syntax:
sub name { my $arg = ref $_[0] ? $_[0] : \do{my $anon = $_[0]}; # Do stuff. $$arg =~ s/^un//; return $$arg; }
or using an alias instead of a reference:
sub name { our $arg; local *arg = ref($_[0]) ? $_[0] : \do{my $anon = $_[0]}; # Do stuff. $arg =~ s/^un//; return $arg; }
Test code:
$i = $j = 'unchanged'; name(\$i); print("i:$i\n"); # i:changed $i = $j = 'unchanged'; $j = name($i); print("i:$i, j:$j\n"); # i:unchanged, j:changed $i = $j = 'unchanged'; $j = name(\$i); print("i:$i, j:$j\n"); # i:changed, j:changed
You could also check the calling context and avoid reference altogether:
sub name { our $arg; local *arg = defined wantarray ? \do{my $anon = $_[0]} : \$_[0]; # Do stuff. $arg =~ s/^un//; return $arg; }
but I'd avoid that since the it's not obvious what's going to happen when reading the call:
name($i); # In place $j = name($i); # Not in place sub test { name($_[0]) } # unknown!!! sub test { name($_[0]) } test($i); # In place sub test { name($_[0]) } $j = test($i); # Not in place
Update: Showed why wantarray is a bad idea instead of just saying it is.
Update: Fixed bug found by eff_i_g. That'll teach me to test without warnings.
Update: Oops, I forgot I should be able to read the argument, not just write to it. Fixed by changing \do{my ...} to \do{my ... = $_[0]}.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Scalar and void subroutines
by eff_i_g (Curate) on Nov 10, 2005 at 21:36 UTC | |
|
Re^2: Scalar and void subroutines
by eff_i_g (Curate) on Nov 10, 2005 at 22:54 UTC | |
by ikegami (Patriarch) on Nov 10, 2005 at 23:12 UTC | |
by eff_i_g (Curate) on Nov 10, 2005 at 23:18 UTC |