in reply to wantarray and Tied Hashes

i seem to recall that hashes, even tied ones, are defined as associating an array of scalar values with an array of lookup keys; as such, i would expect that it's pretty likely that perl always calls FETCH in a scalar context.

as a quick test, you could try calling FETCH yourself in an array context, by saying (i think)

my @array_i_said = FETCH(\%h, 'one');
but, at the moment, i am not at a machine with perl. (shhh! don't tell anyone.) anyway, if that does want an array, then all is in order and perl is calling FETCH in a scalar context regardless; which, as i said, makes sense to me, since we might assume that hash values are scalars.

i do wonder if there's a reason. is there any situation where FETCH would, if it kept the context the hash lookup was called in, return a list when we really want a scalar? i can't think of one...

.

Replies are listed 'Best First'.
Re: Re: wantarray and Tied Hashes
by davorg (Chancellor) on May 24, 2001 at 15:09 UTC

    Thanks for the ideas. I tried adding the following lines to my test script:

    $scalar = tied(%h)->FETCH('one'); @array = tied(%h)->FETCH('two');

    And that returned

    wantarray is false wantarray is true

    so it seems to me that Perl is doing something to force scalar context somewhere in the tie interface.

    To explain why I want FETCH to be callable in a list context, look at Tie::Hash::Regex. I'm thinking that if a hash is matching keys using regexes, then you could match more than one key and return a list of values in list context.

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      People would be a bit surprised to find $hash{key} returning a list. I like the fact that not even tied hashes can break this expectation. I don't think you should use $hash{key} as an all-purpose replacement for funct("key"). If you are going to provide your functionality via a "hash-like" interface, then I think you should make it act like a hash; which means that it can only take a single string as input and can only return a single value.

      Next you'll be wanting to tie scalars such that $x returns a list!!

      If you want to return multiple values, then you'll have to return a reference to an array.

      What I did with this was that I allowed the user to specify whether they wanted a list (er, ref to array) for each hash:

      tied(%hash)->WantList("always"); tied(%hash)->WantList("never"); tied(%hash)->WantList("forMultiples");
      (that isn't really a suggested interface, just a quick hack at a way to describe what I'm talking about). So each user could decide whether they wanted to write code like:
      $first= $hash{key}[0]; # or $first= $hash{key}; # or $values= $hash{key}; $first= ref($values) ? $values->[0] : $values;

              - tye (but my friends call me "Tye")

        i agree, at least until perl6. $hash{key} says "scalar" right on it at the beginning. if you could make perl agree to do it, i wouldn't mind @hash{key} returning a list, but i suspect that would cause other problems.

        and, as i understand it, in perl6 you'll say %hash{key} instead, anyway.