Michael G Schwern wrote: > Yuval Kogman wrote: >>> Likewise with ref in boolean context, I almost never want the object >>> to be able to lie to me. >> But if it has to work hard to lie, then does it matter? > > Yeah, I'm with Yuval here. There seem to be a cold war going on here wrt > identifying an object. > > In the beginning we used UNIVERSAL::isa() and UNIVERSAL::can(). And it > could identify the nature of any scalar, blessed or not. Reference or not. > And it was good. > > And then someone got clever and overrode isa() and can(). And there was > much wailing and nashing of teeth and slaughtering of lambs. Now we're > supposed to use C<< eval { $obj->isa($class) } >> and for a while balance > was restored. Well, except you aren't supposed to do that, because if ->isa can be overloaded, it can also die or throw an exception. So eval { $obj->isa($class) } falsely ignores errors. > And then someone defined a $SIG{__DIE__} so now its C<<{ local > $SIG{__DIE__}; eval { $obj->isa($class) } }>> or you must depend on having > a 3rd party module written in XS, Scalar::Util, available and compiled and > do C<<use Scalar::Util qw(blessed); blessed $obj && $obj->isa($class) >>. This just compounds the above-mentioned mistake. > And then someone got really clever and blessed their object into class "0". > Now we must do C<<use Scalar::Util qw(blessed); defined blessed $obj && > $obj->isa($class) >>. Or if you can't rely on Scalar::Util: C<< local > $SIG{__DIE__}; eval { $obj->isa($class) } >>. And this compounds it further. > But what if isa() is broken or has side effects, hmm? And what if its lying > to me and I *really* want to know what methods are *really* available and > not autoloaded? And what if someone got even more clever and blessed into > class ""... > > ARGHAGHAGHGGGGHHH! > > IT SHOULD NOT BE THIS COMPLICATED TO IDENTIFY THE HERITAGE OF AN OBJECT! use Params::Util '_INSTANCE'; if ( _INSTANCE($obj, 'Whatever') ) { } > The best practice should be straightforward: Ask the object. If it wants > to lie to you and override isa() or use class "0" (and yes, there really is > no other reason to use such a class name but to lie) then damned well let > it. We call this "encapsulation" and it is good. Yep, I was pissed off too, so the above tries to compensate for the problems and re-encapsulate what you originally meant by UNIVERSAL::isa(). > 99.999% of the time you do not want to really know how something is > implemented, you want to remain ignorant. I concur, which is what really pisses me off them IO::String->new(\$string)->isa('IO::Handle') returns false, because the author believes in duck typing over actually having isa describe the interfaces. It is detrimental for your > shopping cart code to pierce the facade surrounding the objects it is using. > The remaining 0.001% of the time you're writing something like Data::Dumper > or a serialization module and fine, employ all the magic you like, but don't > try to apply the needs of a module like Data::Dumper to Joe Business > Programmer! If I caught someone blessing into class "0" at my work he'd > have to give such a damned good reason that I wouldn't use his eye sockets > for USB ports. > > All the trouble here seems to stem from the fact that its so damned hard to > reliably determine what is and is not an object. And the only reason we > care about that is so we can call isa() on it. The proper way to identify > the nature of an object is C<< $obj->isa($class) >>. The proper way to > identify whether a class has a method is C<< $obj->can($method) >>. Done. > All the other junk we do these days is determining if its blessed so there's > not an error when we try to call a method on it. > > Solution... make everything an object. Or at least everything callable with > methods. Or for bloody screaming hell at least the UNIVERSAL ones! This is > called "autoboxing" and there's already a module out there to do it. > http://search.cpan.org/dist/autobox. In one fell swoop all this nonsense > goes away. It doesn't even require a core patch anymore. > > $ perl -Mautobox -wle 'print []->isa("ARRAY");' > 1 > > autobox.pm was proposed as a core module many moons ago but it was rejected > as not being necessary. As its a central tenet of any decent OO language > that everything should be (or at least act like) an object I was very > dismayed at that. Well, here's your use case. > > Please reconsider autobox. heh :) Adam KThread Previous | Thread Next