On 05/20/2012 08:09 AM, sono-io wrote:
Are there any differences between these two idioms if only one or zero
arguments are passed to them?
my ($mode) = @_;
my $mode = shift;
If your subroutine needs to know how many arguments were passed, the
former style (assignment) makes this trivial. Once @_ has been shifted
(latter style), I don't know an easy way to determine if zero or one
argument was passed (stack crawling?).
But, this is Perl and there are more than two ways to do it -- you can
also access the argument array (@_) directly within your subroutine:
1. Might save some CPU cycles and/or memory. Be sure to benchmark this
claim, to see if it's worth the loss of clarity provided by well-named
internal variables.
2. Provides call-by-reference semantics -- your subroutine can modify
the caller's variables (intentionally or otherwise -- beware!).
3. Auto-vivifies missing arguments (?).
4. Blows up if the subroutine tries to modify read-only arguments.
I started using this technique for #1, but soon tripped over the risks
of #2. I'm not sure if I was aware of #3 and #4 prior to writing the
test code, below.
I also tried testing functions with array arguments -- changing elements
(yes, that works) and changing the array length (I got confused).
I concur with Rob's advice for object methods:
On 05/20/2012 08:30 AM, Rob Dixon wrote:
> my $self = shift;
> my ($arg1, $arg2) = @_;
Note that Moose around method modifiers use a shift, shift, assignment
style.
As always, there is no single best approach for all cases:
1. Do what makes sense when you write the code, and
2. Try to be consistent so that it is easier to debug and maintain the
code later.
HTH,
David
--
2012-05-20 14:08:47 dpchrist@p43400e ~/sandbox/perl
$ cat function_arguments.pl
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Terse = 1;
$| = 1;
sub f_assign {
my ($a) = @_;
$a += 1;
}
sub f_direct {
$_[0] += 1;
}
sub f_shift {
my $a = shift;
$a += 1;
}
# main
{
for my $f (qw( f_assign f_shift f_direct )) {
my $y = eval { no strict 'refs'; $f->() };
print "$f() ", $@
? "throws exception: $@"
: 'returns ' . Data::Dumper->Dump([$y], [qw(y)]);
$y = eval { no strict 'refs'; $f->(10) };
print "$f(10) ", $@
? "throws exception: $@"
: 'returns ' . Data::Dumper->Dump([$y], [qw(y)]);
my $xx = my $x = 100;
print '$x = ', Data::Dumper->Dump([$x], [qw(x)]);
$y = eval { no strict 'refs'; $f->($x) };
print "$f(\$x) ", $@
? "throws exception: $@"
: 'returns ' . Data::Dumper->Dump([$y], [qw(y)]);
print '### side effect: $x is now ',
Data::Dumper->Dump([$x], [qw(x)])
if $x != $xx;
}
}
2012-05-20 14:08:49 dpchrist@p43400e ~/sandbox/perl
$ perl function_arguments.pl
f_assign() returns 1
f_assign(10) returns 11
$x = 100
f_assign($x) returns 101
f_shift() returns 1
f_shift(10) returns 11
$x = 100
f_shift($x) returns 101
f_direct() returns 1
f_direct(10) throws exception: Modification of a read-only value
attempted at function_arguments.pl line 12.
$x = 100
f_direct($x) returns 101
### side effect: $x is now 101
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/