Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

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.

      --rjray

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

    broquaint

      or wait til 5.8 for the blessed() function.

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

      /J\

      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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://149717]
Approved by root
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2018-06-18 22:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?



    Results (111 votes). Check out past polls.

    Notices?