Why shouldn't I use UNIVERSAL::isa? - perl

According to this
http://perldoc.perl.org/UNIVERSAL.html
I shouldn't use UNIVERSAL::isa() and should instead use $obj->isa() or CLASS->isa().
This means that to find out if something is a reference in the first place and then is reference to this class I have to do
eval { $poss->isa("Class") }
and check $# and all that gumph, or else
use Scalar::Util 'blessed';
blessed $ref && $ref->isa($class);
My question is why? What's wrong with UNIVERSAL::isa called like that? It's much cleaner for things like:
my $self = shift if UNIVERSAL::isa($_[0], __PACKAGE__)
To see whether this function is being called on the object or not. And is there a nice clean alternative that doesn't get cumbersome with ampersands and potentially long lines?

The primary problem is that if you call UNIVERSAL::isa directly, you are bypassing any classes that have overloaded isa. If those classes rely on the overloaded behavior (which they probably do or else they would not have overridden it), then this is a problem. If you invoke isa directly on your blessed object, then the correct isa method will be called in either case (overloaded if it exists, UNIVERSAL:: if not).
The second problem is that UNIVERSAL::isa will only perform the test you want on a blessed reference just like every other use of isa. It has different behavior for non-blessed references and simple scalars. So your example that doesn't check whether $ref is blessed is not doing the right thing, you're ignoring an error condition and using UNIVERSAL's alternate behavior. In certain circumstances this can cause subtle errors (for example, if your variable contains the name of a class).
Consider:
use CGI;
my $a = CGI->new();
my $b = "CGI";
print UNIVERSAL::isa($a,"CGI"); # prints 1, $a is a CGI object.
print UNIVERSAL::isa($b,"CGI"); # Also prints 1!! Uh-oh!!
So, in summary, don't use UNIVERSAL::isa... Do the extra error check and invoke isa on your object directly.

See the docs for UNIVERSAL::isa and UNIVERSAL::can for why you shouldn't do it.
In a nutshell, there are important modules with a genuine need to override 'isa' (such as Test::MockObject), and if you call it as a function, you break this.
I have to say, my $self = shift if UNIVERSAL::isa($_[0], __PACKAGE__) doesn't look terribly clean to me - anti-Perl advocates would be complaining about line noise. :)

To directly answer your question, the answer is at the bottom of the page you linked to, namely that if a package defines an isa method, then calling UNIVERSAL::isa directly will not call the package isa method. This is very unintuitive behaviour from an object-orientation point of view.
The rest of this post is just more questions about why you're doing this in the first place.
In code like the above, in what cases would that specific isa test fail? i.e., if it's a method, in which case would the first argument not be the package class or an instance thereof?
I ask this because I wonder if there is a legitimate reason why you would want to test whether the first argument is an object in the first place. i.e., are you just trying to catch people saying FooBar::method instead of FooBar->method or $foobar->method? I guess Perl isn't designed for that sort of coddling, and if people mistakenly use FooBar::method they'll find out soon enough.
Your mileage may vary.

Everyone else has told you why you don't want to use UNIVERSAL::isa, because it breaks when things overload isa. If they've gone to all the habit of overloading that very special method, you certainly want to respect it. Sure, you could do this by writing:
if (eval { $foo->isa("thing") }) {
# Do thingish things
}
because eval guarantees to return false if it throws an exception, and the last value otherwise. But that looks awful, and you shouldn't need to write your code in funny ways because the language wants you to. What we really want is to write just:
if ( $foo->isa("thing") ) {
# Do thingish things
}
To do that, we'd have to make sure that $foo is always an object. But $foo could be a string, a number, a reference, an undefined value, or all sorts of weird stuff. What a shame Perl can't make everything a first class object.
Oh, wait, it can...
use autobox; # Everything is now a first class object.
use CGI; # Because I know you have it installed.
my $x = 5;
my $y = CGI->new;
print "\$x is a CGI object\n" if $x->isa('CGI'); # This isn't printed.
print "\$y is a CGI object\n" if $y->isa('CGI'); # This is!
You can grab autobox from the CPAN. You can also use it with lexical scope, so everything can be a first class object just for the files or blocks where you want to use ->isa() without all the extra headaches. It also does a lot more than what I've covered in this simple example.

Assuming your example of what you want to be able to do is within an object method, you're being unnecessarily paranoid. The first passed item will always be either a reference to an object of the appropriate class (or a subclass) or it will be the name of the class (or a subclass). It will never be a reference of any other type, unless the method has been deliberately called as a function. You can, therefore, safely just use ref to distinguish between the two cases.
if (ref $_[0]) {
my $self = shift;
# called on instance, so do instancey things
} else {
my $class = shift;
# called as a class/static method, so do classy things
}

Right. It does a wrong thing for classes that overload isa. Just use the following idiom:
if (eval { $obj->isa($class) }) {
It is easily understood and commonly accepted.

Update for 2020: Perl v5.32 has the class infix operator, isa, which handles any sort of thing on the lefthand side. If the $something is not an object, you get back false with no blowup.
use v5.32;
if( $something isa 'Animal' ) { ... }

Related

What does it mean when 'can' function is used in this way?

I know that 'can' method inspects if package has the method 'some_method'. But, what is happening in the "->(animal => $x)" part?
$z = __PACKAGE__->can("some_method")->(animal => $x)
can() will return reference to method if it exists and then method will be dereferenced with "dereferencing arrow". You must wrap this into eval, or exception will rise if "some_method" doesn't exist. Read more here:
About can(): perldoc UNIVERSAL
About dereferencing of subroutines: perldoc perlref
The can returns a code reference to the method. Perl "methods" are just normal Perl subroutines that expect the class or object (the "invocant") as the first argument.
sub some_method {
my( $self, #args ) = #_;
...
}
In the arrow notation, the invocant is on the left and the method is on the right:
$object->method();
That's really a call of a subroutine in the invocant's package where the invocant becomes the first argument:
SomePackage::method( $object )
Remember, an object is merely a blessed reference, which means the reference has been labelled with a package name. We call that an "object", and when you call a method on an object, it uses that label to determine where to start looking for the right subroutine to use.
Calling it this way directly ignores several object orientation features though. You won't use inheritance, for example. You are directly calling a particular subroutine rather than letting Perl find the appropriate method.
So, back to your code. The can can search through the inheritance tree to find a subroutine to call. It might not be in the package you start with. It then returns a code reference for whatever it found, but you don't know which package supplied that subroutine. You also don't know who asked for the code reference.
You have the code reference now and you want to call it. You have to supply the invocant on your own:
$coderef->( INVOCANT, #args );
Someone has decided that "animal" (a simple string, which means this might be a class method) is the right invocant. The first argument to this code is not an object:
$coderef->( 'animal', #args );
But, don't use code like that. Almost no one does that and it's subverting many of the advantages of object-oriented code. I tend to write it more like:
if( eval { __PACKAGE__->can('some_method') } ) {
__PACKAGE__->some_method( #args );
}
Note that using __PACKAGE__ here is also weird (this coming from a habitual abuser of that). I suspect that if you are using that, there's a better way to accomplish the task.

Why do '::' and '->' work (sort of) interchangeably when calling methods from Perl modules?

I keep getting :: confused with -> when calling subroutines from modules. I know that :: is more related to paths and where the module/subroutine is and -> is used for objects, but I don't really understand why I can seemingly interchange both and it not come up with immediate errors.
I have perl modules which are part of a larger package, e.g. FullProgram::Part1
I'm just about getting to grips with modules, but still am on wobbly grounds when it comes to Perl objects, but I've been accidentally doing this:
FullProgram::Part1::subroutine1();
instead of
FullProgram::Part1->subroutine1();
so when I've been passing a hash ref to subroutine1 and been careful about using $class/$self to deal with the object reference and accidentally use :: I end up pulling my hair out wondering why my hash ref seems to disappear. I have learnt my lesson, but would really like an explanation of the difference. I have read the perldocs and various websites on these but I haven't seen any comparisons between the two (quite hard to google...)
All help appreciated - always good to understand what I'm doing!
There's no inherent difference between a vanilla sub and one's that's a method. It's all in how you call it.
Class::foo('a');
This will call Class::foo. If Class::foo doesn't exist, the inheritance tree will not be checked. Class::foo will be passed only the provided arguments ('a').
It's roughly the same as: my $sub = \&Class::foo; $sub->('a');
Class->foo('a');
This will call Class::foo, or foo in one of its base classes if Class::foo doesn't exist. The invocant (what's on the left of the ->) will be passed as an argument.
It's roughly the same as: my $sub = Class->can('foo'); $sub->('Class', 'a');
FullProgram::Part1::subroutine1();
calls the subroutine subroutine1 of the package FullProgram::Part1 with an empty parameter list while
FullProgram::Part1->subroutine1();
calls the same subroutine with the package name as the first argument (note that it gets a little bit more complex when you're subclassing). This syntax is used by constructor methods that need the class name for building objects of subclasses like
sub new {
my ($class, #args) = #_;
...
return bless $thing, $class;
}
FYI: in Perl OO you see $object->method(#args) which calls Class::method with the object (a blessed reference) as the first argument instead of the package/class name. In a method like this, the subroutine could work like this:
sub method {
my ($self, $foo, $bar) = #_;
$self->do_something_with($bar);
# ...
}
which will call the subroutine do_something_with with the object as first argument again followed by the value of $bar which was the second list element you originally passed to method in #args. That way the object itself doesn't get lost.
For more informations about how the inheritance tree becomes important when calling methods, please see ikegami's answer!
Use both!
use Module::Two;
Module::Two::->class_method();
Note that this works but also protects you against an ambiguity there; the simple
Module::Two->class_method();
will be interpreted as:
Module::Two()->class_method();
(calling the subroutine Two in Module and trying to call class_method on its return value - likely resulting in a runtime error or calling a class or instance method in some completely different class) if there happens to be a sub Two in Module - something that you shouldn't depend on one way or the other, since it's not any of your code's business what is in Module.
Historically, Perl dont had any OO. And functions from packages called with FullProgram::Part1::subroutine1(); sytax. Or even before with FullProgram'Part1'subroutine1(); syntax(deprecated).
Later, they implemented OOP with -> sign, but dont changed too much actually. FullProgram::Part1->subroutine1(); calls subroutine1 and FullProgram::Part1 goes as 1st parameter. you can see usage of this when you create an object: my $cgi = CGI->new(). Now, when you call a method from this object, left part also goes as first parameter to function: $cgi->param(''). Thats how param gets object he called from (usually named $self). Thats it. -> is hack for OOP. So as a result Perl does not have classes(packages work as them) but does have objects("objects" hacks too - they are blessed scalars).
Offtop: Also you can call with my $cgi = new CGI; syntax. This is same as CGI->new. Same when you say print STDOUT "text\n";. Yeah, just just calling IOHandle::print().

How to find which type of object I have on Perl?

How can I find which object type I am dealing with in Perl? I tried using perl -d to enter the debugger, but I'm not sure what to do then. Likewise I'd like a way to easily see which methods are available for each object, how can that be done?
The standard way for telling what type of object you have is either ref or Scalar::Util::blessed. If you know the object is blessed, then they return the same information.
my $class1 = blessed( $obj );
my $class2 = ref $obj;
But ref will also return 'HASH' for unblessed hashes, while blessed refuses to play that game.
As for a list of methods, for the blessed pointer style of perl object, it's easy enough to code one up yourself. The code below works fairly well for me. It returns the names of functions (those taking the "CODE slot" of the given name) mapped to the package which defines them.
sub class_methods {
use Class::ISA;
my $obj = shift;
return unless ref( $obj );
my %meth_names;
foreach my $anc ( Class::ISA::self_and_super_path( ref $obj ), 'UNIVERSAL' ) {
my $stash = \%{"$anc\::"};
my #funcs
= grep { m/^[_\p{Alpha}]/ # begins with _ or alpha
&& !exists $meth_names{$_} # no clobbering
&& defined *{$stash->{$_}}{CODE} # has a filled CODE slot
} keys %$stash
;
# assign to the "hash slice", keyed by all the entries in #funcs
# the value of $anc repeated as many times as elements in #funcs.
#meth_names{#funcs} = ( $anc ) x #funcs;
}
return %meth_names;
}
This will work for reasonably complex objects as well, but if the owning package contains a lot of generated code, it's not going to be that helpful to know which package the generators stuck the code pointer in. It's going to mean more to find what package generated the code.
This being the case, you might get the code out of running your code, including Data::Dumper and setting $Data::Dumper::Deparse to 1, like so: ( local $Data::Dumper::Deparse = 1;) and then dumping the code pointer, like so: say Dumper( $code_ref );
It WON'T work for valid methods that have yet to be created by any AUTOLOAD methods. If you see those in the list, the object might do more, but what all it does, you don't know.
The "base class" UNIVERSAL is included, because that class contains behavior usable by the object.
Good luck.
The blessed function from Scalar::Util will tell you the package name of any blessed reference (an object.)
To find out what methods are available, consult the documentation for that package. Alternatively, you can use something like Class::MOP::Class to instantiate a metaclass and get introspective information about the methods it contains.
Just for completeness, here's a very short intro to the debugger.
perl -d your_program
starts it under the bugger. You'll get control at the first executable line (use statements and the like have already executed at this point).
's' will step to the next line. Once you've entered an 's', you can simply press return to repeat it. 's' will step down into functions/subroutines/methods. Either keep stepping till you return or enter the 'r' command to execute the rest of the function and return to right after the call.
If you want to step 'over' subroutines - that is, execute them and return without having to step in and return, use 'n. The carriage return after the first 'n' also keeps doing 'n' for you.
If you know the line where you want to stop, use the 'b' command - b linenumber - to set a breakpoint, then 'c' to continue till you reach it. Note that every time you 'c' and come back to the breakpoint you will stop again. Use 'B linenumber' to turn the breakpoint back off.
So let's assume you've gotten to something like this:
my $obj = complex_function_returning_unknown_thing;
The debugger's just shown you this line, which says "I have not executed this yet, but it is what I will do next." Enter 'n' to execute the subroutine, then use the 'x' command to look at the object: 'x $obj'. If it's big, you can say '|x $obj' which runs the output through a pager. To see what methods the object has, use 'm $obj'.
There's a lot more to the debugger, but you can indeed use it for this kind of thing - you need to simply see the type of an object you're getting from some code and find out what methods the object you got has.
It may be more useful to 'x' the object, and then go look at the source of the class the object's been blessed into to find out what you should do as opposed to what you can do. The 'x' command is pretty much 'print ref($obj)' crossed with Data::Dumper anyway.
You are looking for reflection in Perl. I just googled "Perl Reflection" without quotes and this came up:
http://coding.derkeiler.com/Archive/Perl/perl.beginners/2004-10/0291.html
Edit:
And this:
http://markmail.org/message/i5mzik56ry4zoxxq
Edit:
And this:
http://en.wikipedia.org/wiki/Reflection_(computer_science)#Perl

How can I write a Perl subroutine that works both as a normal subroutine or a class method?

I'm writing a function that is mostly static in nature. I want to plug it into Template Toolkit, which passes along the class name. In essential, it is doing
ClassName->function( $args.. )
but I want it to do something like
ClassName::function( $args.. )
inside
sub function {
}
what is the proper way to handle both cases?
In general, there isn't. a sub is either written to be called as a method or it isn't.
See how File::Spec::Functions handles this situation by prepending the package name to the argument list.
Now, in a very specific, limited case, you can do:
shift if $_[0] eq __PACKAGE__;
as the first line in your sub to discard the first argument when the sub is called as a class method.
Here is a safer version that combines Sinan's and Alan's answers, and also:
Handles the possibility that the method is called from a derived object
Won't misinterpret ClassName::function("ClassName") as a method call
The code:
if (#_ == $nArgsExpectedForThisFunc + 1) {
$_[0] eq __PACKAGE__ || UNIVERSAL::isa($_[0], __PACKAGE__) || die;
shift;
}
This requires that you know the number of arguments to expect; if you don't, but your first argument can be differentiated from the possible allowable values that might be sent when it is called as a method (e.g. if your first argument must be an arrayref), the same general principle can still be applied.
Template Toolkit expects it's plugins to use OO, so there's no way around providing that interface. If you also want a functional interface you have a couple of options.
Perl doesn't really distinguish between a function and a method. The main difference is that the method invocation syntax implicitly includes the object reference (or class name, depending on how it was invoked) as the first argument. You can use function call syntax and provide the referent manually:
ClassName::function('ClassName', #args);
but that's messy. The cleaner solution would be to split it into two subs with one a wrapper for the other. e.g.
package ClassName;
sub function {
# do something
}
sub method {
my $class = shift;
function(#_);
}
The function could be a wrapper around the method as well. As Sinan alluded to, File::Spec does this by creating two modules: one with the OO interface and one with a functional interface.

Is there an andand for Perl?

I'd rather do this:
say $shop->ShopperDueDate->andand->day_name();
vs. this:
say $shop->ShopperDueDate->day_name() if $shop->ShopperDueDate;
Any ideas?
(This idea is inspired by the Ruby andand extension.)
(Actually it is inspired by the Groovy language, but most people don't know that ;-)
update: I think that both maybe() and eval {} are good solutions. This isn't ruby so I can't expect to read all of the methods/functions from left to right anyway, so maybe could certainly be a help. And then of course eval really is the perl way to do it.
You can use Perl's eval statement to catch exceptions, including those from trying to call methods on an undefined argument:
eval {
say $shop->ShopperDueDate->day_name();
};
Since eval returns the last statement evaluated, or undef on failure, you can record the day name in a variable like so:
my $day_name = eval { $shop->ShopperDueDate->day_name(); };
If you actually wish to inspect the exception, you can look in the special variable $#. This will usually be a simple string for Perl's built-in exceptions, but may be a full exception object if the exception originates from autodie or other code that uses object exceptions.
eval {
say $shop->ShopperDueDate->day_name();
};
if ($#) {
say "The error was: $#";
}
It's also possible to string together a sequence of commands using an eval block. The following will only check to see if it's a weekend provided that we haven't had any exceptions thrown when looking up $day_name.
eval {
my $day_name = $shop->ShopperDueDate->day_name();
if ($day_name ~~ [ 'Saturday', 'Sunday' ] ) {
say "I like weekends";
}
};
You can think of eval as being the same as try from other languages; indeed, if you're using the Error module from the CPAN then you can even spell it try. It's also worth noting that the block form of eval (which I've been demonstrating above) doesn't come with performance penalties, and is compiled along with the rest of your code. The string form of eval (which I have not shown) is a different beast entirely, and should be used sparingly, if at all.
eval is technically considered to be a statement in Perl, and hence is one of the few places where you'll see a semi-colon at the end of a block. It's easy to forget these if you don't use eval regularly.
Paul
I assume your second example should better be:
say $shop->ShopperDueDate ? $shop->ShopperDueDate->day_name() : undef;
instead of what it actually says.
Anyway, you can't do it with exactly that syntax without a source filter because undef isn't an object, but an unary operator, so it can't have any methods.
Instead, consider this:
package noop;
our $maybe = bless [], 'noop';
sub AUTOLOAD { undef };
This $noop::maybe is an object; all of its methods return undef though. Elsewhere, you'll have a regular function like this:
sub maybe { $_[0] || $noop::maybe; }
Then you can write this:
say maybe($shop->ShopperDueDate)->day_name()
This works because "maybe" returns returns its argument if true, otherwise it returns our $noop::maybe object which has methods which always return undef.
EDIT: Correction! the ->andand-> syntax can be had without a source filter, by using an XS that mucks about with Perl's internals. Leon Timmermans made an implementation that takes this route. It replaces the undef() function globally, so it's likely to be a lot slower than my method.
I think I've just written it. I've just uploaded it to CPAN, you can find it here.
Something like (untested):
use Object::Generic::False;
sub UNIVERSAL::andand { $_[0] || Object::Generic::False->false }
UNIVERSAL is automatically a subclass of all other classes, so this provides andand for all objects.
(Obviously creating methods in UNIVERSAL has the potential for conflicts or surprising action at a distance,
so it shouldn't be used carelessly.) If the object upon which the andand method is called is true, return it;
otherwise return a generic false object which returns itself for any method call used upon it.