WeBWorK Main Forum

perl parameter passing help

perl parameter passing help

by Darwyn Cook -
Number of replies: 4
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?
In reply to Darwyn Cook

Re: perl parameter passing help

by Djun Kim -
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



In reply to Darwyn Cook

Re: perl parameter passing help

by Davide Cervone -
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

In reply to Darwyn Cook

Re: perl parameter passing help

by Davide Cervone -
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

In reply to Davide Cervone

Re: perl parameter passing help

by Darwyn Cook -
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!