views:

116

answers:

3

I don't really understand how scoping works in Perl modules. This doesn't print anything. I would like it if running a.pl printed 1

b.pm

$f=1;

a.pl

use b;

print $f
+11  A: 

OK, you have a lot of misconceptions that we can best address by fixing your immediate problem and pointing you to good resources.

b.pm should be:

package b;
our $f = 1;
1;

a.pl should be

use b;
print $b::f

run the whole thing with perl -I. a.pl

Now go read perldocperlmod very carefully.

Also read perldocstrict.

David M
`strict` and `warnings` for the `win`.
Chris Lutz
Although this technically works, it's usually the wrong design for the problem.
brian d foy
+3  A: 

You should start off by reading about Perl modules in the manual: perldoc perlmod at the commandline, or go to http://perldoc.perl.org/perlmod.html.

Ether
+2  A: 

Short answer: Most probably because you're running this code on a case-insensitive file system, where asking for the module b loads the built-in module B. Your module is not getting loaded at all. If you rename b, you get the result you expect.

The longer answer included lots of chiding for failing to observe even minimal good practice, and has been elided.

darch
-1 Perl's packages are case sensitive, so the compiler backend `B.pm` is not called at all. renaming the package will not solve the problem
Eric Strom
@Eric Depends on the platform. The Windows filesystem is case-insensitive, for example.
Greg Bacon
However, it is true that naming packages with lower-cased names is not a best practice, and the variables $a and $b are treated differently.
Ether
I think this is the right answer. If OP changes `b.pm` to `c.pm` and `use b` to `use c`, then both files are operating on the global variable `$f` and the program works as he expected.
mobrule
To test whether this is correct, OP should run: `use b; print $INC{'b.pm'}` and see where the `b` module is loaded from. On Cygwin, I get: `/usr/lib/perl5/5.10/i686-cygwin/b.pm` -- the core B module.
mobrule
nice! on Mac it's `/opt/local/lib/perl5/5.8.9/darwin-2level/b.pm`
David M
@mobrule in the original question, `$f` wouldn't be in scope regardless of whether or not the right b.pm was loaded. The unfortunate choice of the name `b` might be *part* of the problem, but it's not the biggest part.
hobbs
@hobbs - try it out. In the absence of any `my`, `our`, `local`, and `package` declarations, both files refer to the same `$f` variable in the main symbol table
mobrule
mobrule is right about why this works this way. Everyone who claims it doesn't should try it out on a platform with a case-insensitive file system. My test platform was OS X, and I hadn't consciously thought of its deceptive case-insensitivity ("Grargh! It looks like *nix! Why does it hate me?"), but that explains why `B` is loaded when I ask for `b` to my satisfaction. On my Debian environment, the OP's code works as he expected it to in the first place.
darch
@mobrule apologies... `use` ing a file without a `package` declaration in it is so far outside of my everyday experience that my brain didn't even process it :)
hobbs
No worries, hobbs. There's lots of things in this post to make you do a double take.
mobrule