Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Namespace after forking()+eval()ing providing unexpected results

by JPaul (Hermit)
on Jan 23, 2002 at 10:05 UTC ( [id://140840]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings all,
I'm having a bit of trouble with a piece of code of mine. It works kinda like this:
I have two programmes, Launcher and Code. There are two modules, LaunchMod.pm and CodeMod.pm. Straightforward, right? Good. So:
Launcher loads Code from a text file, and passes it in a single string variable to LaunchMod.pm, which then does a little:
unless(fork) { eval($code) || die("Doh - $@\n"); }
Inside Code is:
use strict; use vars qw($me); use CodeMod; $me = "Bob"; &CodeMod::MySub;
And inside CodeMod::MySub is a line or two that, very simply (for testing purposes) prints out the contents of $main::me. Only problem is - it doesn't.
The above says that $main::me is undefined. If I don't use LaunchMod.pm to fork/eval, and instead put that same fork/eval code inside Launch itself, everything is hunky-dory.
Obviously I'm setting up the namespace wrong, but I'm just not understanding where... Whether it forks inside the main code (Launch) or off in its module, I don't see how that can affect the eval()ed code like this...
Help?

JP,
-- Alexander Widdlemouse undid his bellybutton and his bum dropped off --

Replies are listed 'Best First'.
Re: Namespace after forking()+eval()ing providing unexpected results
by chipmunk (Parson) on Jan 23, 2002 at 10:13 UTC
    It's hard to say without seeing some more of the code, but I note that eval executes the string within the current package. Thus, I suspect your problem is that LaunchMod starts with package LaunchMod;, and the code inside the eval is executed inside the LaunchMod package, setting $LaunchMod::me rather than $main::me.

    You can fix this by specifying the appropriate package somewhere... The Code file could start with package main;, or you could stick "package main;" onto the front of $code before evalling it.

    It may also be worth considering doing away with the use of globals altogether, passing $me into &CodeMod::MySub rather than depending on it being in a specific package.

      That makes lots of sense. I couldn't understand why if the fork/eval was out in LaunchMod.pm it wouldn't work, yet it would in Launcher itself - I saw only that it was doing the same code in two different places, the 'package' declaration didn't hit me...
      The 'package main;' makes the code work as I want it to, so I'm quite happy.

      The code example given is, as you can imagine, greatly simplified from the original software - where I'm using a number of globals to relate back and forth between Code and CodeMod.pm, as there are a lot of routines that use these globals - and I began to feel that passing three vars to one sub, which then distributes that to a bunch more, collects the results... and passes it all back? It just started getting really ugly...

      My thanks Chipmunk,
      JP
      -- Alexander Widdlemouse undid his bellybutton and his bum dropped off --

Re: Namespace after forking()+eval()ing providing unexpected results
by perrin (Chancellor) on Jan 23, 2002 at 20:22 UTC
    This is actually pretty simple. When you eval() code, you do it in the context of the current package. When you say use vars qw($me) in the code above from within the LaunchMod package, you are talking about LaunchMod::me, not main::me.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-04-23 15:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found