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

Just want to verify this with the rest of the Monastery...

After some experimenting it seems that the best way to determine if two references are the same is to use the == operator:

my $x = []; my $y = []; if ($x == $y) { print "x and y are the same reference\n" } $y = $x; if ($x == $y) { print "x and x are the same reference\n" }
This is better than using string equality (eq) since the references may have overridden stringification.

I couldn't find any explicit documentation for this, but it seems that evaluating a reference in numeric context returns the address of the reference which is how == works for determining reference equality.

Replies are listed 'Best First'.
Re: checking reference equality (refaddr)
by tye (Sage) on May 10, 2009 at 23:33 UTC

    A (blessed) reference can overload stringification or eq or == or numerification(?) so any of them can fail. I just use == since it is so much simpler than eq when it comes to references (it doesn't involve constructing a multi-part string, just interpretting a pointer as an integer).

    overload's StrVal() documentation recommends Scalar::Util's refaddr(), which would then allow you to use == without worrying about overloading.

    - tye        

      Thanks - I forgot all about numerification. And, yes, I think that's the proper term, along with booleanification :-).
Re: checking reference equality
by kennethk (Abbot) on May 10, 2009 at 23:41 UTC
    The behavior you are using is discussed in Using References.
    Using a reference as a number produces an integer representing its storage location in memory. The only useful thing to be done with this is to compare two references numerically to see whether they refer to the same location.

    My Perl Fu is not so great as to let me weigh in on whether this is the "best" method.

      The only useful thing to be done with this is to compare two references numerically to see whether they refer to the same location.

      I guess this means that the author of that doesn't consider Acme::ESP to be useful. I'm not sure if I should feel hurt... ;)

      - tye        

      Thanks for pointing that out. I was only checking perldoc perlop.
      Re: My Perl Fu is not so great as to let me weigh in on whether this is the "best" method. The document cited shows == to numerically compare addresses to see if two references point to the same object.

      It does not consider overloading == by the class so referenced. For example, I'm sure BigNum will give you equality of the referenced values, not co-referencing.

      So, this is true only for unblessed items. For objects, == should be assumed to be some kind of equivilance operation as befitting the class. So, for Best Practices, I would not use it for object identity.

      That core man page doesn't list any maintainer to email with corrections. Perhaps someone involved will see this and mention it on the proper list.

      For completeness, let me point out that Perl 6 has a === operator for this express purpose.

Re: checking reference equality
by Marshall (Canon) on May 11, 2009 at 09:41 UTC
    Yes to compare two references, use the == operator!
    #!/user/bin/perl -w use strict; my $x = []; #assigns $x to an anonmyous list my $y = []; #assigns $y to an anonmyous list if ($x == $y) { print "x and y are the same reference *1\n"; } else { print "x and y are NOT the same reference *2\n"; } $y = $x; #assigns address x to y if ($x == $y) { print "x and y are NOW the same reference *3\n" } else { print "x and y are different! *4 \n"; } __END__ PRINTS: x and y are NOT the same reference *2 x and y are NOW the same reference *3