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

Hi,
I was a little surprised that
my @test = ( 0 ); if ( defined @{ $test[1] }[1] ){} my $l = @test; print $l;
produced a "2".
Sure it is easy to extend the if clause as
my @test = ( 0 ); if ( defined $test[1] && defined @{ $test[1] }[1] ){} my $l = @test; print $l;
and all is fine again, but where can I find any documentation of this behaviour? It was unexpected to me and I would like to read more about it. Neither perlref nor the perlreftut seemed to document that an element is appended to @test as soon as it is accessed.
Cheers,
Hans

Replies are listed 'Best First'.
Re: defined of a matrix
by pelagic (Priest) on Jun 15, 2004 at 12:43 UTC
    >    I would like to read more about it
    Search for autovivification.
    addon:
    merlyn has also written a couple of articles on that topic.

    pelagic
      Thanks, that makes it much clearer.
Re: defined of a matrix
by rnahi (Curate) on Jun 15, 2004 at 13:03 UTC

    Perhaps your code would look better with exists rather than defined.

    #!/usr/bin/perl -w use strict; my @test = ( 0 ); my $len = 0; if ( exists $test[1]->[1] ) { $len = @test; } print $len;
      this does also autovivification ...

      pelagic
Re: defined of a matrix
by Roy Johnson (Monsignor) on Jun 15, 2004 at 14:50 UTC
    Your 2nd test would be better as
    if (ref $test[1] and exists $test[1][1]) {}
    It occurs to me that a sub that returns the passed value iff it is a ref might provide some shorthand for this idiom:
    sub iff_ref { return ref $_[0] ? $_[0] : undef; } # Then your test becomes (if exists doesn't mind the notation) if (exists iff_ref($test[1])->[1]) {} # or it might have to be if (exists ${iff_ref($test[1])}[1]) {}
    I don't have perl5 where I am today, so this is absolutely untested.

    We're not really tightening our belts, it just feels that way because we're getting fatter.