Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Question about __PACKAGE__

by sman (Beadle)
on Jan 22, 2010 at 01:58 UTC ( #818866=perlquestion: print w/replies, xml ) Need Help??

sman has asked for the wisdom of the Perl Monks concerning the following question:

Hello everyone, I'm doing some comparing between the usage of class and module. I declare a class named Foo with a instance method called hello as the following:
1 package Foo; 2 3 __PACKAGE__->hello('test1'); 4 hello('test2'); 5 6 sub hello { 7 my ($self, $arg) = @_; 8 print "hello=". $arg. "\n"; 9 } 10 1;
And the result is like this:
arg=test1 Use of uninitialized value $arg in concatenation (.) or string at line + 8
I am a bit confused by the usage of __PACKAGE__. In terms of the result, I guess line3 is calling a object method but don't see any new() syntax. Looks like line4 is calling a regular subroutine and that's why the error happens. Am I right about this?

Under which kind of situation should we use __PACKAGE__ to create an object instead of calling its new() in the caller program?

Thank.

Replies are listed 'Best First'.
Re: Question about __PACKAGE__
by ikegami (Pope) 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

      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;
        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.

        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.

        When I trace into the source of DBIx::Class, why I did not see any mehtod like table(), add_columns(), or load_components()?
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.
      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.
        Yes. Mind you, in practice, hello is probably only suppose to called one of the two ways.
        It is important to note that Perl OO does not have any "built in" concept of data. There is no default Constructor and the Destructor consists of a call to DESTROY.

        It might be more descriptive to rewrite Foo->new()->hello('test5'); as

        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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://818866]
Approved by toolic
Front-paged by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2021-03-07 19:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favorite kind of desktop background is:











    Results (122 votes). Check out past polls.

    Notices?