Подтвердить что ты не робот

Может ли Perl обнаруживать массивы?

У меня есть этот 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";
}

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

e
ARRAY(0x2603fa0)

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Существует несколько способов обнаружения массива в 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 [email protected];  # ok
    my $x = eval {\@$arrayobj} or die [email protected];  # ok
    my $x = eval {\@$object}   or die [email protected];  # ok
    my $x = eval {\@$overload} or die [email protected];  # also ok, since overloaded
    

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

Ответ 3

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

Ответ 4

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

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

Результат для вашего примера будет:

$VAR1 = {'a' => 'e'};
$VAR1 = {'a' => ['b','c']};