Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: has it been blessed?

by ehdonhon (Curate)
on Mar 06, 2002 at 16:08 UTC ( [id://149719]=note: print w/replies, xml ) Need Help??


in reply to has it been blessed?

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(); }

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

    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")
Re: Re: has it been blessed?
by rjray (Chaplain) on Mar 06, 2002 at 21:33 UTC

    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.

        I agree, but to clarify, the best approach would seem to be:

        if (ref($obj) and UNIVERSAL::isa($obj, 'UNIVERSAL')) { ... }

        Well, "best" in absence of the blessed primitive, of course...

        --rjray

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://149719]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (9)
As of 2024-04-23 17:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found