I'm using PDL. If I am given variable $foo
that can be a hash reference, an array reference, a scalar, or a piddle (which can be empty or null), how can I tell if it's a piddle?

- 23,492
- 9
- 63
- 110

- 4,800
- 10
- 50
- 67
2 Answers
The typical way to check if something is of a certain class is with isa
.
if( $thing->isa("PDL") ) { ... }
This respects inheritance. So long as $thing
is a subclass of PDL (or says it is) the above will work. This protects you both against custom subclasses and changes to PDL itself. Below is an example.
use strict;
use warnings;
use v5.10;
package MyPDL;
our @ISA = qw(PDL);
package main;
use PDL;
use Scalar::Util qw(blessed);
my $stuff = pdl [1..10];
say blessed $stuff; # PDL
say "\$stuff is a PDL thing" if $stuff->isa("PDL"); # true
my $bar = MyPDL->new([1..10]);
say blessed $bar; # MyPDL
say "\$bar is a PDL thing" if $bar->isa("PDL"); # true
However, method calls don't work on non-references and unblessed references; you'll get an error if you try. You can work around this in two ways. First is to use eval BLOCK
to trap the error, like try
in another language.
if( eval { $thing->isa("PDL") } ) { ... }
If $thing
is not an object, eval
will trap the error and return false. If $thing
is an object, it will call isa
on it and return the result.
The downside is this will trap any error, including an error from isa
. Rare, but it happens. To avoid that, use Scalar::Util's blessed() to first determine if $thing
is an object.
use Scalar::Util qw(blessed):
if( blessed $thing && $thing->isa("PDL") ) { ... }

- 153,029
- 25
- 195
- 336
You can use Scalar::Util to find out if a variable is:
- an object (using the
blessed
function) - a reference, and if so, what type of reference (using the
reftype
function)
You can use the isa
method to find out whether an object is an instance of a particular class or inherits from that class.
Piddles are simply PDL objects, i.e. things that have been blessed into the PDL
class, so
$foo->isa('PDL')
will return true if $foo
is a piddle.
All together:
use strict;
use warnings 'all';
use 5.010;
use PDL;
use Scalar::Util qw(blessed reftype);
my $scalar = 19;
my $arrayref = [ qw(foo bar) ];
my $hashref = { baz => 'qux' };
my $piddle = pdl [ 1..10 ];
foreach my $item ($scalar, $arrayref, $hashref, $piddle) {
my $reftype;
if ( defined(blessed($item)) ) {
say 'piddle' if $item->isa('PDL');
}
elsif ( defined($reftype = reftype($item)) ) {
say $reftype;
}
else {
say 'Not a reference';
}
}
Output:
Not a reference
ARRAY
HASH
piddle

- 23,492
- 9
- 63
- 110
-
1This answer would be better if it's used `isa` to respect inheritance rather than `reftype`. – Schwern Apr 25 '16 at 23:08
-
Yes, I should have said `blessed`. I didn't even know `blessed` returned the type. – Schwern Apr 25 '16 at 23:15
-
@Schwern Thanks, fixed. Now I feel like my answer is just a rip-off of yours :-/ – ThisSuitIsBlackNot Apr 25 '16 at 23:45
-
I'm fine with saying the same thing two different ways. – Schwern Apr 25 '16 at 23:51