Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: difference between packages and module

by tlm (Prior)
on Jun 21, 2005 at 12:51 UTC ( [id://468649]=note: print w/replies, xml ) Need Help??


in reply to difference between packages and module

Here are a few small examples, roughly ordered from most to least typical.

1 package (aka namespace) in 1 module
# File: Foo.pm 1; # keep require happy package Foo; sub hello { print "Hello from Foo!\n"; } __END__

# File: foo.pl require Foo; sub hello { print "Hello from main!\n"; } hello(); # prints "Hello from main!\n"; main::hello(); # prints "Hello from main!\n"; ::hello(); # prints "Hello from main!\n"; Foo::hello(); # prints "Hello from Foo!\n"; __END__

Actually, in this example there are two namespaces (Foo and main), but its principal point is to illustrate the case of one package (Foo) residing in one module (Foo.pm). (Actually, as ysth already alluded to, there is some ambiguity in the common usage of the word "module"; e.g. in some contexts one would talk about the "CGI module", referring to the distribution (which may contain several files); in other contexts one may speak of the "CGI.pm module", referring to a specific file in the distribution.)

As a bonus, this example also illustrates that

  1. when a package is not specified, as happens in foo.pl, the default package is main; that's why, in foo.pl, hello and main::hello refer to the same subroutine.
  2. a leading :: (as in ::hello()) is synonymous with main::.

Multiple packages (namespaces) in 1 module
# File: Foo.pm 1; # keep require happy package Foo; sub hello { print "Hello from Foo!\n"; } package Foo_Helper; sub hello { print "Hello from Foo_Helper!\n"; } __END__

# File: foo.pl require Foo; sub hello { print "Hello from main!\n"; } hello(); # prints "Hello from main!\n"; Foo::hello(); # prints "Hello from Foo!\n"; Foo_Helper::hello(); # prints "Hello from Foo_Helper!\n"; __END__

Notice that in foo.pl we don't have the line

require Foo_Helper;
In fact, perl would complain bitterly if we did:
Can't locate Foo_Helper.pm in @INC (@INC contains: /usr/local/lib/perl +/5.8.4 /usr/local/share/perl/5.8.4 /usr/lib/perl5 /usr/share/perl5 /u +sr/local/lib/site_perl .) at foo.pl line 2.
That's because require is ultimately looking for files. I.e., to a first approximation at least, as far as require is concerned, a module is a file. In fact, once require finds the file that it's looking for, it doesn't care whether the namespace(s) declared in the file correspond to the name of the module. For example:
# File: Foo.pm 1; # keep require happy package Foo_Helper; sub hello { print "Hello from Foo_Helper!\n"; } package Bar; sub hello { print "Hello from Bar!\n"; } # Look, Ma! No Foo! __END__

# File: foo.pl require Foo; sub hello { print "Hello from main!\n"; } hello(); # prints "Hello from main!\n"; Bar::hello(); # prints "Hello from Bar!\n"; Foo_Helper::hello(); # prints "Hello from Foo_Helper!\n"; __END__
Notice that in this case the module require'd (i.e. loaded) by foo.pl is Foo, and require looks for it in a file called Foo.pm in some directory mentioned in @INC. It doesn't matter that no package named Foo is mentioned in Foo.pm.

1 packages (namespaces) in several modules
# File: Foo.pm 1; # keep require happy package Foo; sub hello { print "Hello from Foo!\n"; } __END__

# File: More_Foo.pm 1; # keep require happy package Foo; sub hello_2 { print "Still in Foo!\n"; } __END__

# File: foo.pl require Foo; require More_Foo; sub hello { print "Hello from main!\n"; } hello(); # prints "Hello from main!\n"; Foo::hello(); # prints "Hello from Foo!\n"; Foo::hello_2(); # prints "Still in Foo!\n"; __END__
Notice that in foo.pl we now have two require's:
require Foo; require More_Foo;
In other words, the fact that require is loading stuff in package Foo when it gets Foo.pm does not, by itself, bring in any other Foo code from other modules. If we had omitted the second require, then perl would fail with the error:
Undefined subroutine &Foo::hello_2 called at foo.pl line 10.
On the other hand, a small change in Foo.pm would render unnecessary the second require in foo.pl (as long as one has the first one):
# File: Foo.pm require More_Foo; 1; # keep require happy package Foo; sub hello { print "Hello from Foo!\n"; }

Now Foo.pm loads More_Foo.pm, which makes a single require Foo enough in foo.pl.

the lowliest monk

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2024-04-19 23:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found