On Thu, Jun 16, 2005 at 08:41:34AM +0200, demerphq wrote:
> On 6/16/05, Mark Jason Dominus <[EMAIL PROTECTED]> wrote:
> > yves:
> > >  Using UNIVERSAL::isa() is IMO bad as its suseptible to
> > >
> > >    my $obj=3Dbless [],'HASH';
> > >
> > > type nonsense.
> > 
> > Perhaps, but it seems to me that someone doing that is doing it
> > deliberately to try to deceive the UNIVERSAL::isa function.  In which
> > case it is a feature, not a bug.
> 
> Well, IMO reftype() is superior as its faster and cant be fooled. But
> only insofar as the question being asked is "Is the underlying
> reference to a legitimate hash".
> 
> But the other point, about overload is also important. If an object of
> class Foo::Bar overloads hash dereferencing then it too probably
> should be consider to be isa('HASH') but it isnt.
> 
> So theres three possible questions:
> 
> 1. Is the object underneath the hood implemented with a given perl type
> 2. Is the object a member of the class TYPE or a class that inherits from it
> 3. Does the object provide an TYPE like interface.
> 
> The first one can only be reliably done with reftype.

Correct.

> the second with isa,

Correct. But not UNIVERSAL::isa, which means it's somewhat cumbersome:

   use Scalar::Util 'blessed';
   if (blessed($x) && $x->isa('TYPE')) ...

> the third with reftype and overload.

No reftype involved;  given deref overloading, the only correct way
to do this is short and sweet:  eval {\%$x}

Though one of the evils of psuedo-hashes is that any arrayref looks
like a hashref until you try some particular key.  There's no solution
I can think of to avoid that.

> All im trying to say here is that the subject is not so simple as to
> admit that "isa is the recommended way to do this". IMO in fact isa is
> NOT the recommended way to do this.
> 
> Although that still begs the question what "this" is. In the code that
> chromatic removed IMO the question being asked is 3 which isnt
> answered properly by isa() because it ignores classes that arenot
> isa('HASH') but do overload hash dereferencing, and conversly can be
> fooled by objects that are isa('HASH') but arent reftype() eq 'HASH'
> and arent overloaded.

Adding to your list,

4. Is the class $x either TYPE or a subclass of TYPE?

For this, "$x"->isa("TYPE") works.  ("$x" in case the class name is
itself stored as an overloaded object :)

Reply via email to