У вас есть два вопроса.Я отвечу на них отдельно:
Вопрос: Что делает @{}
?
Когда вы пишете @{$thing}
, вы разыменовываете $thing
в массив,Как вы заметили, это работает только тогда, когда $thing
является ссылкой на массив.(Другими операторами разыменования являются %{$thing}
для хеш-ссылок и ${$thing}
для скалярных ссылок.)
Вам do нужен оператор разыменования там.Учтите это:
my $arrayref = [ 'Alice', 'Bob', 'Charlie' ];
my $hashref = { x => 4, y => 5 };
my $string = "Hello, world";
for my $thing ($arrayref, $hashref, $string) {
print "thing --> ", $thing, "\n";
print "scalar(thing) --> ", scalar($thing), "\n";
}
Вывод:
thing --> ARRAY(0x7f3b8054e468)
scalar(thing) --> ARRAY(0x7f3b8054e468)
thing --> HASH(0x7f3b80560678)
scalar(thing) --> HASH(0x7f3b80560678)
thing --> Hello, world
scalar(thing) --> Hello, world
Нет смысла заставлять $thing
использовать скалярный контекст. Это уже скаляр!
Вопрос: Как безопасно разыменовать скаляр?
Если вы не знаете, какой тип ссылки содержится в $thing
,Вы можете использовать Ref::Util
для его проверки:
use Ref::Util qw( is_arrayref is_hashref );
for my $thing ($arrayref, $hashref, $string) {
if (is_arrayref($thing)) {
print "array: thing --> ", @{$thing}, "\n";
print "array: scalar(thing) --> ", scalar(@{$thing}), "\n";
}
elsif (is_hashref($thing)) {
print "hash: thing --> ", %{$thing}, "\n";
print "hash: scalar(thing) --> ", scalar(%{$thing}), "\n";
}
else
{
print "else: thing --> ", $thing, "\n";
}
}
Вывод:
array: thing --> AliceBobCharlie
array: scalar(thing) --> 3
hash: thing --> y5x4
hash: scalar(thing) --> 2/8
else: thing --> Hello, world
Наблюдения:
- arrayref,когда разыменовывается, становится списком его элементов.
print
выводит каждый элемент без разделителей: AliceBobCharlie
- Ссылка на arrayref при разыменовании и принудительном преобразовании в скаляр становится числом элементов:
3
- Хеш-ссылка при разыменовании, становится списком ключей и значений.
print
выводит каждую пару без разделителей: y5x4
- Хэш-ссылка, когда разыменовывается и вводится в скаляр, становится строкой , где первое число - это число ключей ивторое число - количество сегментов в хеш-таблице:
2/8