That's the Conditional Operator. You'll often see it referred to as the ternary operator (actually, that's what I usually call it). That single statement could be written as:
my $location_array_ref;
if (ref($location_ref) eq 'ARRAY') {
$location_array_ref = $location_ref;
}
else {
$location_array_ref = [ $location_ref ];
}
There's an assumption here that if it's not an arrayref, it will be a hashref. That seemed like a reasonable assumption to me; especially for a short script intended to demonstrate a technique. Furthermore, trying to guess what other data types you might be working with would simply be other assumptions.
The basic syntax for this operator is:
expression1 ? expression2 : expression3
There's nothing to say how complex any of those expressions might be; in fact, any of them could include another ternary operator.
Putting all that together, here's an example of far more robust code that allows arrayrefs, hashrefs, scalarrefs and non-reference scalar values with anything else generating an error.
foreach my $e (@{$getToysResults->{Toys}{Toy}}) {
my $location_ref = $e->{ToyLocations}{ToyLocation};
my $ref_type = ref $location_ref;
my $location_array_ref
= $ref_type eq 'ARRAY' ? $location_ref
: $ref_type eq 'HASH' ? [ $location_ref ]
: $ref_type eq 'SCALAR' ? [ { locationName => $$location_ref }
+ ]
: $ref_type eq '' ? [ { locationName => $location_ref }
+]
: undef;
die 'Data corrupt' unless defined $location_array_ref;
for my $location_array_hash_ref (@$location_array_ref) {
print $location_array_hash_ref->{locationName}, "\n";
}
}
If you want to play around with this, here's the code I used for my tests and the output. Note that I changed die to warn to see all conditions being exercised in a single run.
|