Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Perl detect arrays?

Tags:

arrays

perl

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?

like image 599
Sandra Schlichting Avatar asked Mar 07 '11 23:03

Sandra Schlichting


People also ask

How do I check if something is an array in Perl?

The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0.

How do I view an array reference in Perl?

The Perl array reference can also be passed to a subroutine as shown below. sub add_numbers { my $array_ref = shift; ..... } @numbers = (11,2,3,45); $array_ref = add_numbers(\@numbers); In the above code snippet, we need to de-reference the array, so that the subroutine can take the elements from the original array.

How do I filter an array in Perl?

The Perl grep() function is a filter that runs a regular expression on each element of an array and returns only the elements that evaluate as true. Using regular expressions can be extremely powerful and complex. The grep() functions uses the syntax @List = grep(Expression, @array).


2 Answers

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.

like image 92
justkt Avatar answered Oct 04 '22 06:10

justkt


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.

like image 17
Eric Strom Avatar answered Oct 04 '22 06:10

Eric Strom