Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: find module name from the module archive (in @INC) (updated)

by LanX (Saint)
on Dec 09, 2016 at 19:04 UTC ( [id://1177558]=note: print w/replies, xml ) Need Help??


in reply to find module name from the module archive

hmm just a quick remark:

Calling use will also execute the import function which might do unexpected things.

You might prefer require (or even do ) which are just part of use.

(mnemonic use > require > do > eval with > read as "extends")

Furthermore you should probably check the error code to avoid false negatives.

There are many reasons why a code execution might fail.

Saying so, a function to check @INC without eval-ing the located code would be safer°. (especially if you don't want to activate the whole dependency chain with consecutive use calls)

Cheers Rolf
(addicted to the Perl Programming Language and ☆☆☆☆ :)
Je suis Charlie!

update

°) The page for require has sample code showing how @INC is searched, just skip the part after do($realfilename); to avoid compilation and add the logic for ref($prefix) if needed. (alternatively see also these modules)

use Carp 'croak'; use version; sub require { my ($filename) = @_; if ( my $version = eval { version->parse($filename) } ) { if ( $version > $^V ) { my $vn = $version->normal; croak "Perl $vn required--this is only $^V, stopped +"; } return 1; } if (exists $INC{$filename}) { return 1 if $INC{$filename}; croak "Compilation failed in require"; } foreach $prefix (@INC) { if (ref($prefix)) { #... do other stuff - see text below .... } # (see text below about possible appending of .pmc # suffix to $filename) my $realfilename = "$prefix/$filename"; next if ! -e $realfilename || -d _ || -b _; $INC{$filename} = $realfilename; my $result = do($realfilename); # but run in caller's namespace if (!defined $result) { $INC{$filename} = undef; croak $@ ? "$@Compilation failed in require" : "Can't locate $filename: $!\n"; } if (!$result) { delete $INC{$filename}; croak "$filename did not return true value"; } $! = 0; return $result; } croak "Can't locate $filename in \@INC ..."; }

You might want to use this as a first step and doing your eval only if it's not found in a second step (in order to play safe). Like this you will only execute module code if the parsing mechanism fails (which shouldn't be ever the case and deserves a warning)

NB: This approach answers the question "Can a module be found in @INC" which is slightly different to "Is a module distribution installed" since:

  • @INC could have been manipulated and
  • distribution often include multiple modules.

Log In?
Username:
Password:

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

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

    No recent polls found