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

I am looking for a nice way to determine the underlying type of an Object (ie SCALAR ARRAY HASH etc) - sort of like a ref($obj) for objects:

For examble

my $obj = Some::Class->new(); my $type = ref_like_function_for_object($obj); if ( $type eq 'HASH' ) ...

I know I can say

$type = 'HASH' if $obj->isa('HASH'); $type = 'ARRAY' if $obj->isa('ARRAY');
but I wonder if there is a better way?

Replies are listed 'Best First'.
Re: How do I determine the underlying type of an Object?
by adrianh (Chancellor) on Apr 19, 2003 at 21:35 UTC

    You want reftype from Scalar::Util. Does exactly what you want.

      I believe you are right! Thank you! 8-))
Re: How do I determine the underlying type of an Object?
by Coruscate (Sexton) on Apr 19, 2003 at 21:36 UTC

    I suppose you could do something like this:

    sub type { my $obj = shift; return $obj->isa('HASH') ? 'HASH' : $obj->isa('ARRAY') ? 'ARRAY' : $obj->isa('SCALAR') ? 'SCALAR' : die 'Not HASH, ARRAY or SCALAR'; } print type( bless \a ), "\n"; print type( bless [a] ), "\n"; print type( bless {a=>b} ), "\n"; print type( bless \*STDOUT ), "\n\n";


    If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, please reply to this node or /msg me to inform me as to what is wrong with the post, so that I may update the node to the best of my ability.

      Unfortunately this doesn't work for some edge cases. Consider:

      my $not_a_hash = bless [], 'HASH'; print type($not_a_hash), "\n";
        There are ways around that
        use strict; use warnings; sub better_type { my $obj = shift; my $type = ref $obj; my $orgType = $type; my @ref = qw[ SCALAR ARRAY HASH ] ; #CODE REF GLOB LVALUE ]; if( grep { $_ eq $type } @ref ) { bless $obj, '__schwern'; $type = $obj->isa('HASH') ? 'HASH' : $obj->isa('ARRAY') ? 'ARRAY' : $obj->isa('SCALAR') ? 'SCALAR' : undef; bless $obj, $orgType; # bless it back } return $type; } my @objs = ( bless([],'ary'), bless({},'ash'), bless(sub{'blessed sub HASH'},'HASH'), ); printf "%-30s => %s\n\n", $_ => better_type( $_ ) || 'Not HASH, ARRAY or SCALAR' for @objs; __END__ ary=ARRAY(0x1abf0dc) => ary ash=HASH(0x1ab51b0) => ash HASH=CODE(0x1c0b164) => Not HASH, ARRAY or SCALAR
        But in this version you gotta lookout for read-only variables.


        MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
        I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
        ** The Third rule of perl club is a statement of fact: pod is sexy.

        my $not_a_hash = bless [], 'HASH';

        Anyone blessing something into or using a package named HASH needs to be punished.

        I'll just assume people don't do this. Because they don't.

        Juerd
        - http://juerd.nl/
        - spamcollector_perlmonks@juerd.nl (do not use).
        

        /me nods.

        I noticed your reply with the pointer to the module. ++ for that :)


        If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, please reply to this node or /msg me to inform me as to what is wrong with the post, so that I may update the node to the best of my ability.

Re: How do I determine the underlying type of an Object?
by Abigail-II (Bishop) on Apr 19, 2003 at 23:58 UTC
    my $obj = Module -> new; my ($type) = "$obj" =~ /=(\w+)[(]0x[0-9A-Fa-f]+[)]$/;

    Abigail

      This may fail in the rare case where the author has overloaded stringification for the object.

        Oh, but you can always first rebless the object.

        Abigail

Re: How do I determine the underlying type of an Object?
by mitd (Curate) on Apr 19, 2003 at 22:12 UTC
    Your question is a little confusing (at least to me).
    my $obj = Some::Class->new();
    returns a blessed reference so ref ($obj) returns the name
    of the class into which the ref was blessed.

    UPDATE: please ignore was having an acid flashback!

    Your second examples are incorrect isa() does not
    answer the question is this object this data type.
    IT answers the question is the object an instance of class foo
    either directly or by way of inheritance.
    Assumes the isa() you refer to is UNIVERSAL->isa().
    HASH, ARRAY and SCALAR are NOT Classes they
    are data types.

    That being said, is want you really want to determine the 'underlying' data type of the blessed reference ??

    If so why not just create a 'type' method in the class.

    mitd-Made in the Dark
    I've always been astonished by the absurd turns
    rivers have to make to flow under every bridge.

Re: How do I determine the underlying type of an Object?
by jaa (Friar) on Apr 20, 2003 at 13:53 UTC

    Thanks very much folks, I appreciate your responses!

    Jeff