http://qs321.pair.com?node_id=1130882

saintmike has asked for the wisdom of the Perl Monks concerning the following question:

Can anyone explain why the @options array in the following code snippet doesn't gobble up the empty field at the end?
my $str = "foo:bar:"; my( $a, @options ) = split /:/, $str; my( $b, $c, $d ) = split /:/, $str; use Data::Dumper; print Dumper( [ $a, \@options ] ); print Dumper( [ $b, $c, $d ] );
$VAR1 = [ 'foo', [ 'bar' ] ]; $VAR1 = [ 'foo', 'bar', '' ];
This seems to have to do with split(), as
my( $a, @options ) = ( "foo", "bar", "" ); my( $b, $c, $d ) = ( "foo", "bar", "" ); use Data::Dumper; print Dumper( [ $a, \@options ] ); print Dumper( [ $b, $c, $d ] );
gobbles up everything correctly:
$VAR1 = [ 'foo', [ 'bar', '' ] ]; $VAR1 = [ 'foo', 'bar', '' ];

Replies are listed 'Best First'.
Re: Mystery interaction between split and gobbling arrays
by toolic (Bishop) on Jun 17, 2015 at 20:52 UTC

    Tip #6 from the Basic debugging checklist... B::Deparse

    use strict 'refs'; my $str = 'foo:bar:'; my($a, @options) = split(/:/, $str, 0); my($b, $c, $d) = split(/:/, $str, 4); use Data::Dumper; print Dumper([$a, \@options]); print Dumper([$b, $c, $d]);

    Notice how the 2 split lines have different LIMIT values (0 and 4).

    when assigning to a list, if LIMIT is omitted (or zero), then LIMIT is treated as though it were one larger than the number of variables in the list
      Wow, nice find, thanks for that. I'm pretty sure that setting the limit to 4 in the first case saves some cpu cycles, but setting it to 0 in the second case is pretty crazy, given the special behavior of split() in this case.

      Here's one more: What's the difference between

      ( $a, $b, $c ) = split /:/, $str;
      and
      ( $a, $b, $c, @options ) = split /:/, $str;
      when $str = "foo:bar:"?

      Spoiler: Adding @options to the left hand side makes $c undef'd!

Re: Mystery interaction between split and gobbling arrays
by Discipulus (Canon) on Jun 17, 2015 at 20:58 UTC
    I was in your same pitfall some years ago, then i learned to double check the the docs if something looks strange:
    If LIMIT is omitted (or, equivalently, zero), then it is usually treat +ed as if it were instead negative but with the exception that trailin +g empty fields are stripped (empty leading fields are always preserve +d);
    The output you want can be obtained with a -1 LIMIT:
    perl -MData::Dumper -e "$str='foo:bar:'; ($x,@opt)=split /:/,$str,-1;p +rint Dumper ($x,\@opt)" $VAR1 = 'foo'; $VAR2 = [ 'bar', '' ];

    HtH
    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Mystery interaction between split and gobbling arrays
by kcott (Archbishop) on Jun 17, 2015 at 21:03 UTC

    G'day saintmike,

    The behaviour's the same without split:

    $ perl -E 'my ($x, @y) = (1,2,); say $#y' 0

    or even

    $ perl -E 'my ($x, @y) = (1,2,,,,,); say $#y' 0

    -- Ken

      One or more trailing commas in a list do absolutely nothing, so I'm not sure how this is related.

        The question was why doesn't the array "gobble up the empty field at the end?". I was merely showing that an array won't gobble up one or many empty fields at the end.

        In fact, an array won't gobble up empty fields at the start, middle or end:

        $ perl -E 'my ($x, @y) = (1,2,,3); say $#y' 1 $ perl -E 'my ($x, @y) = (1,2,,,,3,); say $#y' 1 $ perl -E 'my ($x, @y) = (1,,,,,,2,,,,,); say $#y' 0

        Your question only showed the 2-argument form of split; however, answers with the 3-argument form seemed more to your liking.

        I expect the underlying problem may be the huge disconnect that sometimes occurs when people communicate in a common language. :-)

        -- Ken