Re: Question about __PACKAGE__
by ikegami (Patriarch) on Jan 22, 2010 at 02:26 UTC
|
First, let's just make sure you know there's nothing special about __PACKAGE__ for the purpose of this discussion. Think of it as a function that returns the name of the package in which it resides.
I guess line3 is calling a object method but don't see any new() syntax.
A class method. The LHS of the arrow is a class name ('Foo'), not an object. It's funny you should mention new, since it's usually a class method as well.
Foo->new # Calls class method new
Foo->hello # Calls class method hello
__PACKAGE__->new # Calls class method new
__PACKAGE__->hello # Calls class method hello
Looks like line4 is calling a regular subroutine and that's why the error happens.
Correct. hello expects to be called as a class method or an object method, but it's called as a subroutine. As a result, the arguments it receives are different than those it expects.
Under which kind of situation should we use __PACKAGE__ to create an object instead of calling its new() in the caller program?
Never unless you're told to do so for a particular method
| [reply] [d/l] [select] |
|
Thanks for your reply. I guess I got it.
My understaning is that Foo->hello & hello are basically the same except the former is calling class method and passing 'Foo' to hello as the first arg, but the later is calling a subroutine and will not pass 'Foo'. How do you think?
I ask this question is because I see the following Item class generated by catalyst's create script using several _PACKAGE__->...() inside its package. I think the purpose of these class method calls is to initialize some class variables (data structures) instead of object variables for Item's parent class, which is DBIx::Class. Am I right ?
Thanks.
package Result::Item;
use strict;
use warnings;
use base 'DBIx::Class';
__PACKAGE__->load_components( "InflateColumn::DateTime", "Core" );
__PACKAGE__->table("item");
__PACKAGE__->add_columns(
"id",
{
data_type => "INTEGER",
default_value => undef,
is_nullable => 0,
size => undef,
},
);
1;
| [reply] [d/l] |
|
My understaning is that Foo->hello & hello are basically the same except the former is calling class method and passing 'Foo' to hello as the first arg, but the later is calling a subroutine and will not pass 'Foo'.
That's almost entirely correct. The method form, whether the invocant is the name of a class or an object, always performs dispatch. That is, Perl looks up the most appropriate method based on the given class. Then, Perl invokes that method and passes the invocant as the first argument.
The function form is a direct invocation of the subroutine of that name in the current package. There's no dispatch lookup step to find the most appropriate method. You get what's there, and the first argument is whatever you've passed in explicitly.
| [reply] |
|
My understaning is that Foo->hello & hello are basically the same except the former is calling class method and passing 'Foo' to hello as the first arg, but the later is calling a subroutine and will not pass 'Foo'. How do you think?
I think you understand, but your wording leaves to be desired. The same sub is called in both cases; the difference is in how it's called:
Foo->hello & hello are basically the same except the former is calling hello as a class method and passing 'Foo' (or whatever's left of the arrow) as the first arg, but the latter is calling hello as a subroutine and will not pass 'Foo'.
One difference that wasn't mentioned is that inheritance will come into play when hello is called as a method.
{ package Foo; sub hello { ... } }
{ package Bar; our @ISA = 'Foo'; }
Foo->hello('world'); # Foo::hello('Foo', 'world')
Bar->hello('world'); # Foo::hello('Bar', 'world')
Foo::hello('world'); # Foo::hello('world')
Bar::hello('world'); # hello not found in Bar
I think the purpose of these class method calls is to initialize some class variables
And maybe even create subs, yes.
| [reply] [d/l] [select] |
|
When I trace into the source of DBIx::Class, why I did not see any mehtod like table(), add_columns(), or load_components()?
| [reply] |
|
|
|
|
Re: Question about __PACKAGE__
by gam3 (Curate) on Jan 22, 2010 at 02:19 UTC
|
These are exactly the same after the compile stage
__PACKAGE__->hello('text1');
Foo->hello('text1');
These are also the same
hello(__PACKAGE__, 'text1');
hello('Foo', 'text1');
The difference between f('x') and 'x'->f() is that if
there is no sub f {} in Foo @INC will be used
to look for one.
Look at UNIVERSAL and perltoot.
-- gam3
A picture is worth a thousand words, but takes 200K.
| [reply] [d/l] [select] |
|
Do you mean these four lines belonged to Foo are calling class method instead of object method? Therefore no object is created by them, right?
__PACKAGE__->hello('test1');
Foo->hello('test2');
hello(__PACKAGE__, 'text3');
hello('Foo', 'text4');
However, if I call this line:
Foo->new()->hello('test5');
one object will be created. Am I right so far?
Thanks.
| [reply] [d/l] [select] |
|
Yes. Mind you, in practice, hello is probably only suppose to called one of the two ways.
| [reply] [d/l] |
|
bless(\sub {}, 'Foo')->hello('test5');
This just blesses a CODE_REF for fun. It could be a HASHREF or some other REF.
The only real difference between
'Foo'->hello()
and
bless(sub {}, 'Foo')->hello()
Besides the fact that the blessed version can contain data, is that
just before the blessed object is Garbage Collected,
DESTROY is called with it as the argument ($x->DESTROY). UNIVERSAL
contains a DESTROY method, so it always exists.
-- gam3
A picture is worth a thousand words, but takes 200K.
| [reply] [d/l] [select] |