Может ли Perl обнаруживать массивы? - PullRequest
15 голосов
/ 08 марта 2011

У меня есть этот скрипт

#!/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";
}

, который выводит

e
ARRAY(0x2603fa0)

Проблема в том, что я не знаю, когда вход представляет собой массив или скаляр, а когда этомассив Я хотел бы также распечатать эти значения.

Можно ли изменить p для этого?

Ответы [ 4 ]

38 голосов
/ 08 марта 2011

Да, Perl может определить тип переменной. Используйте функцию ref () . Например:

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

Подробнее в этом обсуждении perlmonks .

14 голосов
/ 08 марта 2011

Существует несколько способов обнаружения массива в Perl, каждый из которых имеет различные функциональные возможности.

С учетом следующих переменных:

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}}  
}
  • ref встроенная функция

    ref $array    eq 'ARRAY'
    ref $arrayobj eq 'ARRAY'
    ref $object   eq 'Some::Object'
    ref $overload eq 'Can::Be::Array'
    
  • функция reftype из основного модуля Scalar :: Util

    reftype $array    eq 'ARRAY'
    reftype $arrayobj eq 'ARRAY'
    reftype $object   eq 'ARRAY'
    reftype $overload eq 'HASH'
    
  • функция blessed из Scalar :: Util, которая в основном используется для определения, содержит ли переменная объект, для которого можно вызывать методы.

    blessed $array    eq undef
    blessed $arrayobj eq 'ARRAY'
    blessed $object   eq 'Some::Object'
    blessed $overload eq 'Can::Be::Array'
    
  • перехватисключение

    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
    

В последнем примере пара \@ разыменовывает аргумент как ARRAY, а затем немедленно получает ссылку на него.Это прозрачная операция, которая возвращает то же значение, если это значение равно ARRAY.Если значение перегружено, оно вернет массив ref, созданный модулем.Однако, если значение не может быть разыменовано как ARRAY, perl сгенерирует исключение.

1 голос
/ 08 марта 2011

Если вам нужен динамический ответ, используйте функцию ref.

0 голосов
/ 08 марта 2011

Если вы хотите просто напечатать переменную, замените print ... на print Dumper ...:

$Data::Dumper::Indent = 0;
print Dumper($x);

Для вашего примера вы получите:

$VAR1 = {'a' => 'e'};
$VAR1 = {'a' => ['b','c']};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...