4 ms·
His problem has nothing to do with commas at all. my (@array1, @array2) = ...; will always assign all of the right side to the first array. This is just the w
by simcop2387 8y ago
His problem has nothing to do with commas at all. my (@array1, @array2) = ...; will always assign all of the right side to the first array. This is just the way perl works with assigning lists to arrays. There's a few other ways you can do this instead.
# with array references
my ($arr_ref1, $arr_ref2) =
(index($str2, '-') != -1) ?
([split /-/,$str2], [split /;/, $str4]) :
([split /:/,$str2], [split /;/, $str4]);
The above will assign two array references to each scalar variable.
The other option is similar but only works in newer perls with a feature called "refaliasing" and "declared_refs", which are still considered experimental, but which are expected to be marked as stable in 5.30 (If my memory serves)
use feature qw/refaliasing declared_refs/;
my (\@arr1, \@arr2) =
(index($str2, '-') != -1) ?
([split /-/,$str2], [split /;/, $str4]) :
([split /:/,$str2], [split /;/, $str4]);
This takes the array references and assigns binds them to the arrays similar to what the author originally intended.
This is a result of the same problem that perl's default argument passing has with list flattening.
sub foo {
my (@a, @b) = @_; # load the arguments that were passed into the subroutine
...
}
foo(@data, @names);
That will result in both sets of values to be assigned to @a and nothing in @b, because @a ends up consuming everything.
Ref-aliasing with perl's prototypes will allow you to make this work like you might expect if you aren't experienced with perl's quirks but generally when you see this pattern you should be passing a reference to begin with and not trying to use the "magic" to hide that from the callers.
You can play around with these examples in an pastebin that allows running live perl code (server side), here https://perl.bot/p/gblj94 https://perl.bot/p/gblj94
EDIT: fix the code slightly, and provide interactive pastebin.
- simcop2387 8y agoA slightly bizarre version of this that nobody should ever use. If you see someone doing this, tell them they are a bad programmer and shouldn't be putting code into production. It's also unlikely that this would actually be useful for the real code in the authors situation because it ends up mostly limited, but the technique can be useful even if this example shouldn't be done this way. # declare our arrays my @arr1; my @arr2; # alias specific elements to the arrays my \$first = \$arr1[0]; my \$second = \$arr1[1]; my \$third = \$arr2[0]; my \$fourth = \$arr2[1]; # assign to those aliases. note the , 2) added to each split. This forces each split to only ever produce two values. ($first, $second, $third, $fourth) = (index($str2, '-') != -1) ? (split(/-/,$str2,2), split(/;/, $str4, 2)) : (split(/:/,$str2,2), split(/;/, $str4, 2)); This is bad code simply because you're unrolling the arrays and not using things the way you should in the language. But this does demonstrate how refaliasing can be useful for doing some other weirdly specific things. This also works for things inside hashes and other perl data structures.