Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

has it been blessed?

by pmc2 (Acolyte)
on Mar 06, 2002 at 15:55 UTC ( #149717=perlquestion: print w/replies, xml ) Need Help??

pmc2 has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks, how do I do
if (are_you_blessed($obj)) { $obj->invoke_method(); }

Replies are listed 'Best First'.
Re: has it been blessed?
by ehdonhon (Curate) on Mar 06, 2002 at 16:08 UTC

    If you want to find out if an object is blessed and is a particular class, you would do something like this:

    if ( UNIVERSAL::isa( $obj, 'Class::I::am::checking::for' )){ $obj->invoke_method(); }

    If you want to know if it is blessed into any old class at all, you could do something like this:

    my $ref = ref($obj); if ( $ref && ($ref !~ /^(SCALAR|HASH|ARRAY)$/) ) { $obj->invoke_method(); }

      For the first case, I'd add an additional check:

      if( ref($obj) && UNIVERSAL::isa($obj,'Class') ) { $obj->invoke_method(); }
      since UNIVERSAL::isa("main",'main') returns true even though "main" is not an object; UNIVERSAL::isa() works on class names as well.

      For your second test, I'd go a quite different route:     if(  ref($obj)  &&  UNIVERSAL::isa($obj,'UNIVERSAL')  ) { or, just to be shorter:

      if( ref($obj) && UNIVERSAL::can($obj,'can') ) { # or if( ref($obj) && UNIVERSAL::can($obj,'isa') ) {
      You can also do:     use UNIVERSAL qw( isa can ); to make the above tests much shorter to write (allowing you to drop "UNIVERSAL::" in each).

      This all partially illustrates why it was a mistake for ref() to deal with both reference nature and blessedness nature. ref() should only return things like 'ARRAY' while a separate function, blessed() should tell you whether the item is a blessed reference or not (and probably return the package into which it was blessed, though using such information directly is usually a bad idea).

              - tye (but my friends call me "Tye")

      The second test you pose is probably the more efficient, but you overlook a few candidates:

      my $ref; if ($ref = ref($obj) and $ref !~ /^(SCALAR|ARRAY|HASH|GLOB|Regexp) +$/) { $obj->method(); }

      Technically, the Regexp references are objects, but they are part of the core, and wouldn't represent an application-defined class. Of course, you can drop that from the regex above, if you like.


        Efficiency is nice, but there's something to be said for correctness as well. You've also forgotten REF, CODE, and LVALUE.

        Comparing the return value from ref to a list of known types is simply the wrong approach. Either you'll forget something, or a new type will be added in a future version and your code will break.

        Go with the UNIVERSAL::isa() approach. Really.

Re: has it been blessed?
by broquaint (Abbot) on Mar 06, 2002 at 16:08 UTC
    Try this is you're just checking for the method
    if($obj->can("invoke_method")) { $obj->invoke_method(); }
    wait til 5.8 for the blessed() function or read ehdonhon's node.


      or wait til 5.8 for the blessed() function.

      Or get it now by installing the module Scalar::Util from CPAN ;-}


      If $obj hasn't been blessed at all, that will still fail.

        But you can use can in a non-OO way: if (UNIVERSAL::can($obj, 'method'))

        dave hj~

Re: has it been blessed?
by dash2 (Hermit) on Mar 06, 2002 at 16:17 UTC
    To check if you are blessed into a particular class: if (ref ($obj) eq $classname)

    To check if you are blessed at all... I think if (ref $obj and ref $obj ne 'ARRAY' and ref $obj ne 'HASH') # ... etc. would do it...

    but if (UNIVERSAL::isa($obj, 'UNIVERSAL')) is probably better.

    dave hj~

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://149717]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2021-12-08 01:35 GMT
Find Nodes?
    Voting Booth?
    R or B?

    Results (34 votes). Check out past polls.