in reply to referring to packages indirectly

Because symbol tables are hashes, a reference to a non-existant subroutine will auto-vivify that subroutine name into the symbol table, albeit with no (useful) code attached. To achieve your aim you should test for the existance of the subroutine within the package.

eval { no strict "refs"; require "$fqn_file"; local $SIG{'__DIE__'}; $ref = exists ${ $foo . '::' }{ 'f_preferred' } ? \&{$foo . "::f_preferred"} : undef; }; warn $@ if $@;

Note. That's still not foolproof because if the package contains a forward reference to the sub

sub f_preferred;

But no body, the symbol will exist in the stash, and it's value will be set to a CODE(0xhhhhhhh) reference, but an attempt to call it will fail with 'undefined subroutine'.

I've never worked out where the code reference for declared, but un-bodied (and autovivified) subs, points?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: referring to packages indirectly
by ikegami (Patriarch) on Oct 11, 2006 at 15:28 UTC

    Grab the CODE slot of the typeglob if you want to check if a function is defined. The existance of any of the package variables $f_preferred, @f_preferred, %f_preferred, etc will cause exists to return true, so exists is not suitable.

    my $pkg = ...; my $mod_file = ...; # require always returns true or an exception. eval { require $mod_file } or warn $@; my $sym = do { no strict 'refs'; ${ "${pkg}::" }{ 'f_preferred' } }; my $ref = *$sym{CODE};

    If the function hasn't been declared, or if the function has been declared (sub func;) but not defined (sub func { ... }), then $ref will be undef.

    Update: Rephrased for increased clarity. Code unchanged.