Returns / list context

Discussion in 'Perl Misc' started by Chris Newton, Jul 8, 2004.

  1. Chris Newton

    Chris Newton Guest

    Hi all,

    I think I've been looking at this too long, now, and I'm just missing
    the blindingly obvious...

    I want to pass back a sequence of values from a function, to put into a
    hash mapping from strings onto string arrays. I tried this (obviously
    simplified here) approach:

    my %hash;
    my $key = "key";

    @hash{$key} = values();

    sub values
    {
    return ("value1", "value2");
    }

    After this, @hash{"key"} seems to be an array containing just the one
    string "value1". Why wouldn't this call be working in list context, and
    stuffing both values into the hash entry?

    Thanks in advance for any insights.

    Chris
     
    Chris Newton, Jul 8, 2004
    #1
    1. Advertising

  2. Chris Newton

    Matija Papec Guest

    X-Ftn-To: Chris Newton

    Chris Newton <> wrote:
    >I think I've been looking at this too long, now, and I'm just missing
    >the blindingly obvious...
    >
    >I want to pass back a sequence of values from a function, to put into a
    >hash mapping from strings onto string arrays. I tried this (obviously
    >simplified here) approach:
    >
    >my %hash;
    >my $key = "key";
    >
    >@hash{$key} = values();
    >
    >sub values
    >{
    > return ("value1", "value2");
    >}


    First, you'll be probably better with some other function name; "values" is
    perl builtin function for returning hash values.

    If you want to store an array in hash{$key}, you'll need reference (check
    perldoc perlref),

    $hash{$key} = [ values() ];

    use Data::Dumper; print Dumper \%hash;

    >After this, @hash{"key"} seems to be an array containing just the one
    >string "value1". Why wouldn't this call be working in list context, and
    >stuffing both values into the hash entry?


    @hash{"key"} is called hash slice and it is used for reading/populating
    multiple hash values at once,

    @hash{'one', 'two'} = 1..2;
    is pretty same as
    ($hash{'one'}, $hash{'two'}) = 1..2;


    --
    Matija
     
    Matija Papec, Jul 8, 2004
    #2
    1. Advertising

  3. Chris Newton wrote:
    > I want to pass back a sequence of values from a function, to put
    > into a hash mapping from strings onto string arrays. I tried this
    > (obviously simplified here) approach:


    Does your approach include "use warnings;"? It should.

    > my %hash;
    > my $key = "key";
    >
    > @hash{$key} = values();


    That line causes a compilation error, since values() is a built-in
    Perl function. I assume that you actually are using some other name;
    I'm using mysub() below.

    It should be noted that @hash{$key} results in a warning, since it is
    a slice with only one key. If you had had warnings enabled, that might
    have given you enough of a hint to realize what's wrong.

    > sub values
    > {
    > return ("value1", "value2");
    > }
    >
    > After this, @hash{"key"} seems to be an array containing just the
    > one string "value1". Why wouldn't this call be working in list
    > context, and stuffing both values into the hash entry?


    Even if you are calling the function in list context, since the slice
    only contains one key, the hash cannot assume more than one value.

    You may want to either store an array reference:

    $hash{ $key } = [ mysub() ];

    or add a key to the hash slice:

    my $key = "key";
    my $key2 = "key2";

    @hash{ $key, $key2 } = mysub();

    HTH

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 8, 2004
    #3
  4. Chris Newton wrote:

    > I want to pass back a sequence of values from a function, to put into a
    > hash mapping from strings onto string arrays. I tried this (obviously
    > simplified here) approach:
    >
    > my %hash;
    > my $key = "key";


    Strict, warnings, useless double-quotes, etc.

    > @hash{$key} = values();
    >
    > sub values
    > {
    > return ("value1", "value2");
    > }
    >
    > After this, @hash{"key"} seems to be an array containing just the one
    > string "value1". Why wouldn't this call be working in list context, and
    > stuffing both values into the hash entry?


    It's not clear what you were expecting. Did you want to assign the array
    elements to separate hash elements? If so, you need to use multiple hash
    keys in the assignment, like this:

    @hash{'key1','key2'} = getvalues();

    If you want to associate an array with a single key, you need to write your
    sub so that it returns a reference, and then store the reference:

    $hash{'key'} = getvalues();
    sub getvalues {
    return ['value1','value2'];
    }

    Note that in both cases, I named the sub "getvalues" instead of "values" -
    the latter is the name of a built-in sub in Perl.

    For more on complex data structures - a *lot* more - see:

    perldoc perldsc
    perldoc perllol

    sherm--

    --
    Cocoa programming in Perl: http://camelbones.sourceforge.net
    Hire me! My resume: http://www.dot-app.org
     
    Sherm Pendley, Jul 8, 2004
    #4
  5. Chris Newton

    Chris Newton Guest

    Matija Papec wrote...
    > First, you'll be probably better with some other function name;
    > "values" is perl builtin function for returning hash values.


    Sorry, that was just brain-fade while typing in the simplified version.
    The real code uses a different name.

    > If you want to store an array in hash{$key}, you'll need reference
    > (check perldoc perlref),
    >
    > $hash{$key} = [ values() ];


    Thanks; I'd forgotten it needed to become a reference when stored in a
    hash. Told you it would be obvious! :)

    Thanks to all for the replies,
    Chris
    (who's been programming in too many different languages this week!)
     
    Chris Newton, Jul 9, 2004
    #5
  6. Chris Newton

    Matija Papec Guest

    X-Ftn-To: Chris Newton

    Chris Newton <> wrote:
    >> "values" is perl builtin function for returning hash values.

    >
    >Sorry, that was just brain-fade while typing in the simplified version.
    >The real code uses a different name.


    :)

    >> If you want to store an array in hash{$key}, you'll need reference
    >> (check perldoc perlref),
    >>
    >> $hash{$key} = [ values() ];

    >
    >Thanks; I'd forgotten it needed to become a reference when stored in a
    >hash. Told you it would be obvious! :)
    >
    >Thanks to all for the replies,
    >Chris
    >(who's been programming in too many different languages this week!)


    Is it Python that made you forget all sane things? ;)



    --
    Matija
     
    Matija Papec, Jul 9, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VS_NET_DEV
    Replies:
    2
    Views:
    3,839
    jenny
    May 25, 2004
  2. =?Utf-8?B?U3VuU21pbGU=?=
    Replies:
    0
    Views:
    722
    =?Utf-8?B?U3VuU21pbGU=?=
    Jan 10, 2006
  3. Flip Rayner
    Replies:
    1
    Views:
    733
    bruce barker
    Jan 23, 2007
  4. ++imanshu
    Replies:
    7
    Views:
    499
    ++imanshu
    Aug 23, 2008
  5. Bo Lindbergh

    List context versus list context

    Bo Lindbergh, Jun 21, 2006, in forum: Perl Misc
    Replies:
    12
    Views:
    243
    Charles DeRykus
    Jun 28, 2006
Loading...

Share This Page