The package code is compiled into is what "scalar caller(0)" would return if it were called. It is determined at compile time, there is nothing you can do at run time to change it.
Anno | [reply] [d/l] |
| [reply] |
| [reply] [d/l] |
| [reply] |
i think the point you're aiming at lies in how you use the eval() function. the perl docs imprecise about the possibilites this mighty function implies. if you take a look at how the ModPerl::RegistryCooker handles compilation, caheing and execution of CGI-like scripts within their individual namespaces, you might find an answer to your question.
the perldoc says about eval():
eval EXPR
eval BLOCK
eval In the first form, the return value of EXPR is parsed and executed as if it were a little
Perl program. The value of the expression (which is itself determined within scalar con-
text) is first parsed, and if there weren't any errors, executed in the lexical context of
the current Perl program, so that any variable settings or subroutine and format defini-
tions remain afterwards. Note that the value is parsed every time the "eval" executes.
If EXPR is omitted, evaluates $_. This form is typically used to delay parsing and subse-
quent execution of the text of EXPR until run time.
In the second form, the code within the BLOCK is parsed only once--at the same time the
code surrounding the "eval" itself was parsed--and executed within the context of the cur-
rent Perl program. This form is typically used to trap exceptions more efficiently than
the first (see below), while also providing the benefit of checking the code within BLOCK
at compile time.
to be more precise, an example:
suppose there is a file named
my $filename = '/var/lib/some_dir/sume_subdir/filename';
which contains the code we want to be executed within its own, individual namespace. the first step is to construct the namespace:
my $nspace = $filename;
$nspace =~ s/[^a-zA-Z]/_/g;
now $nspace will be '_var_lib_some_dir_some_subdir_filename'
in order to be perl-compliant, prepend this name with something like
$nspace= "ROOT::NameSpace::$nspace";
now slurp in the contents of $filename:
open FILE, $filename or die $!;
my @content = <FILE>;
close FILE;
i assume the code in $filename is executable, and what we want is to prevent perl from executing it, except it does so within the namespace we want it to do. hence we make a module out of our code:
my $eval = qq~package $nspace;
sub handler {
local $0 = $filename;~ . join('', @content);
what we now have in our hands, is a full-fledged perl module, which won't be executed, but just compiled when we now call
eval $eval;
die $@ if $@; # will die if there are any compile time errors.
now $eval contains the compiled code from the freshly created module. later on you execute this code by simply calling its handler() method:
my $codevector_name = join '::', $nspace, 'handler';
my $codevector = &\{ $codevector_name };
eval { $codevector->(@_) }; # pass arguments to the handler
die $@ if $@
this is how ModPerl has been knitted, and most of what i've been telling stems from a code which i derived from ModPerl::RegistryCooker for my own project. three hurrah to Andreas J. Koenig, Doug MacEachern and Stas Bekman, who do a wonderful job. | [reply] [d/l] [select] |
| [reply] |
Argh... another two CPAN one-liner modules:
# alias
*{$new_package . '::'} = *{$old_package . '::'};
# remove
undef *{$new_package . '::'};
| [reply] [d/l] |
Is there something virtuous about using a lot of code to do something?
| [reply] |
I can just wrap that in an eval, but that loses my compile-time syntax checking.
If you typically do this in a string eval, I'm not sure what it buys you to avoid eval. I guess you could wrap the whole thing up in a BEGIN if you want to see errors as soon as possible, though.
| [reply] |
This could work easily if there were a non-scoping (read: unhygienic) version of eval. Then it would be just a
if ($foo) {
unhygienic_eval "package $foo";
sub bar { 23 }
}
But I have no experience with the perl guts and expect this to be much more work than it looks like.
Ordinary morality is for ordinary people. -- Aleister Crowley
| [reply] [d/l] |