in reply to Object identity?

Not possible in the general case to the best of my knowledge. The only in-built object identifier is the address - so AFAIK there is no way of avoiding the (unlikely) situation of both objects getting the same address without adding some form of unique ID to the class.

It will also fail if either object overloads +, etc. to return something that is not the address - use refaddr if this is a concern.

If the reason you want this is to test that an object is being DESTROYed because it falls out of scope you can always use weaken like this.

I suppose you could do something totally evil, like overriding bless to store a UID somewhere for each object blessed. However this seems excessive :-)

Can you give us an idea of why you need to do this? I can't think of a situation where it would be necessary (although this is probably just a lack of imagination on my part).

Of course, if this is only an issue for one class it would be simplest to just add a UID slot to each object.

Replies are listed 'Best First'.
Re: Re: Object identity?
by diotalevi (Canon) on Jun 20, 2003 at 13:03 UTC

    The following code is copied directly from Class::WeakSingleton's test.pl. I only care about this for testing so I know that I'm getting the same object when I expect to and not when I don't. I think I'll just put in an object counter and compare *that* since everything else would involve gyrations it seems.

    Added: adrianh said I wasn't clear about what this code shows. If I had a way of comparing past object identity with present objects then I could assert $s1_addr != Class::WeakSingleton->instnace. It turns out that there's a much easier solution which just has me assigning a unique value to each object (just a $counter++) so I can determine identity in the case for my specific problem. The general case may not be solvable.

    { my %h; { # call Class::WeakSingleton->instance() twice and expect to ge +t the same # reference returned on both occasions. my $s1 = Class::WeakSingleton->instance(); my $s2 = Class::WeakSingleton->instance(); ok( $s1 == $s2 ); # Test 4 ok( $s1 == Class::WeakSingleton->instance ); ok( $Class::WeakSingleton::_instance == $s1 ); # Test 5 $h{test} = $s1; } ok( $Class::WeakSingleton::_instance ); # Test 6 } ok( not defined $Class::WeakSingleton::_instance ); # Test 7 { { # call MySingleton->instance() twice and expect to get the sam +e # reference returned on both occasions. my $s3 = DerivedSingleton->instance(); my $s4 = DerivedSingleton->instance(); $s5 = DerivedSingleton->instance; ok( $s3 == $s4 ); ok( $s4 == $s5 ); } ok( $s5 == DerivedSingleton->instance ); undef $s5; ok( not $DerivedSingleton::_instance ); }
      adrianh said I wasn't clear about what this code shows

      I meant to say I didn't understand what you were getting at - apologies :-)

      If I had a way of comparing past object identity with present objects then I could assert $s1_addr != Class::WeakSingleton->instnace.

      If it were me I would check that $s1 had been deallocated using weak references. Something like this example. What you want to test (if I'm reading this correctly) is that the object goes away when it falls out of scope. Having a unique object identifier isn't the only way of doing this.

      It turns out that there's a much easier solution which just has me assigning a unique value to each object

      Not that this is a bad solution either :-)

        Correct - I want to know that the object ceases to exist when all the references except the internal Class::WeakSingleton reference are gone. I can always examine the global scalar where the weak reference is expected to be stored but what I wanted to be sure was that a call to ->instance really does return a new object and not just somehow get the old one because I had a typo somewhere.