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

I have two references and I would like to know if they both point to the same object. Should I use $ref1 == $ref2 or $ref1 eq $ref2 or something else? Both == and eq currently work but wasn't sure if one was correct and the other simply happened to work with current versions of perl.

Replies are listed 'Best First'.
(ar0n) Re: eq or == with references
by ar0n (Priest) on Jul 08, 2001 at 04:55 UTC
    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 ]

      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.

      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

      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.
Re: eq or == with references
by rrwo (Friar) on Jul 08, 2001 at 22:35 UTC

    ref() returns a string, not a number, so use 'eq'.