Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Empty List miracle (2)

by rovf (Priest)
on Apr 29, 2010 at 09:30 UTC ( [id://837491]=perlquestion: print w/replies, xml ) Need Help??

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

In the following code, the second call to use_hash fails:

use strict; use warnings; $|=1; sub empty_list { @{ [] } } sub use_hash { my (%h) = @_; print(join(',',keys %h),"\n"); } use_hash(foo1 => undef, bar1 => 5); print "not defined\n" unless defined ((empty_list)[0]); use_hash(foo2 => (empty_list)[0], bar2 => 5);
The ouput of the program is as follows:
bar1,foo1 not defined Odd number of elements in hash assignment at C:\tmp\emptylist_a.pl lin +e 12. foo2,5
We see that the first use_hash works. We also see that (not surprising) an empty list indexed by [0] yields undef. I would have expected the 2nd call to use_hash being the same as the first: Instead of passing undef<c> explicitly to key <c>foo2, I "generate" it by taking the first element of an empty list. However, the latter does not work.

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: Empty List miracle (2)
by moritz (Cardinal) on Apr 29, 2010 at 09:40 UTC
    Without having investigated it in more detail, I suspect that (empty_list)[0] is (), which turns into undef in scalar context, but is the empty list in list context. That's why you get 3 items passed to use_hash.

    (In Perl 6 we call that value "Nil").

      Without having investigated it in more detail, I suspect that (empty_list)[0] is ()
      It is, in list context. In list context, such a construct is called a slice. Quoting perldata:
      A slice of an empty list is still an empty list.
      which turns into undef in scalar context
      Perl doesn't work that way. It doesn't say, "let's evaluate EXPR in list context, then do a list-to-scalar conversion of the result". In scalar context, (empty_list)[0] is just the indexing operator. [0] is out of bounds (there's no first element), and hence, the result is undef.

        In scalar context, (empty_list)[0] is just the indexing operator.

        It's still a slice. For example, you can do

        $x = ( f() )[2,3,4];

        The rest is accurate, though. In scalar context, the slice operator will always return exactly one element. It will never return an empty list that magically becomes a scalar.

Re: Empty List miracle (2)
by Sandy (Curate) on Apr 29, 2010 at 14:20 UTC
    If you compare the output of your empty_list routine in scalar and list context:
    sub empty_list { return @{ [] } } my @y=(empty_list())[0]; my $x = (empty_list())[0]; use Data::Dumper;print Dumper \$x,\@y;
    You will see that @y is an empty array, and $x is undef.

    think of the difference between using $x and @y in your hash declaration:

    my @y=(empty_list())[0]; # @y = (); my $x = (empty_list())[0]; # $x = undef; my %x = (foo=>$x); my %xx = (foo=>@y);
    So, to use your function in your hash declaration, you need to force scalar context.
    my %x=(foo=>scalar((empty_list1())[0]));

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (2)
As of 2024-04-19 01:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found