in reply to Re^6: ref eq "REF"
in thread ref == "REF"

another, well-known breach of this generalization — you can't use references as hash keys

This is a different issue. Hash keys are not scalar values, they are string values. It happens that, very often, the stringified value is the same as the useful scalar value. In some cases, though, this is not true. References are one example, but another would be a variable with a dual value. Consider the following example:

open "non_existent_file"; print $!+0, ": ", $!; $hash{$!}++; for (keys %hash) { print $_+0, ": ", $_; }

Which outputs the following:

2: No such file or directory 0: No such file or directory

The separate numerical value is lost, because the value is stringified as the hash key, not stored as an arbitrary scalar.

Replies are listed 'Best First'.
Re^8: ref eq "REF"
by gaal (Parson) on Oct 18, 2004 at 20:31 UTC
    I don't see it as a different issue at all: in fact, this is exactly my point about the internals showing!

    Hash keys accept only string values because it was a lowercase-p-perl design decision to make them string values. This didn't have to be the case! Trading off efficiency, hv_store and friends could have accepted RVs as well. The dual value issue you raise is indeed different, and more vexing in this case, because if you were to use a multi-valued SV as a hash key, confusion would probably arise about which value you wanted to be definitive (or if you wanted to require subsequent SVs to have *both* values determine the lookup). This is not a problem with references as keys.

      in fact, this is exactly my point

      I thought your point was that a scalar is a scalar is a scalar; a scalar that's a reference should still be thought of as a scalar. That's a notion I'll agree with, even though I don't have any problem with ref returning REF. The reason I say hash keys are a separate issue is because, I repeat, hash keys are not a scalar values, they are string values.

      Hash keys accept only string values because it was a lowercase-p-perl design decision to make them string values.

      I have no direct knowledge of why they chose to implement Perl's hashes using string values as keys, but I can easily see it as both an implementation choice and a language choice. Using arbitrary scalar values as hash keys adds complexity to both areas. With something as fundamental as hashes, I can easily understand the desire to keep it simple.

        I see it as the same issue because "string value" doesn't have (much of) a place in the nomenllature of Perl. I mean in typical usage; in the docs; in tutorials an well-known books. People are educated to think of $var as a scalar (which is a scalar etc.), and then when they use a reference as a hash key it loses its magic and they are suprised.

        There are other places where stringification occurs. For example, if you create a file from a variable that holds a reference, and then use readdir to attempt to recover it, obviously it's going to lose its magic. I don't think that suprises anyone as much <g> but that's precisely because you are unPerlifying your data.

        I take back my claim about the genesis of string-only hash keys. You're right: I don't know how the decision was made either. We both recognize simplicity; my gripe was about consistency (which, when lacking, often causes loss of simplicity elsewhere).

        (Paranthetically: in Java, references can be hash keys. Of course, Java hashes are nowhere near as elegant to use as in Perl, so I don't know whose point of view this supports. Then again I think we've more or less come to see eye to eye on this, no?)