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

I have following code in a big build system inherited from somewhere. It's not only deprecated but nowadays it errors out and the "no strict" is a no go afaik.
sub PkgContains { my ($package, $sub) = @_; # Return TRUE if $package contains $sub no strict; local(*pkg_symtab) = eval("*${package}::"); return 0 unless defined(%pkg_symtab); return defined($pkg_symtab{$sub}); }
I changed it to this:
sub PkgContains { my ($package, $sub) = @_; # Return TRUE if $package contains $sub no strict; local(*pkg_symtab) = eval("*${package}::"); if (exists $pkg_symtab{$sub}){ return defined($pkg_symtab{$sub}); }else{ return 0; } }
My perl skills are very low so now the questions. What does the code do at all, do my changes make sense and how to improve this? I'm asking because I get an error with one of my make targets which didn't appear before the deprecate warning for "defined(%pkg_symtab)" went to be an error. Thanks in advance and regards, Uli

Replies are listed 'Best First'.
Re: error defined on hash
by choroba (Cardinal) on Dec 22, 2015 at 14:30 UTC
    Do you know that exists can be used for the same task?
    #! /usr/bin/perl use warnings; use strict; use Data::Dumper (); # No export. my $package = 'Data::Dumper'; my $subroutine = 'Dumper'; print exists &{ $package . "::$subroutine" };
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Thanks so far guys. Maybe I'll come back later.
Re: error defined on hash
by kcott (Archbishop) on Dec 22, 2015 at 15:54 UTC

    G'day Uli,

    Welcome to the Monastery.

    The bog standard response to this is to urge you to read "How do I post a question effectively?". However, you've obviously made some attempt to present a reasonably formatted question, and have said "My perl skills are very low", so let's work through it.

    Firstly, do you want to fix the problem or just stick your head in the sand and pretend there's no problem at all? Stating "... the "no strict" is a no go ..." rather suggests the latter and, if that's the case, simply adding

    no warnings;

    is possibly all you need.

    Read "perlintro: Safety net" (and follow the links therein) for more about this.

    Now, assuming you haven't just yelled "Hurray! I got rid of the warning." and are still with me, delete the totally erroneous (and, no doubt, highly misleading) comment "# Return TRUE if $package contains $sub" (that's not what "my ($package, $sub) = @_;" is doing) as well as the "no strict;" (on the following line). Ensure you have these lines:

    use strict; use warnings;

    near the top of your script then rerun your script.

    Next, you need to show us exactly what the error/warning messages are (as opposed to a prosaic description) within <code>...</code> tags. We also need to know how your calling &PkgContains which should include the context of that call.

    With that information, we can provide you with a much better answer. I strongly suspect there's a much better way to do what you want but, without additional information, this is purely guesswork.

    If you look through the documentation for defined, you'll no doubt see the reason for the deprecation warning.

    You may also see a way to check whether a particular subroutine has been defined. Functions provided by UNIVERSAL may be better suited to this. Other options may exist depending on the specifics of what you're doing and the context in which you're doing them.

    — Ken

Re: error defined on hash
by GotToBTru (Prior) on Dec 22, 2015 at 13:55 UTC

    Your changes are equivalent, near as I can tell. It appears to be checking a module for the presence of a subroutine.

    Dum Spiro Spero