in reply to defined &{ $pkg . '::foo' } vs. $pkg->can( 'foo' )

O.k., you've gotten the answer to the underlying question, but you might still wonder what is the difference between those snippets of code, in terms of their practical effect. The first one answers the question, "Of the symbols defined in the given package, which ones are functions? (vs. scalars, arrays, etc.)" The second one answers the question, "Of the methods that the given class can handle, which ones are defined in the class, vs. in some ancestor class." It's worth noting that these tests can be fooled by AUTOLOAD and other aspects of the run-time dynamicity of perl.
  • Comment on Re: defined &{ $pkg . '::foo' } vs. $pkg->can( 'foo' )

Replies are listed 'Best First'.
Re^2: defined &{ $pkg . '::foo' } vs. $pkg->can( 'foo' )
by japhy (Canon) on Jul 14, 2005 at 21:01 UTC
    I have to pick a nit. The second one doesn't answer "of the methods that the given class can handle, which ones are defined in the given class?". The (psuedo)code for that would be @local = grep defined &{$class . "::$_"}, $obj->list_all_my_methods. The second one answers the question "of all the symbols in the given class, which ones are names of methods of the given class?".

    Case in point:

    package Parent; sub foo { 1 } package Child; @ISA = 'Parent'; sub new { bless {}, shift } $foo = 10; package main; my $pkg = "Child"; print join(", ", grep defined &{ $pkg . "::$_" }, keys %{ $pkg . '::' +}), "\n"; print join(", ", grep $pkg->can( $_ ), keys %{ $pkg . '::' }), "\n";
    This prints "new" on the first line, and "new, foo" on the second. I changed the defined() test a bit, because with $pkg in there, it's saying "of the symbols in $pkg, which are defined as functions in this current package I'm in?" rather than "... which are defined as functions in $pkg?".

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re^2: defined &{ $pkg . '::foo' } vs. $pkg->can( 'foo' )
by chromatic (Archbishop) on Jul 14, 2005 at 21:36 UTC
    It's worth noting that these tests can be fooled by AUTOLOAD and other aspects of the run-time dynamicity of perl.

    The second one fails only if you write broken code.