[Phoenix-pm] Eval Namespace Question
Douglas E. Miles
perlguy at earthlink.net
Mon Aug 7 19:42:21 PDT 2006
Scott Walters wrote:
>Hi Doug,
>
>So, what *have* you been up to?
>
>Don't use eval on a string. eval { } is fine to use and you should be
>trapping errors, and that's how that's done. 99% of the time people use
>eval on a string, they're trying to hammer in a screw.
>
>
>
I'm evaling a string because that's what I have. :) I might be
hammering a screw, but it's been working fine for several years. I
wrote the code knowing "Caveat Emptor". The real code is trapping
errors. I just made the smallest example that illustrated the behavior
I was wondering about. As far as what I've been up to, unfortunately,
mostly ASP. The Perl is cleansing me. :)
>>This means that in my code below, that $bar is in scope within the
>>eval. What blows me away is that $foo::foo is also in scope because of
>>the "package foo" statement in $eval_string. Does anyone know how perl
>>
>>#!/usr/bin/perl
>>package foo;
>>
>>
>
>Use strict and warnings.
>
>
>
>>$foo = "FOO!";
>>
>>
>
>
>
>>package bar;
>>my $bar = "BAR!";
>>my $perl_code = 'print "$bar $foo\n"';
>>print "$perl_code\n";
>>
>>my $eval_string = "package foo;\n$perl_code";
>>eval $eval_string;
>>
>>
>
>To answer your actual question, variables created (defined implicitly or explicitly)
>at the "top level" (outside of any blocks) have a scope called "file scope", where
>they're in scope until the end of the file. This would work with my $foo too.
>Sometimes people do this to get less scope than file scope:
>
>package foo; {
> my $foo = "FOO!";
>}
>
>package bar; {
> ...
>}
>
>There are other derivitives of out.
>
>Now, here's what you *should* be writing to avoid a plague of security and
>performance problems too numerous to enumerate and too pervasive to ignore
>the shame they've brought upon us all:
>
>package foo;
>use strict;
>use warnings;
>my $foo = "FOO!";
>
>package bar;
># note that strict and warnings also have file scope
>my $bar = "BAR!":
>my $perl_code = sub { print "$bar $foo\n"; };
>$perl_code->(); # note that you could pass arguments
>
>In this adaptation, you can't easily modify the code by prepending things
>like "package foo;", but dataflow is an entire other question. Rather than
>changing packages that code evaluates in, you should be passing objects in,
>and the object should encapsulate the set of values. Also, with code references,
>if the code reference references some variable (such as $foo and $bar), if
>the value of $foo or $bar changes (the *same* $foo or $bar, not one
>created later or in a different scope) then the value that gets printed
>also changes.
>
>So...
>
>1. use code references instead of eval
>2. use object instances rather than packages full of global values
>3. when you want a global of some sort, use the constant module... use constant foo => 'FOO!';
>4. report to the list more often and tell us how your life is going
> and what you're up to, for chrissakes!
>
>As far as the "use objects" spiel... I'm assuming the worst, so forgive me for that, but
>in my experience, the not-so-bad-scenario can usually be considered to be similar enough
>to the bad scenario that the refactoring/best practice/design heuristic/whatever
>still applies. Computing package names on the fly invokes fear and dread for good
>reason and should only be used to intentionally voke fear and dread. Etc, etc, etc.
>
>Glad to see you're still alive, Doug.
>
>-scott
>
>
>
>
>
>>_______________________________________________
>>Phoenix-pm mailing list
>>Phoenix-pm at pm.org
>>http://mail.pm.org/mailman/listinfo/phoenix-pm
>>
>>
More information about the Phoenix-pm
mailing list