Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

'package' and 'do'

by integral (Hermit)
on Dec 06, 2003 at 20:17 UTC ( [id://312799]=perlquestion: print w/replies, xml ) Need Help??

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

I have some code in a file which I am loading with do. It's a mixture of code to run and subroutine definitions. I'm loading this file multiple times with different package statements in effect to declare the subs in different packages.

In some debugging messages I'm trying to use __PACKAGE__ to give the current package, but it isn't working. It's always printing 'main', even though subs are ending up in the correct package. Attached below is an example case.

Can anyone figure out what I'm missing?

#### test1-do.pl $var++; print " Point A: " . __PACKAGE__ . " $var\n"; #### test.pl #!/usr/bin/perl -w $main::var = $B::var = 5; print "Point 1: " . __PACKAGE__ . " $main::var $B::var\n"; package B; $rv = do "test1-do.pl"; die $@ if $@; die $! unless defined $rv; print "Point 2: " . __PACKAGE__ . " $main::var $B::var\n"; __END__ As I understand it the code in the do should be evaluated in the same +package it was called from. This does happen for the assignment ($var++), but it doesn't seem to g +et the right __PACKAGE__ #### Actual output Point 1: main 5 5 Point A: main 6 Point 2: B 5 6 ^^ $B::var has actually been changed #### Expected: Point 1: main 5 5 Point A: B 6 Point 2: B 5 6

--
integral

Replies are listed 'Best First'.
Re: 'package' and 'do'
by duff (Parson) on Dec 06, 2003 at 20:59 UTC

    test1-do.pl is a different compilation unit. package declarations do not extend beyond the current compilation unit. You can think of them as lexical in nature with "scope" similar to what you would get with "my" variables.

      That makes sense, which would imply that the behaviour of __PACKAGE__ is correct, but surely the code would output Point 2: B 6 5 (ie $main::var incremented, not $B::var).

      Also perldoc -f do, implies an equivalence to eval `cat stat.pl`, although it does then say that 'do FILENAME' cannot see lexicals in the enclosing scope. This is one reason why I was using do instead of eval. Is there some way to have this behaviour with eval so that I can get around the scoping of package, but still hide lexical variables?

      --
      integral
      

        Quite a while ago I recall a thread in which it was noted that some Perl constructs results in a case where there isn't just a single "current package" (I searched but wasn't able to find it and have run out of time for now).

        There are several different ways in which the "current package" can be felt. What __PACKAGE__ returns, how $x is interpretted (if there is no lexical $x in scope), where sub foo puts the subroutine, etc.

        I think you've discovered this same problem. The outer package should either "leak" in or it should be reset to "main", but some constructs manage to only reset some of the "current package" items (when it should be either "all" or "none", not "some").

        So, I think it is simply a bug in Perl, though a minor one.

                        - tye
Re: 'package' and 'do'
by bsb (Priest) on Dec 22, 2003 at 08:58 UTC
    You can probably use caller to get the, erm, caller.
    $ perl -le 'package A; do "./done.pl"' A-e1 $ cat done.pl print caller;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (7)
As of 2024-04-25 11:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found