Can Perl detect arrays?

21,632

Solution 1

Yes, perl can detect what type a variable is. Use the ref() function. For example:

if (ref($var) eq 'ARRAY') {
   # Do stuff
}

See more in this perlmonks discussion.

Solution 2

There are several ways to detect an array in Perl, each with different functionality.

Given the following variables:

my $array    = [1, 2, 3];
my $arrayobj = bless [1, 2, 3] => 'ARRAY';
my $object   = bless [1, 2, 3] => 'Some::Object';
my $overload = bless {array => [1, 2, 3]} => 'Can::Be::Array';
{package Can::Be::Array;
    use overload fallback => 1, '@{}' => sub {$_[0]{array}}  
}
  • the ref builtin function

    ref $array    eq 'ARRAY'
    ref $arrayobj eq 'ARRAY'
    ref $object   eq 'Some::Object'
    ref $overload eq 'Can::Be::Array'
    
  • the reftype function from the core module Scalar::Util

    reftype $array    eq 'ARRAY'
    reftype $arrayobj eq 'ARRAY'
    reftype $object   eq 'ARRAY'
    reftype $overload eq 'HASH'
    
  • the blessed function from Scalar::Util which primarily is used to determine if a variable contains an object that you can call methods on.

    blessed $array    eq undef
    blessed $arrayobj eq 'ARRAY'
    blessed $object   eq 'Some::Object'
    blessed $overload eq 'Can::Be::Array'
    
  • catching an exception

    my $x = eval {\@$array   } or die $@;  # ok
    my $x = eval {\@$arrayobj} or die $@;  # ok
    my $x = eval {\@$object}   or die $@;  # ok
    my $x = eval {\@$overload} or die $@;  # also ok, since overloaded
    

In the last example, the \@ pair dereferences the argument as an ARRAY, and then immediately takes the reference to it. This is a transparent operation that returns the same value if that value is an ARRAY. If the value is overloaded, it will return the array ref that the module created. However, if the value can not be dereferenced as an ARRAY, perl will throw an exception.

Solution 3

If you need the answer dynamically, use the ref function.

Share:
21,632

Related videos on Youtube

Sandra Schlichting
Author by

Sandra Schlichting

Updated on July 09, 2022

Comments

  • Sandra Schlichting
    Sandra Schlichting almost 2 years

    I have this script

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    use Data::Dumper;
    
    my %x1 = ();
    $x1{"a"} = "e";
    
    my %x2 = ();
    $x2{"a"} = ["b","c"];
    
    p(\%x1);
    p(\%x2);
    
    sub p {
        my $x = shift @_;
        print $x->{a};
        print "\n";
    }
    

    which outputs

    e
    ARRAY(0x2603fa0)
    

    The problem is I don't know when the input is an array or a scalar, and when it is an array I would like to print those values as well.

    Can p be modified to do this?

    • Eric Strom
      Eric Strom about 13 years
      => I encourage you to use longer variable and field names, it helps a lot with readability (especially when you come back to some code you wrote a while ago). @Claudiu => no one appreciates your spamming the question; it's great that you like python, save it for the python questions