This is an obscure perl question, not for the faint of heart.
Suppose you have a hash. In that hash is some key "foo". The value
of "foo" in the hash might be either a scalar or an array. (Assume it
is not possible to modify the creation of the hash to make "foo"
always be an array.)
Example:
my %hash;
$hash{"foo"} = "one"; // it's a scalar here
$hash{"foo"} = [ "two", "three"]; // it's an array here
Is it possible to dereference $hash{"foo"} in such a way that the
result is always an array? That is, for the second example, I want to
get back the array as-is, but for the first example, I want perl to
wrap "one" as an array of one element. In other circumstances (i.e.
not when dereferencing a hash element) this is easy, because you can
just sort of evaluate a scalar in a list context and get a one-element
array.
So the first thing I tried was using an explicit cast to list
context:
my @foos = @{$hash{"foo"}};
This works for the second example but not for the first, because perl
knows that "one" is not an array reference.
Then I tried an implicit cast:
my @foos = $hash{"$foo"};
This works for the first example (creating the one-element array) but
not the second, because the hash element is "really" an array ref, so
@foos becomes a one-element array whose member is a reference to the
array of interest.
Some experimenting did yield a solution:
my @foos = cast_to_array($hash{"foo"});
sub cast_to_array {
my ($x) = @_;
ref($x) eq "ARRAY" ? @$x : ( $x );
}
But I have this itchy feeling that there is More Than One Way To Do
It, and that one of those other ways must be better.
So the question is: what is a one-line construction for dereferencing
this hash element to yield an array, regardless of whether the hash
value is really a scalar or an array? |