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.

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

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) } >>.

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!

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.

99.999% of the time you do not want to really know how something is
implemented, you want to remain ignorant.  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.

Reply via email to