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

Fellow monks, I come to you with a multitude of problems, all slightly related to one another, seeking the preservation of my sanity...

1) Are there any caveats about an eval use that I should be aware about? Specifically, why does the following snippet not work as expected?
use warnings; eval "use Data::Dumper;"; print Dumper "asdf"; Name "main::Dumper" used only once: possible typo at - line 3. print() on unopened filehandle Dumper at - line 3.
2) How can I use a local package to demonstrate a throwaway? I tried something similar to this, but Perl complained about not being able to find the package in @INC.
use Durf; print(ALPHA); package Durf; use constants ALPHA => 1; 1;
3) I'm trying to dynamically load a package dependant on @ARGV (hence the attempt at eval). And the package to be included defines constants, but does not export them. Should I be able to access these constants by referring to them with their full package names? If I do not use any eval trickery and type out Package::Name::CONSTANT, it works as expected. But if I try saying eval("use $argv;"); it does not yield any compilation errors, but Package::Name::CONSTANT throws any error like a bareword.

All of the above are stumping my peers, and any light you could shed on the situation would be much appreciated.

Cheers.

Replies are listed 'Best First'.
Re: eval use, local packages, and use constants
by Corion (Patriarch) on Sep 07, 2007 at 06:43 UTC

    use My::Package; basically is

    BEGIN { require My::Package; My::Package->import(...); };

    Your first question relates to that - the eval delays the execution of the use statement until after compile time, which means that the print Dumper ... line gets interpreted as print {Dumper} ..., that is a print to a filehandle named Dumper. You could disambiguate that by using

    print Dumper(...);

    The answer to your second question will be clear when you look, again, at what use really is:

    # use Durf; # basically is BEGIN { require Durf; Durf->import(...); };

    ... and as there is no file Durf.pm (or Durf.pmc), this fails. Just leave out the use line and you'll be allright. There are other ways to trick require (and <c>use) into not going looking for a file, but not calling require is the easiest.

    Dynamically loading packages should, again, be done at compile time, especially if you want the constant names to be interpreted as subroutines/constants:

    BEGIN { for (@ARGV) { eval "use $_; 1" or die $@; # don't forget to reraise module errors }; };