in reply to Question about __PACKAGE__

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

Replies are listed 'Best First'.
Re^2: Question about __PACKAGE__
by sman (Beadle) on Jan 22, 2010 at 04:01 UTC
    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()?
        found them with grep, though:
        1:53 spiceman@cynic ~/perl5/lib/perl5 % grep -R 'sub add_columns ' DBIx
        DBIx/Class/CDBICompat/ColumnGroups.pm:sub add_columns {
        DBIx/Class/CDBICompat/ColumnCase.pm:sub add_columns {
        DBIx/Class/DynamicDefault.pm:sub add_columns {
        DBIx/Class/TimeStamp.pm:sub add_columns {
        DBIx/Class/ResultSource.pm:sub add_columns {
        DBIx/Class/ResultSourceProxy.pm:sub add_columns {
        
        1:53 spiceman@cynic ~/perl5/lib/perl5 % grep -R 'sub table ' DBIx
        DBIx/Class/ResultSetManager.pm:sub table {
        DBIx/Class/ResultSourceProxy/Table.pm:sub table {
        
        1:53 spiceman@cynic ~/perl5/lib/perl5 % grep -R 'sub load_components ' .
        ./Class/C3/Componentised.pm:sub load_components {
        
        I found the corresponding classes that these three class methods belong to:

        DBIx::Class::ResultSourceProxy::Table
        table()
        add_columns()

        Class::C3::Componentised
        load_components()

        And I also know Class::C3::Componentised is the parent class of DBIx::Class that is the parent of Item, so this makes sense. But I don't know the relationship between DBIx::Class::ResultSourceProxy::Table and DBIx::Class.

        Any idea?