You have two questions there. I'll answer them separately:
Question: What is @{} doing?
When you write @{$thing}, you are dereferencing $thing into an array. As you have noticed, this only works when $thing is an array reference. (Other dereferencing operators are %{$thing} for hash references and ${$thing} for scalar references.)
You do need a dereferencing operator there. Consider this:
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";
}
Output:
thing --> ARRAY(0x7f3b8054e468)
scalar(thing) --> ARRAY(0x7f3b8054e468)
thing --> HASH(0x7f3b80560678)
scalar(thing) --> HASH(0x7f3b80560678)
thing --> Hello, world
scalar(thing) --> Hello, world
There's no point in forcing $thing to a scalar context. It's already a scalar!
Question: How can I safely dereference a scalar?
If you don't know what kind of reference is contained in $thing, you can use Ref::Util to inspect it:
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";
}
}
Output:
array: thing --> AliceBobCharlie
array: scalar(thing) --> 3
hash: thing --> y5x4
hash: scalar(thing) --> 2/8
else: thing --> Hello, world
Observations:
- The arrayref, when dereferenced, becomes a list of its elements.
print outputs every element with no separators: AliceBobCharlie
- The arrayref, when dereferenced and forced into a scalar, becomes the number of elements:
3
- The hashref, when dereferenced, becomes a list of keys and values.
print outputs every pair with no separators: y5x4
- The hashref, when dereferenced and forced into a scalar, becomes a string where the first number is the number of keys and the second number is the number of buckets in the hashtable:
2/8