You have use strict and use warning turned on and you're using a
package. When you use it as a program everything is cool. But when it
is run as a package it wants you to use the package scoped variable. So
you need to do:
eval 'sub greet { print "$Foo::greet\n" }';
Or to really use the global variable I think you use something like:
eval 'sub greet { print "$::greet\n" }';
or
eval 'sub greet { print "$main::greet\n" }';
I'm not really sure which on you want. They both work though.
Justin Rogers
[EMAIL PROTECTED]
[EMAIL PROTECTED]
-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED]] On Behalf Of
$Bill Luebkert
Sent: Monday, April 23, 2001 05:09 AM
To: [EMAIL PROTECTED]
Subject: Re: Problem with eval() and BEGIN { ... }
Steve Hay wrote:
>
> "$Bill Luebkert" wrote:
>
> > Steve Hay wrote:
> > >
> > > I have a strange problem with "eval" and "BEGIN" blocks.
> > >
> > > If I compile the attached module (Foo.pm) then it reports no
problems:
> > >
> > > C:\Temp>perl -c Foo.pm
> > > Foo.pm syntax OK
> > >
> > > If I run the same module then it executes correctly, eval()ing
some code
> > > and saying it's okay:
> > >
> > > C:\Temp>perl Foo.pm
> > > eval()'d OK
> > >
> > > But if I try and use the module from any script then it reports a
> > > compilation failure in the
> > > line which "require"d the module; this is most easily seen with a
Perl
> > > one-liner:
> > >
> > > C:\Temp>perl -MFoo -e 1
> > > eval() ERROR:
> > > Global symbol "$greet" requires explicit package name at (eval 1)
line
> > > 1.
> > >
> > > Compilation failed in require.
> > > BEGIN failed--compilation aborted.
> > >
> > > Why???!!!
> > >
> > > What's even stranger is that if I change the "{ ... }" block in
the
> > > module into a
> > > "BEGIN { ... }" block, or if I remove the curly braces altogether
and
> > > put the enclosed
> > > code at the file-scope level, then it works fine!
> > >
> > > Why???!!!
> >
> > Probably because $greet isn't defined in the eval context.
> >
> > Try:
> > eval {
> > my $greet = 'Hello, world.';
> > sub greet { print "$greet\n" }
> > }
> > if ($@) { die "eval() ERROR:\n$@\n" } else { print "eval()'d
OK\n" }
>
> It's true that this works, but why doesn't my original example?
>
> According to the Perl manpage for eval(), the EXPR being eval()'d is
executed IN
> THE CONTEXT OF THE CURRENT PERL PROGRAM, so it should "see" the $greet
anyway.
>
> Indeed, I thought one classic way to setup closures was exactly this
-- to
> eval() a subroutine within the scope of a lexical variable.
>
> Also, why does making the block into a BEGIN block or removing the
block
> altogether make any difference, and why does it only fail when it's in
a module
> being use()'d, not when it's in a program being run?
>
> This is only a workaround to my problem -- it doesn't explain what's
actually
> going on.
As near as I can reckon, it is looking for a global $greet and my guess
is
that the eval is not truly in the confines of the bracketing { } in your
example, but seems to have file scope. You'll have to get Jan or one of
the experts in source to give you the real reason. In the meantime, try
a globla variable or use my work around.
--
,-/- __ _ _ $Bill Luebkert ICQ=14439852
(_/ / ) // // DBE Collectibles http://www.todbe.com/
/ ) /--< o // // Mailto:[EMAIL PROTECTED]
http://dbecoll.webjump.com/
-/-' /___/_<_</_</_ http://www.freeyellow.com/members/dbecoll/
_______________________________________________
Perl-Win32-Users mailing list
[EMAIL PROTECTED]
http://listserv.ActiveState.com/mailman/listinfo/perl-win32-users
_______________________________________________
Perl-Win32-Users mailing list
[EMAIL PROTECTED]
http://listserv.ActiveState.com/mailman/listinfo/perl-win32-users