Can Perl detect arrays?
I have this script
#!/usr/bin/perl
use warnings;
use stri开发者_开发知识库ct;
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?
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.
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::Utilreftype $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.
If you need the answer dynamically, use the ref
function.
If you just want to pretty print a variable, replace your print ...
with print Dumper ...
:
$Data::Dumper::Indent = 0;
print Dumper($x);
Output for your example would be:
$VAR1 = {'a' => 'e'};
$VAR1 = {'a' => ['b','c']};
精彩评论