in reply to eq or == with references

package Foo; sub new { return bless {}, shift } package main; my $x = new Foo; my $y = new Foo; print "number: ", int $x, " -- ", int $y, "\n"; print "string: $x -- $y\n";

The following is wrong. Sorry. You've got to love those Perl quirks :)

Using == will always be true when both variables point to something, even though it's not the same object. It'll probably be treated the same as "Whatever" == "Something else".

Use eq, since that will stringify your objects into the form of PackageName=HASH(0xdeadbeef). If they point to the same object, they'll have the same memory address. (the 0xdeadbeef part). If that's the case, the two string will be equal.


ar0n ]

Replies are listed 'Best First'.
(tye)Re: eq or == with references
by tye (Sage) on Jul 08, 2001 at 05:53 UTC

    Sorry, no. References have a little-used feature that was specifically designed to make == work for comparing references.

    my $var; print \$var,$/; print 0+\$var,$/;
    outputs:
    SCALAR(0x1a6533c) 27677500
    so $ref1 == $ref2 if and only if they both point to the same object. This is a very efficient test. eq will also work but isn't quite as efficient.

            - tye (but my friends call me "Tye")
      This is true, but...

      References are compared according to some magical numerical values the contain (probably some address of what they refer to, but that's not important). So two references will only ever compare equal using == if they do indeed refer to the same object. However, a reference will compare equal to its numerical value.

      Try this in Tye's example...

      $rv = \$var; # reference to $var $num = 0+\$var; # NUMERICAL value of $rv # ($num could conceivably occur in your # program "by chance") ref $rv or die; # ASSERT: $rv is a reference !(ref $num) or die; # ASSERT: $num is NOT a reference print $rv == $num, $/; # Prints "1": a reference equals a # number.

        Sure, but that isn't any different than the case for eq:

        $rv = \$var; # reference to $var $str = "".\$var; # STRING value of $rv # ($str could conceivably occur in your # program "by chance") ref $rv or die; # ASSERT: $rv is a reference !(ref $str) or die; # ASSERT: $str is NOT a reference print $rv eq $str, $/; # Prints "1": a reference equals a string.
        So I don't really appreciate your point. If you want to decide if two things are equal references, then you have to first determine that they are both references, whether you use eq or ==. I suppose that you could argue that a matching number is more likely to come up than a matching string but I 1) wouldn't buy that argument and 2) think that making your program rely on the unlikelyhood of either is poor design. (:

                - tye (but my friends call me "Tye")
(CL) Re^2: eq or == with references
by CheeseLord (Deacon) on Jul 08, 2001 at 05:50 UTC

    I think eq will work, but according to this, so would ==...

    my %one = ('a' => 'b'); my %two = ('b' => 'a'); my $ref1 = \%one; my $ref2 = \%two; if ($ref1 == $ref2) { print "Equal.\n" } else { print "Not equal.\n" } $ref2 = $ref1; if ($ref1 == $ref2) { print "Equal.\n" } else { print "Not equal.\n" }

    prints out

    Not equal. Equal.

    for me, which seems to say that == will work. Of course, I'm likely overlooking a not-so-trivial point, as I just hacked that little test together...

    His Royal Cheeziness

Re: (ar0n) Re: eq or == with references
by sierrathedog04 (Hermit) on Jul 08, 2001 at 07:35 UTC
    It makes sense that == should not work for references. After all, references are scalars. == is an arithmetic operator that interprets comparable scalars as numbers.

    Using arithmetic operators on pointers is a form of pointer arithmetic in C.

    Perl, however does not have pointers. It has references. And the major difference between C pointers and Perl references is that C pointers allow pointer arithmetic and Perl references do not allow pointer or reference arithmetic. Hence the use of an arithmetic operator such as == on a Perl reference is not meaningful.

    Tye points out that Perl has a feature that interprets the == for references in a meaningful way. Larry and company ought to remove this feature. References are not numbers. The Perl compiler ought to prohibit numeric operations on references.

      Except that it exists for the purpose of determining likeness between two references. Numerically comparison is generally faster than string comparison.

      japhy -- Perl and Regex Hacker
      Treating a reference as a number would only be a problem if it were possible to create (i.e. compute) a new reference numerically. This would be equivalent to allowing pointer arithmetic. As long as this is not the case, one representation for comparison purposes should be as good as any other, as long as there's a one-to-one correspondence between the references and their representations.

        Yes, using == on references does not "reference arithmatic" make... (sierrathedog04 wrote

        The Perl compiler ought to prohibit numeric operations on references.
        ). Perl doesn't support any numeric operations on references. It does support converting a reference to a number and then doing numeric operations on those. It certainly doesn't support converting a number (no matter how you got it) into a reference (nor does it support any operations that take a reference and a number as input and return a reference as output). So I don't understand the leap from == to fears of reference arithmatic.

        I don't like using eq to compare references because it feels very much like comparing numbers via:     sprintf("0x%X",$num1) eq sprintf("0x%X",$num2) (And if a design bug I found in overloading is ever fixed, I'm likely to overload the stringification of many of my objects but would never overload the numeric value of them so, if that were to happen, eq would become unreliable while == would continue to work. I think it makes sense to have objects return human-readable stringifications but don't see much use for numeric values of objects except as already provided for.)

        Anyway, I wanted to point out that in (tye)Re: Creative use of pack/unpack I heavily abuse the numeric value of references in a way that I think only the insane would take seriously. In (tye)Re2: resurrecting objects? I hint that even more insanity is technically possible, though not even I have been insane enough to actually try that. ;)

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