Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

How to determine if a sub is defined in a package, without calling it?

by lamber45 (Initiate)
on Feb 27, 2017 at 20:10 UTC ( [id://1183004]=perlquestion: print w/replies, xml ) Need Help??

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

So I'm trying to build an interpreter for a certain non-perl bytecode, and I think I'll be able to represent classes in that system as perl packages.

Method invocations in that system are by method name (OK to overload) and argument types. When the bytecode says to call a method "foo" with descriptor "EGXX", I'd like my code to first check whether a sub "foo__EGXX" exists in the target package (or any of its base packages, recursively); if it doesn't find it, I'd like to check for a sub "foo" (also recursively).

Is there a (standard or easy-to-install) module that does the "find a sub, don't invoke it yet" part? If I have to roll my own, I guess I'd do recursive ascent through @ISA, but how do I test if a sub is defined? Is it as simple as

if (${ $package . '::' }{ $longName }) { $value = eval '$objectref->' . $longName . '( @args )'; } else { $value = eval '$objectref->' . $shortName . '( @args )'; }
?

  • Comment on How to determine if a sub is defined in a package, without calling it?
  • Download Code

Replies are listed 'Best First'.
Re: How to determine if a sub is defined in a package, without calling it?
by haukex (Archbishop) on Feb 27, 2017 at 20:34 UTC

    Since you're asking about methods and not plain subs, i.e. inheritance plays a role, I believe what you are looking for is UNIVERSAL's can.

    { package Foo; sub foo {} } { package Bar; use parent -norequire, 'Foo'; sub bar {}; } print Foo->can('foo')//'undef', "\n"; print Foo->can('bar')//'undef', "\n"; print Bar->can('foo')//'undef', "\n"; print Bar->can('bar')//'undef', "\n"; __END__ CODE(0x1343fa8) undef CODE(0x1343fa8) CODE(0x1343b68)

    Update: If you don't want to take inheritance into account and just want to know if a certain subroutine has been defined in a specific package, you can use defined(&Package::subroutine).

Re: How to determine if a sub is defined in a package, without calling it?
by stevieb (Canon) on Feb 27, 2017 at 20:37 UTC

    You can use defined:

    perl -wMstrict -E 'sub blah{}; say defined &blah' 1 perl -wMstrict -E 'say defined &blah'

    Or, in another package:

    perl -wMstrict -E 'package X;{sub blah{}} say defined &X::blah' 1

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1183004]
Approved by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-19 01:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found