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

Hello Monks,

I have mangaged to program myself into a corner whereby an argument passed to a subroutine is in one case a reference to a list of strings and in the other a reference to a list of objects. I shall fix the problem by creating an appropriate list of strings from the list of objects.

However, I was wondering, if I did want to pass two different types of reference to the subroutine, what the best way of determining the type of reference within the subroutine would be.

Any ideas?

Thanks,

loris

  • Comment on Distinguishing between an array of objects and an array of strings

Replies are listed 'Best First'.
Re: Distinguishing between an array of objects and an array of strings
by GrandFather (Saint) on Sep 22, 2005 at 09:56 UTC

    ref is true if its operand is a reference so you can test like this:

    use warnings; use strict; my $str = 'Str'; my $rStr = \$str; my $rrStr = \$rStr; print "\$rrStr is ref to ref to str\n" if ref $rrStr and ref $$rrStr; print "\$rStr is ref to str\n" if ref $rStr; print "\$str is str\n" if ! ref $str;

    Note that each additional $ dereferences by one.


    Perl is Huffman encoded by design.
      ref is true if its operand is a reference
      slightly different: ref returns the type of object ('ARRAY', 'SCALAR', or the classname).
      if the classname was '0' (zero), then ref would not be 'true'.
      ok, nobody would call their classes '0', just thought i should add that to clarify what ref does.
        ok, nobody would call their classes '0', . . .

        There is a good reason for that.

        $ perl -e'package 0' syntax error at -e line 1, near "package 0" Execution of -e aborted due to compilation errors. $
        Namespace names follow the same rules as variable names.

        After Compline,
        Zaxo

        Indeed, and unfortunally, if $var isn't a reference, ref($var) returns a false, but defined value, so testing for defined ref($var) is even worse than testing for ref($var). However, it isn't possible to bless something into a package with no name, if the second argument of bless equals the empty string, the thing is blessed into main. So, if ref returns anything but the empty string, its argument is a reference.
Re: Distinguishing between an array of objects and an array of strings
by Zaxo (Archbishop) on Sep 22, 2005 at 10:03 UTC

    An array might be mixed, containing both objects and strings (or other scalar values). Also, some might be references to unblessed data structures.

    If the strings you want to construct from objects can be obtained by overloading double-quotes, then you don't need to test; just say,

    sub foo { my @stringy_args = map { "$_" } @{shift()}; # . . . }
    If overloading quotes is not feasable, you can say,
    sub foo { my @stringy_args = map { ref ? bestring($_) : "$_" } @{shift()}; # . . . }
    That lumps blessed objects with other references, and numbers with strings. For finer discrimination, Scalar::Util has a bunch of functions like blessed and looks_like_number to help out.

    After Compline,
    Zaxo

Re: Distinguishing between an array of objects and an array of strings
by bart (Canon) on Sep 22, 2005 at 10:58 UTC
    Strings are not references in Perl. So ref could actually tell you whether a scalar is a plain scalar, a refrerence, or an object.

    However, you should be very aware that people might be trying to pass objects, that they want to be treated as strings. See overload, operator '""', on how you can make an object from any class, return a useful result when treated as a string.

Re: Distinguishing between an array of objects and an array of strings
by Moron (Curate) on Sep 22, 2005 at 11:40 UTC
    The problem seems to me to be distinguishing references rather than testing for whether or not it's a reference. Furthermore, the ref() of a list of objects might be its scope e.g. 'main', depending how it is passed. I would make a test version of the subroutine that prints out ref $_[0] and run it for each kind of test case before writing the rest of the code to handle the cases.

    -M

    Free your mind

Re: Distinguishing between an array of objects and an array of strings
by Anonymous Monk on Sep 22, 2005 at 09:49 UTC
    perldoc -f ref
Re: Distinguishing between an array of objects and an array of strings
by shady (Sexton) on Sep 22, 2005 at 11:39 UTC
    Look at UNIVERSAL::isa, it's better than ref() in any cases, course it let you to determine the type of blessed reference. For example, see code below: if (UNIVERSAL::isa($ref, 'ARRAY')) { print 'It's an array reference'; }