packages

D

David McDivitt

I am having difficulty understanding packages. I made a package, and
figured out how to make variables visible to modules using it without
qualifying with the package name, but exposing package subroutines the
same way is a bit confusing. I read several things. I do not understand
export syntax and how to set that up. Would someone please post an
example package having one routine called "init", and make the init
routine visible to any module using it without having to say
PACKAGENAME::init() in that module. Thanks
 
J

Jay Tilton

: I am having difficulty understanding packages. I made a package, and
: figured out how to make variables visible to modules using it without
: qualifying with the package name, but exposing package subroutines the
: same way is a bit confusing.

It shouldn't be. For purposes of poking around in the symbol table, the
only difference between a variable and a subroutine is the funny sigil
in front of the name.

If you show how you're exporting variables from one namespace to
another, you can see how the same technique can export a subroutine.
 
D

David McDivitt

Subject: Re: packages
Date: Thu, 25 Sep 2003 06:20:44 GMT


: I am having difficulty understanding packages. I made a package, and
: figured out how to make variables visible to modules using it without
: qualifying with the package name, but exposing package subroutines the
: same way is a bit confusing.

It shouldn't be. For purposes of poking around in the symbol table, the
only difference between a variable and a subroutine is the funny sigil
in front of the name.

If you show how you're exporting variables from one namespace to
another, you can see how the same technique can export a subroutine.

I have it commented out where I tried to include a function name. All but
one function was removed for brevity. Thanks

package DGM;

use warnings;
use strict;
use CGI qw:)standard);


# use vars qw($MicrosoftTimeDiff %passed problem);

use vars qw($MicrosoftTimeDiff %passed);

$MicrosoftTimeDiff = \2209161600;
%passed;
my ($fontsize, $buttonsize, $buttonprop, $tdprop);

1;

sub problem {
print '<br>',shift(),"\n",'</body></html>';
exit;
}
 
D

David McDivitt

From: David McDivitt said:
Subject: packages
Date: Thu, 25 Sep 2003 00:04:42 -0500

I am having difficulty understanding packages. I made a package, and
figured out how to make variables visible to modules using it without
qualifying with the package name, but exposing package subroutines the
same way is a bit confusing. I read several things. I do not understand
export syntax and how to set that up. Would someone please post an
example package having one routine called "init", and make the init
routine visible to any module using it without having to say
PACKAGENAME::init() in that module. Thanks

Below is how I resolved my problem. If I find my own answer I like to put my
own answer back in the forum. In the modules using this package I give two
lines:

use DGM;
my @ISA = qw(DGM);

I got confused with the export stuff and did not understand what was going
on. I had however read about @ISA when reading about classes. It seems
placing "use export" in the package does nothing more than avoid one extra
line of code in the main application, but ends up pulling in another whole
module, too. It was the "use export" which confused me, and I thought it was
a necessary thing. With what I have, two variables are made visible to the
main application without having to qualify with package name, and all
functions are visible.

package DGM; #no functions shown

use warnings;
use strict;
use CGI qw:)standard);

our $MicrosoftTimeDiff = \2209161600;
our %passed = ();
*main::MicrosoftTimeDiff = *MicrosoftTimeDiff;
*main::passed = *passed;
my ($fontsize, $buttonsize, $buttonprop, $tdprop);

1;
 
S

Steve Grazzini

David McDivitt said:
Below is how I resolved my problem. If I find my own answer I
like to put my own answer back in the forum. In the modules
using this package I give two lines:

use DGM;
my @ISA = qw(DGM);

I got confused with the export stuff and did not understand what
was going on. I had however read about @ISA when reading about
classes. It seems placing "use export" in the package does nothing
more than avoid one extra line of code in the main application,
but ends up pulling in another whole module, too. It was the
"use export" which confused me, and I thought it was a necessary
thing.

I assume you mean "use Exporter" or "use base qw(Exporter)" ?
In that case, no: it's not necessary, but it's quite a bit better
than what you're using now.
With what I have, two variables are made visible to the
main application without having to qualify with package name, and all
functions are visible.

package DGM; #no functions shown

use warnings;
use strict;
use CGI qw:)standard);

our $MicrosoftTimeDiff = \2209161600;
our %passed = ();
*main::MicrosoftTimeDiff = *MicrosoftTimeDiff;
*main::passed = *passed;

First of all, this assumes that the calling package is "main", which
might not always be the case.

It breaks the convention where the calling package can say
"use DGM qw(%passed)" to specify exactly which symbols get imported.

It doesn't export any functions. I don't know what you meant by that;
the CGI functions are only visible in the DGM package, and the OO
methods don't have anything to do with import/export.

You're aliasing the whole globs instead of just the scalar or hash
or subroutine slots. This is more destructive than it needs to be,
since you clobbered &main::passed for no good reason. And see another
recent post where somebody seems to have gotten bit by the interaction
of glob-aliasing and foreach iterators. Exporter does the safer thing
here and aliases only the specified (or requested) symbols.

And since you said that doing it this way avoids pulling in another
whole module: Exporter is ALREADY LOADED! (By CGI.pm.) You save a
function call -- and do it by making a mess of your module's interface.
 
S

Steve Grazzini

Steve Grazzini said:
And since you said that doing it this way avoids pulling in another
whole module: Exporter is ALREADY LOADED! (By CGI.pm.)

Okay, this is not actually the case. In fact, CGI says that it
doesn't use Exporter for reasons of "execution speed" -- but I
still think it's better to be slow than incorrect, and that
Exporter is not really so slow, and that constantly reinventing
Exporter will eventually lead to *more* bloat, not less.

Sigh.
 
J

Jay Tilton

: >From: David McDivitt <[email protected]>
: >
: >I am having difficulty understanding packages. I made a package, and
: >figured out how to make variables visible to modules using it without
: >qualifying with the package name, but exposing package subroutines the
: >same way is a bit confusing. I read several things. I do not understand
: >export syntax and how to set that up. Would someone please post an
: >example package having one routine called "init", and make the init
: >routine visible to any module using it without having to say
: >PACKAGENAME::init() in that module. Thanks
:
: Below is how I resolved my problem. If I find my own answer I like to put my
: own answer back in the forum.

Very nice. Not a behavior that needs excusing.

: In the modules using this package I give two
: lines:
:
: use DGM;
: my @ISA = qw(DGM);

That doesn't do what you think it does. @ISA must be a package variable
for inheritance to work.

our @ISA = qw(DGM);

But that only makes sense if DGM.pm is a class you wish to inherit from.
If it's a class, why should it be exporting symbols?

: I got confused with the export stuff and did not understand what was going
: on. I had however read about @ISA when reading about classes. It seems
: placing "use export"

"use Exporter;"

: in the package does nothing more than avoid one extra
: line of code in the main application, but ends up pulling in another whole
: module, too.

Well, that's not a very good reason not to use Exporter.pm .
The modules that get loaded are small, and if your app achieves any kind
of complexity, they're probably already being loaded by some other
module your code requires.

A good reason not to use Exporter.pm would be that it simply can't do
what you want. In this case, it's perfectly suited to the task.

Getting basic functionality from Exporter.pm is dead simple.

require Exporter;
our @ISA = 'Exporter';
our @EXPORT = qw($foo @bar %baz &qux);

: It was the "use export" which confused me, and I thought it was
: a necessary thing.

Not necessary, but it's very easy to use once its function is
understood.

: With what I have, two variables are made visible to the
: main application without having to qualify with package name, and all
: functions are visible.

Visible in main:: , yes. And if main:: is not the package where the
use() occurred, main:: gets the extra baggage instead of the package
that asked for it.

Exporter.pm , on the other hand, exports symbols to the package where
the use() occurrs. Even better, the programmer can control which
symbols get exported without altering the module at all.
 
D

David McDivitt

Yeah I looked and did not see Exporter in CGI. But I'm frustrated and am
having problems anyway. Maybe I'll use a one character package name so it
doesn't take much typing to qualify everywhere, and forget class stuff :)

The application works fine. I started on another application and wanted to
reuse some of the code. So I thought it would be a good opportunity to
understand packages and use them. I was using require statements in each of
the main modules, referencing a PL file. I decided to make a PM file
instead. Much trial and error is involved. No better way to learn things
though.
 
A

Anno Siegel

Steve Grazzini said:
Okay, this is not actually the case. In fact, CGI says that it
doesn't use Exporter for reasons of "execution speed" -- but I
still think it's better to be slow than incorrect, and that
Exporter is not really so slow, and that constantly reinventing
Exporter will eventually lead to *more* bloat, not less.

In fact, Exporter bends over backwards to load only minimal stubs
at compile time. Only when Exporter->import is actually called
the heavy stuff is pulled in (only once, of course). Carp is
constructed similarly.

Anno
 
D

David McDivitt

From: (e-mail address removed) (Jay Tilton)
Subject: Re: packages
Date: Thu, 25 Sep 2003 22:06:31 GMT

Visible in main:: , yes. And if main:: is not the package where the
use() occurred, main:: gets the extra baggage instead of the package
that asked for it.

Exporter.pm , on the other hand, exports symbols to the package where
the use() occurrs. Even better, the programmer can control which
symbols get exported without altering the module at all.

When I reference one package from another package, variables in the
innermost package I want to be global are no longer visible to the main
module. If I reference the package declaring the global variables directly,
they are visible. My application has seven main modules, each making a
different browser page. On some I do not need the functionality of both
packages, on others I do. It seemed best to reference one package from the
other package making them nested. For those modules needing both packages I
reference the outer one. For others I reference the inner one. With exporter
this does not work. Variables placed in the export list, when used in the
outer module, generate the error saying they must be qualified by package
name. Also, some routines say too many arguments are being used.
 
B

Bart Lateur

Steve said:
Okay, this is not actually the case. In fact, CGI says that it
doesn't use Exporter for reasons of "execution speed" -- but I
still think it's better to be slow than incorrect, and that
Exporter is not really so slow, and that constantly reinventing
Exporter will eventually lead to *more* bloat, not less.

CGI.pm is accusing another, much smaller module than itself of bloat?!?
*boggle* (10k for Exporter vs. >200k for CGI.pm)
 
D

David H. Adler

CGI.pm is accusing another, much smaller module than itself of bloat?!?
*boggle* (10k for Exporter vs. >200k for CGI.pm)

I may be wrong as I'm working from memory here, but...

The point is that CGI.pm uses its own exporting system so as to minimize
what's actually exported - i.e. only what's actually used by your
program gets compiled. I *believe* that Exporter wasn't as good for
this in this particular case.

Or I may be hallucinating. *shrug*

dha
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,813
Members
47,357
Latest member
sitele8746

Latest Threads

Top