Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Array mysteriously growing

by AntsPants (Novice)
on Mar 09, 2006 at 15:01 UTC ( [id://535403]=perlquestion: print w/replies, xml ) Need Help??

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

I have a list, and sometimes I want to read-ahead (next element) in the list and compare it to my current element (while the index stays on my current element)

If there's a next element (i.e. I'm not out of bounds) then I'll grab a value. If there's no next element then I'm done.

This works ..........

my $next_version_key = $ordered_list->[($i+1)]->[0] if( $ordered_list->[($i+1)] );
but then I thought I'd try ............
my $next_version_key = $ordered_list->[($i+1)]->[0] || undef;
and that added ..........
[] to @{ $ordered_list }
which meant my list had grown. The next time round, it added ......
[ undef, {} ]
next time round ..............
[ ${\$VAR1->[3][0]}, {} ]
usw. The same happens if I use ............
my $next_version_key = $ordered_list->[($i+1)]->[0] || 0;
Now, it seems as though $ordered_list->[($i+1)]->[0] is evalutaing to true even though it's out-of-bounds but what strange behaviour!!

Can someone throw some light on that for me? This isn't critical as I'm using ...

my $next_version_key = $ordered_list->[($i+1)]->[0] if( $ordered_list->[($i+1)] );
which my prefered way .... I'm just interested in the internals with this prob.

Cheers -Ants

Replies are listed 'Best First'.
Re: Array mysteriously growing
by swkronenfeld (Hermit) on Mar 09, 2006 at 15:17 UTC
    With your first method
    my $next_version_key = $ordered_list->[($i+1)]->[0] if( $ordered_list->[($i+1)] );
    The if is evaluated first, comes out to false, and the $ordered_list->[($i+1)]->[0] is never evaluated.

    With your second method, the $ordered_list->[($i+1)]->[0] is evaluated first. Even if this value does not exist, it is autovivified.
Re: Array mysteriously growing
by ikegami (Patriarch) on Mar 09, 2006 at 15:24 UTC

    This post doesn't answer your question; it's about an error in your code.

    Don't use
    my $var = ... if ...;
    Use
    my $var; $var = ... if ...;
    The former can leave Perl's guts in a twist.

Re: Array mysteriously growing
by duff (Parson) on Mar 09, 2006 at 15:59 UTC

    This also doesn't answer your question, but rather than checking if there's a "next element" in your array, check that your index hasn't gone beyond the end of your array:

    $next_version_key = $ordered_list->[$i+1]->[0] if $i+1 < @{$ordered_li +st};

      Depending what appears more natural to you, you can also check this as

      if $i < $#$ordered_list;

        Aye. I prefer the way I did it because it uses $i+1 in both places.

Re: Array mysteriously growing (autovivification explained)
by Aristotle (Chancellor) on Mar 11, 2006 at 07:47 UTC

    Congratulations, you have stumbled onto autovivification. :-) To expand on swkronenfeld’s point, this always happens when you dereference an undefined value “en passant”:

    undef $_; $_->[0]; print $_; __END__ ARRAY(0x812f180)

    This is so you can build deep structures without a lot of checks:

    my %bill; while( <$records_fh> ) { my ( $time, $worker, $project ) = split /\t/, $_; push @{ $bill{ $project }{ $worker } }, $time; }

    If Perl didn’t autovivify, you would have to write this like so:

    my %bill; while( <$records_fh> ) { my ( $time, $worker, $project ) = split /\t/, $_; $bill{ $project } = {} if not exists $bill{ $project }; $bill{ $project }{ $worker } = [] if not exists $bill{ $project }{ $worker }; push @{ $bill{ $project }{ $worker } }, $time; }

    Most of the time this implicit creation of anonymous data structures on access is very convenient. However, you have to be mindful of it when you are writing condition checks.

    Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://535403]
Approved by neversaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-03-19 06:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found