Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Think about Loose Coupling
 
PerlMonks  

Source files, packages and name spaces

by Dinosaur (Beadle)
on Apr 15, 2002 at 12:34 UTC ( #159144=perlquestion: print w/ replies, xml ) Need Help??
Dinosaur has asked for the wisdom of the Perl Monks concerning the following question:

I am hacking together an application under Win98 with ActiveState perl 5.6.1, that forks a child process that does most of the work. To earlier avoid confusion (futher described in Win98 Socket Woes) over parent and child copies of data, I got the bright idea to put the child in its own package, so only the child could see the application data.

OTOH, the whole thing isn't really big enough to warrant chopping into modules, so I kept it all in a single file, like so:

use strict; use warnings; &Hello::printit; package Hello; sub printit; our($b) = "Hello, world!\n"; sub printit { print $b; }

When I run the above, I get warned that $b is undefined in the print call.

If I split the above into two files, and "require Hello;" in the main, the message prints OK.

The difference must lie in how and when "our($b)=..." gets executed, and where $b gets defined. But I would have expected $b to be defined in package Hello, either way.

Any explanations would be welcome!

(Note: there's no fork in the above example; fork isn't the problem, it's just the motivation for splitting things up)

Thanks! -- Dinosaur

Comment on Source files, packages and name spaces
Select or Download Code
Re: Source files, packages and name spaces
by broquaint (Abbot) on Apr 15, 2002 at 12:45 UTC
    Try changing around the position of where you declare the Hello package.
    package Hello; sub printit; # NB: used $bar instead of special var $b for sanity our $bar = "Hello, world!\n"; sub printit { print $bar; } 1; package main; use strict; use warnings; &Hello::printit(); __output__ Hello, world!
    It now works because $bar has been declared, so &printit() has something to print.
    HTH

    broquaint

Re: Source files, packages and name spaces
by Biker (Priest) on Apr 15, 2002 at 12:49 UTC

    I'm not sure if it's just in your example code, but please take the habit of not using $a and $b as variable names unless you're building a sort routine.

    I learnt it 'the hard way' in this thread.


    Everything went worng, just as foreseen.

•Re: Source files, packages and name spaces
by merlyn (Sage) on Apr 15, 2002 at 14:07 UTC
    My standard idiom for including multiple packages in the same file is:
    BEGIN { package My::Package; ... code goes here ... }
    That way, it acts like a use, causing all "regional" definitions and actions to be executed before the "main" program starts running.

    -- Randal L. Schwartz, Perl hacker

Re: Source files, packages and name spaces
by Dinosaur (Beadle) on Apr 15, 2002 at 16:11 UTC

    Thanks for the replies, guys. Broquaint's example makes clear what the problem is. Code occurring outside of any sub just gets executed in sequence -- the package statement doesn't alter that sequence of execution.

    Things which *do* alter that sequence include reordering the code (broquaint), forcing its early execution with BEGIN (merlyn), or pulling it in early with require (my initial example).

    FWIW, I'd read about the $a/$b trap on previous visits here. Guess that sort of thing doesn't sink in until you get burned by actually doing it -- at least that's how I've learned just about everything else :(

    --Dinosaur

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2014-04-18 05:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (461 votes), past polls