perl - Perl5: returning several arrays/hashes from a sub -


i wanna return several arrays , hashes sub. when execute sub, first output array wraps outputs toguether , others keep empty. pls see example:

the main file script.pl has:

use mymodule; (@o1, $o2)=mymodule::mysub; print "o1 gives ".$o1[0]."  ".$o1[1]."  ".$o1[2]; print ", , o2 gives ".$o2."  \n"; 

file mymodule.pm looks like:

package mymodule; sub mysub{    @a = ('a', 'b');    $b = 4;    return (@a, $b);    }; 1; 

running script.pl return o1 gives b 4, , o2 gives .

as see, correspondence of (@o1, $o2) values (@a, $b) returned module not preserved.

can me here? thx lot!


thx explanation. cannot obtain aimed result thru suggestion. code:

my ($o1_ref, $o2)=mysub; @o1 = @{$o1_ref}; print "o1 has ".$#o1." elements, o2 has ".$#o2." elements\n"; print "the first element of o1 ".$o1->[0]."\n";  sub mysub{    @a = ('a', 'b');    $b = 4;    return (\@a, $b);    }; 

will return

o1 has -1 elements, o2 has -1 elements first element of o1  

thus not work perl 5.14.

it's time learn references.

in perl, can return a single list of items subroutine or have a single list of items import. single list, if attempt return 2 arrays, perl put them single undifferentiated list:

use strict; use warnings; use feature qw(say);  (@a, @b) = foo(); join ": ", @a; join ": ", @b;  sub foo {     @first = qw(one 2 thee);     @second = qw(uno dos tres);     return (@first, @second); } 

if run this, see of data returned @a , nothing in @b.

references allow around restriction. reference pointer place in memory contains data. data scalar ($foo), array (@foo), or hash (%foo). since location in memory single bit of data, references allow have array contains references other arrays giving array of arrays. or array of hashes, or hash of hashes, or sorts of more complex data structures.

let's @ module , modify it's code wee bit:

sub mysub{    @a = ('a', 'b');    $b = 4;    return (\@a, $b);  # added backslash! }; 1; 

that backslash says not returning array. instead, returning location in memory array lives.

now program can this:

my ($o1_ref, $o2) = mymodule::mysub();   # we'll talk later.. 

another slight change in code. first item i'm returning isn't array, reference array. now, have dereference (that allows me access array):

my @o1 = @{ $o1_ref }; 

you dereference putting sigil of data structure in front of reference. have done this:

my @o1 = @$o1_ref; 

i don't because it's easy miss @$ combination. using curly braces emphasizes dereferencing array reference.

now, rest of program should work.


bonus advice

take @ exporter module. it's standard module comes perl.

this allow export functions module, don't have prefix module's name:

package mymodule;              # custom says give modules capital names.  use strict; use warnings; use exporter qw(import);  our @export_ok = qw(mysub);  # list of subroutines want main use 

sub mysub { @a = qw(a b); $b = 4; return (\@a, $b); } 1;

now, have mysub in main program:

use strict; use warnings; use mymodule  qw(mysub);     # include list of want imported use feature qw(say);          # better "print" "print"  ($o1_ref, $o2) = mysub(); @01 = @{ $o1_ref }; "o1 gives ".$o1[0]."  ".$o1[1]."  ".$o1[2]; 

in response this

here's code:

my ($o1_ref, $o2)=mysub; @o1 = @{$o1_ref}; print "o1 has ".$#o1." elements, o2 has ".$#o2." elements\n"; print "the first element of o1 ".$o1->[0]."\n";  sub mysub{    @a = ('a', 'b');    $b = 4;    return (\@a, $b); }; 
  • there's no array @o2, $#o2 invalid.
  • $# returns last index , not number of items. use scalar function number of items in array.
  • you've dereferenced @o1. did simplify problem. now, you're dereferencing deferenced item when $o1->[0]. way $o1 doesn't exist variable.
  • always use strict , warnings pragmas. you'd catch lot of errors when use these.
  • use say instead of print. forgot \n on end again. if you're going that, use say use feature qw(say);

corrected code

use strict; use warnings; use feature qw(say);  ($o1_ref, $o2) = mysub(); @o1 = @{$o1_ref};  "\@o1 has " . scalar @o1 . " elemenets"; "the first element of \@o1 '$o1[0]'"; "the second element of \@o1 '$o1[1]'"; "\$o2 equal  '$o2'";  sub mysub{     @a = ('a', 'b');     $b = 4;     return (\@a, $b); }; 

the output:

@o1 has 2 elemenets first element of @o1 'a' second element of @o1 'b' $o2 equal  '4' 

all correct.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -