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

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.

Related

Why do some users quote classnames in Perl?

Looking at Type::Tiny, I see that the class name in the call to Type::Tiny->new is quoted in the official docs,
my $NUM = "Type::Tiny"->new(
name => "Number",
constraint => sub { looks_like_number($_) },
message => sub { "$_ ain't a number" },
);
Why is this? Is this mere style? Is there any performance ramifications for this practice?
Take a simpler example
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
In the above example, the constant Foo resolves to "Bar", so so this calls "Bar"->new not "Foo"->new. How do you stop the subroutine from resolving? You can quote it.
"Foo"->new();
As for the performance implication, things are not made worse by using a string rather than a bareword. I've confirmed the optree generated by O=Deparse is the same. So as a general rule, it seems it's better to quote the Classnames if you value correctness.
This is mentioned in Programming Perl, (sadly in the context of indirect method invocation)
... so we'll tell you that you can almost always get away with a bare class name, provided two things are true. First, there is no subroutine of the same name as the class. (If you follow the convention that subroutine names like new start lowercase and class names like ElvenRing start uppercase, this is never a problem). Second, the class been loaded with one of
use ElvenRing;
require ElvenRing;
Either of these declarations ensures that Perl knows ElvenRing is a module name, which forces any bare name like new before the class name ElvenRing to be interpreted as a method call, even if you happen to have declare a new subroutine of your own in the current package.
And, that makes sense: the confusion here can only happen if your subroutines (typically lowercase) have the same name as a class (typically uppercase). This can only happen if you violate that naming convention above.
tldr; it is probably a good idea to quote your classnames, if you know them and you value correctness over clutter.
Side note: alternatively you can stop resolution of a bareword to a function by affixing a :: to the end of it, for example in the above Foo::->new.
Thanks to Ginnz on reddit for pointing this out to me, and to Toby Inkster for the comment (though it didn't make sense to me on first read).
Explicitly quoting the class name rather than using a bareword (which is treated as a string) is one of three ways to avoid syntactic ambiguity. The Invoking Class Methods section of the perlobj documentation explains.
Because Perl allows you to use barewords for package names and
subroutine names, it sometimes interprets a bareword’s meaning
incorrectly. For example, the construct Class->new() can be
interpreted as either 'Class'->new() or Class()->new() .In English,
that second interpretation reads as “call a subroutine named Class(),
then call new() as a method on the return value of Class().” If there
is a subroutine named Class() in the current namespace, Perl will
always interpret Class->new() as the second alternative: a call to
new() on the object returned by a call to Class().
See this odd case in action with the demo below.
#! /usr/bin/env perl
use strict;
use warnings;
sub Type::Tiny { print "Returning Bogus\n" ; return "Bogus" }
sub Type::Tiny::new { print "Type::Tiny::new\n" }
sub Bogus::new { print "Bogus::new\n" }
my $class = "Type::Tiny";
Type::Tiny->new;
Type::Tiny::->new;
"Type::Tiny"->new;
$class->new;
Its output is
Returning Bogus
Bogus::new
Type::Tiny::new
Type::Tiny::new
Type::Tiny::new
The rest of the aforementioned documentation section shows how to protect against surprising behavior or inadvertent errors.
You can force Perl to use the first interpretation (i.e., as a
method call on the class named "Class") in two ways. First, you can
append a :: to the class name:
Class::->new()
Perl will always interpret this as a method call.
Alternatively, you can quote the class name:
'Class'->new()
Of course, if the class name is in a scalar Perl will do the right
thing as well:
my $class = 'Class';
$class->new();
Applying to your question, all of the calls below are equivalent.
Type::Tiny::->new( … );
"Type::Tiny"->new( … );
my $class = "Type::Tiny";
$class->new( … );
Appending :: to the end has the advantage of producing a helpful warning. Say you accidentally typed
Type::Tinny::->new;
That produces
Bareword "Type::Tinny::" refers to nonexistent package at ./try line 15.
Can't locate object method "new" via package "Type::Tinny" (perhaps you forgot to load "Type::Tinny"?) at ./try line 15.

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().

Why aren't both versions of this code failing the -c Perl check?

The new method of Parse::RecDescent has this prototype:
sub new ($$$)
{
# code goes here
}
and if I create an object like this:
my $parser = Parse::RecDescent->new($grammar);
it will create a parser, and the method will receive 2 parameters "Parse::RecDescent" and $grammar, right? If I try to create an object like:
Parse::RecDescent::new("Parse::RecDescent",$grammar)
this will fail saying "Not enough arguments for Parse::RecDescent::new", and I understand this message. I'm only passing 2 parameters. However, I don't understand why the arrow version works.
Can you explain?
Function prototypes are not checked when you call it as an OO-style method. In addition, you bypass prototype checking when you call a sub with &, as in &sub(arg0, arg1..);
From perldoc perlsub:
Not only does the "&" form make the argument list optional, it also disables any prototype checking on arguments you do provide. This is partly for
historical reasons, and partly for having a convenient way to cheat if you know what you're doing. See Prototypes below.
Method calls are not influenced by prototypes either, because the function to be called is indeterminate at compile time, since the exact code called depends on inheritance.
While Parse::RecDescent::new("Parse::RecDescent", $grammar) is syntactically correct, that's a pretty smelly way of calling the constructor, and now you are forcing it to be defined in that class (rather than in an ancestor). If you really need to validate your arguments, do it inside the method:
sub new
{
my ($class, #args) = #_;
die "Not enough arguments passed to constructor" if #args < 2;
# ...
}
See also this earlier question on prototypes and why they aren't usually such a great idea.

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.

Why shouldn't I use UNIVERSAL::isa?

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' ) { ... }