How should I compare Perl references?

后端 未结 3 701
孤独总比滥情好
孤独总比滥情好 2021-02-11 18:32

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 \"ref         


        
相关标签:
3条回答
  • 2021-02-11 18:58

    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.

    0 讨论(0)
  • 2021-02-11 19:09

    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...
    }
    
    0 讨论(0)
  • 2021-02-11 19:12

    I have to assume that your #commentabout how cheap (=fast) the equality test is was there for a reason. Given that, you should probably keep using the cheap equality test. It is very fast, much faster than eq, let alone than any sort of deep compare.

    It's possible that an object with a directly or indirectly overloaded == operator might usurp the test for its own purposes. But if it is doing that, you might even prefer its mediated answer.

    Which approach you take may depend on what you know about the object's classes. Approaches that apply to general cases are not always optimal for specific ones. The more you know about something, the more you can optimize it — and the other way around, too.

    So if you know that you aren't using a class with applicable overloading, there's no reason to go hauling in a non–built‐in library function, and fair reason not to. If you do not know about overloading, or you know about it and don't want it to apply, then perhaps take the slow approach.

    As long as you understand the overloading concerns, it's a mistake to consider one approach is right and another is wrong. Each has its purpose. If it were always wrong to do what you're doing, then that operation would be either forbidden or at least warned about.

    You will note that it is not so marked.

    0 讨论(0)
提交回复
热议问题