I was hoping someone could help with the ins and outs of parameter passing in Perl. I am trying to use Perl 5 style positional parameters to pass an exponent and two arrays of numbers to a subroutine. The arrays are causing me trouble, which I guess amounts to a referencing/dereferencing issue somewhere along the line. Anyhow, here is a simplified version of the code:
sub Snxy()
{
my ($args) = @_;
my @x = $args->{inputs};
my @y = $args->{outputs};
my $n = $args->{n};
return $x[1];
}
$S = Snxy({n=>'1',inputs => (1,2,3),outputs => (4,5,6)});
Why isn't $S = 2?
Darwyn,
your parameters are getting flattened. If you have a look (for example using Data::Dumper) you'll see that your argument is actually passed as
("n", 1, "input", 1, 2, 3, "output", 4, 5, 6)
which is interpreted as
{n=>1, input=>1, 2=>3, output=>4, 5=>6}
Cheers, Djun
As Djun points out, arrays are flattened when passed as arguments. You want to pass an array reference rather than an array itself. That is done using square brackets, not round ones, so you should use
$S = Snxy({n=>'1',inputs => [1,2,3],outputs => [4,5,6]});Then in the subroutine, you need to de-reference those arrays. There are several ways that can be done. Using
@{...}
around an array reference gets you the array:
sub Snxy() { my ($args) = @_; my @x = @{$args->{inputs}}; my @y = @{$args->{outputs}}; my $n = $args->{n}; return $x[1]; }Or using
$a->[$i]
gets you an element out of an array reference:
sub Snxy() { my ($args) = @_; my $x = $args->{inputs}; my $y = $args->{outputs}; my $n = $args->{n}; return $x->[1]; }It is up to you which way you prefer.
Hope that helps.
Davide
Another thing you could consider is not passing a hash reference, but just the hash itself (as it done with many of the WeBWorK macros). So you could do
$S = Snxy(n => '1', inputs => [1,2,3], outputs => [4,5,6]);without the braces and then use
sub Snxy() { my %args = @_; my @x = @{$args{inputs}}; my @y = @{$args{outputs}}; my $n = $args{n}; return $x[1]; }I think this makes passing the arguments easier, but it's up to you.
Davide
There we go! I used Davide's last suggestion, might as well use a similar format to other WeBWorK macros. Thanks a lot for the help!