Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I compare Perl references?

I want to check if two references point to the same object. It seems I can simply use

if ($ref1 == $ref2) {   # cheap numeric compare of references  print "refs 1 and 2 refer to the same thing\n"; } 

as mentioned in perlref, but I vaguely remember seeing the use of some function for the same purpose. Is there any reason I shouldn't use the simple numerical equality test?

Note I only want to know whether the references point to the exact same object. I don't look for a way to compare the content of the object(s).

like image 312
David B Avatar asked Oct 31 '10 16:10

David B


People also ask

How do I dereference a reference in Perl?

Dereferencing is the way of accessing the value in the memory pointed by the reference. In order to dereference, we use the prefix $, @, % or & depending on the type of the variable(a reference can point to a array, scalar, or hash etc).

What are references Perl?

A Perl reference is a scalar data type that holds the location of another value which could be scalar, arrays, or hashes. Because of its scalar nature, a reference can be used anywhere, a scalar can be used. You can construct lists containing references to other lists, which can contain references to hashes, and so on.

What is a hash reference in Perl?

A hash is a basic data type in Perl. It uses keys to access its contents. A hash ref is an abbreviation to a reference to a hash. References are scalars, that is simple values. It is a scalar value that contains essentially, a pointer to the actual hash itself.

How do I return a reference in Perl?

When you say return @a , you are returning the contents of the array. In certain programs, it works out more cleanly to return the contents of the array. In certain programs, it works out more cleanly to return a reference to the array. Make your decision case by case.


2 Answers

References, by default, numify to their addresses. Those reference addresses are unique for every reference, so it can often be used in equality checks.

However, in the snippet you showed, you'd first have to make sure that both $ref1 and $ref2 are actually references. Otherwise you might get incorrect results due to regular scalars containing reference addresses.

Also, nothing guarantees references to numify to their address. Objects, for example, can use overloading to influence the value they return in different contexts.

A more solid way than comparing references directly for numeric equality would be to use the refaddr function as provided by Scalar::Util, after making sure both sides actually are references.

like image 186
rafl Avatar answered Sep 20 '22 09:09

rafl


The function you are looking for is refaddr from Scalar::Util (after ensuring that the values being compared really are references):

use Scalar::Util 'refaddr';  if ($obj1 and ref($obj1) and $obj2 and ref($obj2) and     refaddr($obj1) == refaddr($obj2)) {     # objects are the same... } 
like image 23
Ether Avatar answered Sep 18 '22 09:09

Ether