From: chromatic Date: Sat, 18 Jun 2005 12:15:41 +0000 (-0700) Subject: Recommend Against UNIVERSAL:: Methods as Functions, take 2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=da279afeb837e7a711e0ba9bd4b5d1fee73608ef;p=p5sagit%2Fp5-mst-13.2.git Recommend Against UNIVERSAL:: Methods as Functions, take 2 Message-Id: <1119122141.21521.9.camel@localhost> p4raw-id: //depot/perl@24909 --- diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 79c3c78..41d2cc8 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -1162,9 +1162,11 @@ maintain arbitrary state about the nature of the exception. Such a scheme is sometimes preferable to matching particular string values of $@ using regular expressions. Here's an example: + use Scalar::Util 'blessed'; + eval { ... ; die Some::Module::Exception->new( FOO => "bar" ) }; if ($@) { - if (ref($@) && UNIVERSAL::isa($@,"Some::Module::Exception")) { + if (blessed($@) && $@->isa("Some::Module::Exception")) { # handle Some::Module::Exception } else { @@ -4200,9 +4202,6 @@ name is returned instead. You can think of C as a C operator. unless (ref($r)) { print "r is not a reference at all.\n"; } - if (UNIVERSAL::isa($r, "HASH")) { # for subclassing - print "r is a reference to something that isa hash.\n"; - } See also L. diff --git a/pod/perlobj.pod b/pod/perlobj.pod index 891ebe3..f427de7 100644 --- a/pod/perlobj.pod +++ b/pod/perlobj.pod @@ -373,18 +373,19 @@ are inherited by all other classes: C returns I if its object is blessed into a subclass of C -You can also call C as a subroutine with two arguments. -The first does not need to be an object or even a reference. This -allows you to check what a reference points to, or whether -something is a reference of a given type. Example +You can also call C as a subroutine with two arguments. Of +course, this will do the wrong thing if someone has overridden C in a +class, so don't do it. - if(UNIVERSAL::isa($ref, 'ARRAY')) { - #... - } +If you need to determine whether you've received a valid invocant, use the +C function from L: -To determine if a reference is a blessed object, you can write + if (blessed($ref) && $ref->isa( 'Some::Class')) { + # ... + } - print "It's an object\n" if UNIVERSAL::isa($val, 'UNIVERSAL'); +C returns the name of the package the argument has been +blessed into, or C. =item can(METHOD) @@ -392,21 +393,9 @@ C checks to see if its object has a method called C, if it does then a reference to the sub is returned, if it does not then I is returned. -C can also be called as a subroutine with two arguments. -It'll always return I if its first argument isn't an object or a -class name. So here's another way to check if a reference is a -blessed object - - print "It's still an object\n" if UNIVERSAL::can($val, 'can'); - -You can also use the C function of Scalar::Util: - - use Scalar::Util 'blessed'; - - my $blessing = blessed $suspected_object; - -C returns the name of the package the argument has been -blessed into, or C. +C can also be called as a subroutine with two arguments. It'll +always return I if its first argument isn't an object or a class name. +The same caveats for calling C directly apply here, too. =item VERSION( [NEED] ) diff --git a/pod/perltooc.pod b/pod/perltooc.pod index 6737105..06f697c 100644 --- a/pod/perltooc.pod +++ b/pod/perltooc.pod @@ -1089,7 +1089,10 @@ for a significant performance improvement: if (my $coderef = $self->can($parent . "::CData1")) { $self->$coderef($newvalue); } - } + } + +If you override C in your own classes, be sure to return the +reference appropriately. =head2 Locking the Door and Throwing Away the Key