Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Package vs. plain file

by bradcathey (Prior)
on Jun 04, 2005 at 16:20 UTC ( [id://463539]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow Monasterians,

I'm discovering the benefits of reusable code. My question is this: do I have to put the code in a package or can it just be a file that ends with 1;? I have done it both ways, but the package method requires a little extra code. I have read in Programming Perl that the package method protects the namespaces, but what else? Thanks.

Main (without using package):

use Common.pm; my $returnvalue = somesub();

Common.pm:

sub somesub { ...create value... return($value); } 1;

Main (with package):

use Common.pm; my $returnvalue = Common->somesub();

Common.pm:

package Common; sub somesub { ...create value... return($value); } 1;

—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Replies are listed 'Best First'.
Re: Package vs. plain file
by crashtest (Curate) on Jun 04, 2005 at 17:29 UTC
    The beauty of Perl is you don't have to do it any which way. TIMTOWTDI, after all.

    But I think you've gotten some concepts confused. I had trouble initially with Perl's idea of packages because I was so used to Java. Java has a one-to-one relationship between a file and its namespace. The class java.lang.String has to live in a file called "String.class" in a directory hierarchy of java/lang. Perl on the other hand allows you to switch namespaces within the same file, or use a namespace that's totally unrelated to the file the code lives in.

    In practice, there usually is a correspondence between a file (like Crypt/Blowfish.pm) and the namespace it uses (Crypt::Blowfish::). But this doesn't have to be. In your example for instance, I can put somesub in a separate namespace within the same file, or load a somesub that lives in a namespace totally unrelated to the file name it is defined in:

    In a file called "TestFile.pm":
    package Foo::Bar; sub somesub{ return "somesub value from package Foo::Bar!"; } 1;
    In a file called "test.pl":
    use TestFile; package Common; sub somesub { my $value = 'somesub value from Common package!'; return $value; } package main; print "Back in main package.\n"; my $rv1 = Common->somesub(); # Defined just above in this file my $rv2 = Foo::Bar->somesub(); # Found in file TestFile.pm print "Return Value 1: $rv1\nReturn Value 2: $rv2\n";
    My point being that file names and packages are very loosely coupled in Perl. Good reading for all of this is perlmod and package.
Re: Package vs. plain file
by fishbot_v2 (Chaplain) on Jun 04, 2005 at 19:59 UTC

    You'll come across this in the recommended documentation, but I'd thought that I would mention that in your example:

    my $returnvalue = Common->somesub();

    you likely really want

    my $returnvalue = Common::somesub();

    ...assuming you want to use modules to package together functions. Common::somesub() is a fully qualified subroutine, Common->somesub() is a class method. Here's a clumsy example of (some of) the differences:

    package Foo; sub bar { print join( ',', @_ ) . "\n"; } package Baz; push @ISA => "Foo"; package main; Foo::bar('arg1'); Foo->bar('arg1'); Baz->bar('arg1'); Bar::bar('arg1'); __END__ arg1 Foo,arg1 Baz,arg1 Undefined subroutine &Bar::bar called at - line 9.

Re: Package vs. plain file
by djohnston (Monk) on Jun 04, 2005 at 19:46 UTC
    Perl doesn't force it upon you, but it's worth the extra effort to put your reusable code in their own unique name space. By doing so, your code is closer to a full fledged Perl module and is self-contained, which helps to avoid name space collisions with the subroutines and global variables of the programs which use it (hopefuly you're avoiding global variables altogether). In fact, I tend to use the same subroutine names in my modules when it makes sense, just to make their use consistent and easier for me to remember.
    package My::This; sub thing { print 'This' } package My::That; sub thing { print 'That' } package main; &My::This::thing; # prints This &My::That::thing; # prints That
    It's also just one small step from becoming object oriented...
    package My::This; sub new { bless {} } sub thing { print 'This' } package My::That; sub new { bless {} } sub thing { print 'That' } package main; my $This = My::This->new(); my $That = My::That->new(); $This->thing; # prints This $That->thing; # prints That
Re: Package vs. plain file
by Ninthwave (Chaplain) on Jun 04, 2005 at 17:05 UTC

    Get the book by merlyn :
    Learning Perl Objects, References and Modules

    It walks through different ways of reusing code and when to use modules and OO techniques

    "No matter where you go, there you are." BB
Re: Package vs. plain file
by jhourcle (Prior) on Jun 04, 2005 at 17:07 UTC

    package is used for keeping namespace seperate, but it's also used for OO code in perl, as the name of the class.. You want to take a look at package and the references at the end (especially perlmod), and perltoot

Re: Package vs. plain file
by tlm (Prior) on Jun 04, 2005 at 21:23 UTC

    As others have pointed out, the main purpose of packages is namespace management, but I wanted to point out that in your "with-package" version you are using the OO calling syntax, which is probably not what you want. I think what you want is

    use Common; my $returnvalue = Common::somesub();
    (Not use Common.pm;, btw.)

    the lowliest monk

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://463539]
Approved by Limbic~Region
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: (4)
As of 2024-04-20 04:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found