Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Testing package membership

by FreakyGreenLeaky (Sexton)
on Nov 21, 2008 at 08:25 UTC ( #725066=perlquestion: print w/replies, xml ) Need Help??
FreakyGreenLeaky has asked for the wisdom of the Perl Monks concerning the following question:


I'm looking for a cleaner way to test if a package member exists/is valid.

I'm currently testing it thusly:
package Util::Stuff::abc; sub attrib1 { 1 } sub attrib2 { 10 } ... eval { $symref->attrib1; }; if (!$@) { ... $symref->attrib1 is OK ... }
Is there a cleaner way?


UPDATE: forgive me if I'm not using the correct Perl nomenclature. I'm an old procedural boy an' all this OO'ism makes me sleepy...

Replies are listed 'Best First'.
Re: Testing package membership
by GrandFather (Sage) on Nov 21, 2008 at 08:45 UTC

    If you are testing for methods you can:

    use strict; use warnings; use strict; package Abc; sub new { return bless {}, shift; } sub attrib1 { 1 } sub attrib2 { 10 } package main; my $abc = Abc->new (); for my $methName (qw(attrib1 attrib2 attrib3)) { next unless my $meth = $abc->can ($methName); print "Can $methName: ", $meth-> (), "\n"; }


    Can attrib1: 1 Can attrib2: 10

    Perl reduces RSI - it saves typing
      Thanks - but I need to step through almost a hundred packages (which is existing code) extracting those attribute values. So modifying the code and adding sub new() for each is problematic.

        There is a theme running through your last three questions, but it's not clear to me just what you are trying to achieve (although you could be trying to auto-document some legacy code). We may be able to help more if you let us in on the bigger problem.

        Perl reduces RSI - it saves typing
Re: Testing package membership
by moritz (Cardinal) on Nov 21, 2008 at 08:46 UTC
    You can ask with $ref->can('methodname') or yourpackage->can('methodname') if such a method exists (which will not work if AUTOLOAD is in effect, but otherwise it's fine).

    can is defined and documented in UNIVERSAL.

      Got it! Using ->can() wrapped in eval{} does the trick nicely:
      package Util::Stuff::abc; sub attrib1 { 1 } sub attrib2 { 10 } ... eval { if ($symref->can('attrib1')) { ... $symref->attrib1 is OK ... }};
      Thanks to GrandFather and moritz.
      Hmm, looks like AUTOLOAD is in effect since ->can() is failing.

      Looks like I'm stuck with eval{}, unless there's another way.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://725066]
Approved by GrandFather
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (15)
As of 2016-10-24 13:30 GMT
Find Nodes?
    Voting Booth?
    How many different varieties (color, size, etc) of socks do you have in your sock drawer?

    Results (305 votes). Check out past polls.