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 :)