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

'package' and 'do'

by integral (Hermit)
on Dec 06, 2003 at 20:17 UTC ( #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 (Vicar) 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
Node Status?
node history
Node Type: perlquestion [id://312799]
Approved by gmax
help
Chatterbox?
[Eily]: you could tie a variable into not having the same value each time, if you like to make people who try to debug your code facepalm
[Corion]: perl -wle 'package o; use overload q("") => sub {warn "str"; ""}, bool => sub{warn "bool"; 1}; package main; my $o={}; bless $o => o; print "Yay" if ($o && !length($o))'
[Corion]: But people writing such code should document the objects they construct and why it makes sense for an object to be invisible as string while being true in a boolean context
[hippo]: That's equal parts clever and horrendous.
[Eily]: the overload version wouldn't return true with "$x" && !length $x though, I guess
[hippo]: The more I look at this code, the more $x is a plain old scalar and the more this condition will never be true. I'm calling it a bug at this point.
[hippo]: Thanks for your input which has soothed my sanity (a little)
[Corion]: Eily: Sure - if you force both things into stringy things, then you break that magic. But that would also mean that you changed the expression, as now $x = 0.00 will be true instead of false as it were before
[Corion]: Ah no, at least in my feeble experiments that doesn't change the meaning
[Corion]: We sell sanity in small packages ;)

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (8)
As of 2017-07-27 13:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I came, I saw, I ...
























    Results (413 votes). Check out past polls.