I'm trying to untangle some legacy code where an operation is done on $value iff its size is more than x (where x is a hard coded int). This is what it currently looks like:
if (scalar(@{$value}) > x) {
...
}
As with all legacy code, this $value can be almost anything (hash, scalar, array) although it's expected to be an array of different objects. This code currently fails with a "Not an ARRAY reference" around 5% of the time and I'm trying to figure out what's the possible $value that can break it.
I assumed it might fail if the $value is undefined so I even gave it a || [] but to no avail (same error):
if (scalar(@{$value || []}) > x) {
...
}
I'm also trying to figure out why I need the @{}? My understanding is that that evaluates $value in a list context so that scalar can later ensure I get the size. Does that make the code more robust or can I just directly use scalar $value? Does @{} even do what I think it does?
I'm using perl 5.8.
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:
Output:
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 useRef::Util
to inspect it:Output:
Observations:
print
outputs every element with no separators:AliceBobCharlie
3
print
outputs every pair with no separators:y5x4
2/8