Ask a Question related to PERL Beginners, Design and Development.
-
mcdavis941@netscape.net #1
How to import symbols and semantics from one namespace into another
Hi, this question has to do with importing names from one package into another. In my case, both packages reside in the same file, and I simply want to import all the package-global symbols from the one package into the other. Can anyone say how to do this? Here's a bunch of tries that didn't work.
test_import.pl
--------------
package main;
print "Hi world\n";
$x = dosomething();
print "did something and got $x\n";
exit;
package SomePackage;
sub dosomething{
return time;
}
Obviously this isn't going to work because symbol dosomething is not defined in package main. (In this trivial example I could just say $x = SomePackage::dosomething(), but I have dozens of functions and I would prefer to simply import them into the namespace of main. Also, apart from this specific instance, I want to understand what I can do in general.)
The documentation for perlmod implies there's an import method that's part of exporter, so I tried something like this.
test_import.pl
--------------
package main;
SomePackage::import(qw(dosomething));
print "Hi world\n";
$x = dosomething();
print "did something and got $x\n";
exit;
package SomePackage;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(dosomething);
sub dosomething{
return time;
}
outcome:
--------
Undefined subroutine &SomePackage::import called at test_import.pl line 2.
Another variation:
test_import.pl
--------------
package main;
import SomePackage (qw(dosomething));
print "Hi world\n";
$x = dosomething();
print "did something and got $x\n";
exit;
package SomePackage;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(dosomething);
sub dosomething{
return time;
}
outcome:
--------
(Not what I expected; why didn't it tell me main::import is undefined?)
Hi world
Undefined subroutine &main::dosomething called at test_import.pl line 5.
Another variation:
test_import.pl
--------------
package main;
use SomePackage;
print "Hi world\n";
$x = dosomething();
print "did something and got $x\n";
exit;
package SomePackage;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(dosomething);
sub dosomething{
return time;
}
outcome:
--------
This obviously won't work because 'use' expects a module name, not a package name. Same issue with 'require'.
Can't locate SomePackage.pm in @INC (@INC contains: d:/app/xampp/perl/lib D:/app/xampp/perl/lib D:/app/xampp/perl/site/lib .) at test_import.pl line 3.
BEGIN failed--compilation aborted at test_import.pl line 3.
That's it. Any ideas?
__________________________________________________ ________________
New! Unlimited Netscape Internet Service.
Only $9.95 a month -- Sign up today at [url]http://isp.netscape.com/register[/url]
Act now to get a personalized email address!
Netscape. Just the Net You Need.
mcdavis941@netscape.net Guest
-
IPTables namespace - how to commandeer namespace
I have a Perl module, IPTables::IPv4, that I've been developing for some time, and that is in the CPAN repository. I've expanded the module to... -
flock() semantics?
Hi all, I'm writing an app which uses a flat file to store a *short* list of simple key/value pairs. However having read the flock() man page,... -
Formal Language Semantics
Does anyone know where I can get the formal language semantics for Ruby (assuming such a thing exists)? Thank you, Christopher Aycock Oxford... -
module_function semantics
Hi all! I'm trying to understand some code in the stdlib (drb/drb.rb, to be particular). Is there any difference between: module Foo ... -
Wiggins D Anconia #2
Re: How to import symbols and semantics from one namespace into another
another. In my case, both packages reside in the same file, and I> Hi, this question has to do with importing names from one package into
simply want to import all the package-global symbols from the one
package into the other. Can anyone say how to do this? Here's a bunch
of tries that didn't work.This doesn't make a lot of sense to me, if you are going to export them>
all why bother? The big reason for the separate packages is to avoid
namespace pollution, which if you export everything you have just
counteracted. At least put them in a separate file, and use it? But to
each their own....
defined in package main. (In this trivial example I could just say $x => test_import.pl
> --------------
> package main;
>
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> sub dosomething{
> return time;
> }
>
> Obviously this isn't going to work because symbol dosomething is not
SomePackage::dosomething(), but I have dozens of functions and I would
prefer to simply import them into the namespace of main. Also, apart
from this specific instance, I want to understand what I can do in general.)part of exporter, so I tried something like this.>
> The documentation for perlmod implies there's an import method that'sClose, but import is a method not a plain function, so you need to call>
> test_import.pl
> --------------
> package main;
> SomePackage::import(qw(dosomething));
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> use Exporter;
> @ISA = qw(Exporter);
> @EXPORT = qw(dosomething);
> sub dosomething{
> return time;
> }
>
it on the class,
SomePackage->import();
Because the syntax you causes Perl to realize it is supposed to be a> outcome:
> --------
> Undefined subroutine &SomePackage::import called at test_import.pl line 2.
>
> Another variation:
>
> test_import.pl
> --------------
> package main;
> import SomePackage (qw(dosomething));
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> use Exporter;
> @ISA = qw(Exporter);
> @EXPORT = qw(dosomething);
> sub dosomething{
> return time;
> }
>
> outcome:
> --------
> (Not what I expected; why didn't it tell me main::import is undefined?)
> Hi world
> Undefined subroutine &main::dosomething called at test_import.pl line 5.
>
method, now the problem is that SomePackage hasn't done any exporting
yet, because it hasn't been seen yet.
package name. Same issue with 'require'.> Another variation:
>
> test_import.pl
> --------------
> package main;
> use SomePackage;
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> use Exporter;
> @ISA = qw(Exporter);
> @EXPORT = qw(dosomething);
> sub dosomething{
> return time;
> }
>
> outcome:
> --------
> This obviously won't work because 'use' expects a module name, not ad:/app/xampp/perl/lib D:/app/xampp/perl/lib D:/app/xampp/perl/site/lib>
> Can't locate SomePackage.pm in @INC (@INC contains:
..) at test_import.pl line 3.Which sort of tells you that you ought to be moving in that direction,> BEGIN failed--compilation aborted at test_import.pl line 3.
>
but that's up to you...
Go with your method call syntax above (or the one provided below) and> That's it. Any ideas?
>
either move the definition of SomePackage to the top of the script, or
wrap the definition in a BEGIN {} compile time block.... so,
#!/usr/local/bin/perl
use strict; # Always!
use warnings; # usually!
Some::Package->import();
print "Hi world\n";
my $x = dosomething();
print "did something and got $x\n";
exit;
BEGIN {
package Some::Package;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(dosomething);
sub dosomething {
return time;
}
}
HTH,
[url]http://danconia.org[/url]
Wiggins D Anconia Guest
-
Paul Johnson #3
Re: How to import symbols and semantics from one namespace into another
On Wed, Jan 28, 2004 at 01:32:14PM -0500, [email]mcdavis941@netscape.net[/email] wrote:
Thanks for showing what you've tried. First couple snipped.> Hi, this question has to do with importing names from one package into
> another. In my case, both packages reside in the same file, and I
> simply want to import all the package-global symbols from the one
> package into the other. Can anyone say how to do this? Here's a
> bunch of tries that didn't work.
This one will work if you swap the order of the two packages in the> Another variation:
>
> test_import.pl
> --------------
> package main;
> import SomePackage (qw(dosomething));
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> use Exporter;
> @ISA = qw(Exporter);
> @EXPORT = qw(dosomething);
> sub dosomething{
> return time;
> }
>
> outcome:
> --------
> (Not what I expected; why didn't it tell me main::import is undefined?)
> Hi world
> Undefined subroutine &main::dosomething called at test_import.pl line 5.
file. Last example snipped.
This might be simpler:> That's it. Any ideas?
package main;
*dosomething = \&SomePackage::dosomething;
print "Hi world\n";
$x = dosomething();
print "did something and got $x\n";
exit;
package SomePackage;
sub dosomething{
return time;
}
--
Paul Johnson - [email]paul@pjcj.net[/email]
[url]http://www.pjcj.net[/url]
Paul Johnson Guest
-
Drieux #4
Re: How to import symbols and semantics from one namespace into another
On Jan 28, 2004, at 10:32 AM, [email]mcdavis941@netscape.net[/email] wrote:
[..]> Hi, this question has to do with importing names from one package into
> another.[..]> outcome:
> --------
> This obviously won't work because 'use' expects a module name, not a
> package name. Same issue with 'require'.
>
> Can't locate SomePackage.pm in @INC (@INC contains:
> d:/app/xampp/perl/lib D:/app/xampp/perl/lib D:/app/xampp/perl/site/lib
> .) at test_import.pl line 3.
> BEGIN failed--compilation aborted at test_import.pl line 3.
>
> That's it. Any ideas?
first off my complements on the most excellent work so far.
Well there are a couple of basic solutions here.
a. decide the perl modules should be in an external file
so that one can simply use the
use SomePackage;
approach that simply requires that the module be external.
b. decide that the 'package' approach needs to be in the
perl script itself and adopt the oo-ish type of approach
so that one winds up accessing the methods by indirection
through say a blessed reference, rather than by importation
into the package main.
for more details you might want to
a. pick up the perl modules and reference book.
<http://www.oreilly.com/catalog/lrnperlorm/>
b. see my stock rant
<http://www.wetware.com/drieux/CS/lang/Perl/PM/quick_pm.html>
Since basically I go with the idea that perl modules really
belong as perl modules and then one has a simpler overall
management problem. First because then multiple scripts
can use the package, then as you so elegantly have demonstrated,
because it winds up becomeing so much simpler than trying to
work around managing the namespace issues on one's own.
ciao
drieux
---
Drieux Guest
-
Tassilo Von Parseval #5
Re: How to import symbols and semantics from one namespace into another
On Wed, Jan 28, 2004 at 01:32:14PM -0500 [email]mcdavis941@netscape.net[/email] wrote:
import() is a method and not a function. When you call it as a function> Hi, this question has to do with importing names from one package into
> another. In my case, both packages reside in the same file, and I
> simply want to import all the package-global symbols from the one
> package into the other. Can anyone say how to do this? Here's a
> bunch of tries that didn't work.
>
> test_import.pl
> --------------
> package main;
>
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> sub dosomething{
> return time;
> }
>
> Obviously this isn't going to work because symbol dosomething is not
> defined in package main. (In this trivial example I could just say $x
> = SomePackage::dosomething(), but I have dozens of functions and I
> would prefer to simply import them into the namespace of main. Also,
> apart from this specific instance, I want to understand what I can do
> in general.)
>
> The documentation for perlmod implies there's an import method that's
> part of exporter, so I tried something like this.
>
> test_import.pl
> --------------
> package main;
> SomePackage::import(qw(dosomething));
it no longer obeyes inheritance and thus cannot be found since
SomePackage inherits import() from Exporter.
Because here you called it as a method. This is indirect method> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> use Exporter;
> @ISA = qw(Exporter);
> @EXPORT = qw(dosomething);
> sub dosomething{
> return time;
> }
>
> outcome:
> --------
> Undefined subroutine &SomePackage::import called at test_import.pl line 2.
>
> Another variation:
>
> test_import.pl
> --------------
> package main;
> import SomePackage (qw(dosomething));
> print "Hi world\n";
> $x = dosomething();
> print "did something and got $x\n";
> exit;
>
> package SomePackage;
> use Exporter;
> @ISA = qw(Exporter);
> @EXPORT = qw(dosomething);
> sub dosomething{
> return time;
> }
>
> outcome:
> --------
> (Not what I expected; why didn't it tell me main::import is undefined?)
invocation:
import SomePackage qw(bla);
is the same as
SomePackage->import(qw(bla));
Here perl was indeed able to call import(). However, the reason why it
still doesn't work as you expect is the order of execution. If you do
package SomePackage;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(dosomething);
sub dosomething{
return time;
}
package main;
SomePackage->import( qw/dosomething/ );
print dosomething();
things will work. This has to do with the fact that @EXPORT is still
empty when you do the import() and when you have package main before the
exporting package. That is because assignment happens at runtime.
In case you wonder why you got no error with
package main;
SomePackage->import(...);
package SomePackage;
use Exporter;
@ISA = qw(Exporter);
even though @ISA was still empty by the time you called
SomePackage->import, this is because 'import' and 'unimport' are two
special cases. They can always be called as method even when they do not
exist nor are inherited. So in fact you can also do:
package main;
main->import( qw/bla/ );
__END__
and wont get any error.
Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
Tassilo Von Parseval Guest
-
Jeff 'Japhy' Pinyan #6
Re: How to import symbols and semantics from one namespace into another
On Jan 28, [email]mcdavis941@netscape.net[/email] said:
The fact that they're in the same file is why your test cases all fail.>Hi, this question has to do with importing names from one package into
>another. In my case, both packages reside in the same file, and I simply
>want to import all the package-global symbols from the one package into
>the other. Can anyone say how to do this? Here's a bunch of tries that
>didn't work.
Right.>$x = dosomething();
>exit;
>
>package SomePackage;
>sub dosomething{
>return time;
>}
>
>Obviously this isn't going to work because symbol dosomething is not
>defined in package main. (In this trivial example I could just say $x =
>SomePackage::dosomething(), but I have dozens of functions and I would
>prefer to simply import them into the namespace of main. Also, apart
>from this specific instance, I want to understand what I can do in
>general.)
Right. The 'import' method is a part of Exporter.pm, NOT of SomePackage.>The documentation for perlmod implies there's an import method that's
>part of exporter, so I tried something like this.
Thus, calling SomePackage::import() isn't going to work, since SomePackage
doesn't HAVE an 'import' function.
SomePackage->import('dosomething');
would have worked. It's the same as
import SomePackage 'dosomething';
They're method-calling syntaces, not function calls.
>import SomePackage (qw(dosomething));
>$x = dosomething();
>exit;
>
>package SomePackage;
>use Exporter;
>@ISA = qw(Exporter);
>@EXPORT = qw(dosomething);
>sub dosomething{
>return time;
>}This is because you run into a problem caused by the the package being in>(Not what I expected; why didn't it tell me main::import is undefined?)
>Undefined subroutine &main::dosomething called at test_import.pl line 5.
the same file as your program. Some things in Perl are done at
compile-time, and others are done at run-time. Functions are parsed at
compile-time, which is why this code doesn't die because it can't find the
'foo' function:
foo();
sub foo { print 100 }
If subroutine definitions weren't parsed ahead of time, Perl wouldn't know
you'd made a 'foo' function.
In your code, simplified as follows, the problem is thus: Perl doesn't
know to use Exporter's 'import' method, and so it uses SomePackage's
'import' method. However, as the documentation states, if a package
doesn't HAVE an 'import' method, it silently fails (that is, no warning
message is given, and no error is thrown).
SomePackage->import('foo');
foo();
package SomePackage;
require Exporter;
@ISA = 'Exporter';
@EXPORT = 'foo';
sub foo { print "foo!\n" }
You see, @ISA and @EXPORT aren't defined until Perl reaches them when
EXECUTING your program. And since the first thing Perl executes is the
'import' call, those arrays are defined too late to help.
One way to fix this is with a BEGIN block:
SomePackage->import('foo');
foo();
BEGIN {
package SomePackage;
require Exporter;
@ISA = 'Exporter';
@EXPORT = 'foo';
sub foo { print "foo!\n" }
}
The stuff in the BEGIN block is executed at compile-time. Therefore, when
Perl executes SomePackage->import('foo'), it will know to look at
Exporter's 'import' method, and things will work properly.
--
Jeff "japhy" Pinyan [email]japhy@pobox.com[/email] [url]http://www.pobox.com/~japhy/[/url]
RPI Acacia brother #734 [url]http://www.perlmonks.org/[/url] [url]http://www.cpan.org/[/url]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.
[ I'm looking for programming work. If you like my work, let me know. ]
Jeff 'Japhy' Pinyan Guest
-
mcdavis941@netscape.net #7
Re: How to import symbols and semantics from one namespace into another
"Wiggins d Anconia" <wiggins@danconia.org> wrote:
<snip old posts>>
>>another. In my case, both packages reside in the same file, and I>> Hi, this question has to do with importing names from one package into
>simply want to import all the package-global symbols from the one
>package into the other. Can anyone say how to do this? Here's a bunch
>of tries that didn't work.>>>
>This doesn't make a lot of sense to me, if you are going to export them
>all why bother? The big reason for the separate packages is to avoid
>namespace pollution, which if you export everything you have just
>counteracted. At least put them in a separate file, and use it? But to
>each their own....
>
Wiggins d Anconia,
Thanks for your usual helpful answers, which do so much to make this list such a treasure trove for beginners.
To answer your valid questions about "why would you want to do that":
my circumstance is that I have a 10,000 line standalone command-line Perl program which I am refactoring into working as both a web app (Apache+Mod_perl+MySQL) and a command-line app. I'm not yet clear on what either the file or object architecture will be, which is why I'm not carving pieces out into separate files quite yet. All of the code written so far is pretty tightly coupled, again making it nontrivial to partition. It also has some long CPU-bound computation sequences, and I'm reluctant to make changes which would add overhead.
Long story short, I'm casting about for solutions and trying to find out what all my options are. Even if not applicable to this particular case, it seems reasonable that some day you're going to want to import all symbols and semantics from one namespace into another (which doesn't have to be main:: ... it could be some other package). And it's kind of an interesting question just from an academic perspective. TMTOWTDI with Perl.
I also find that it's really convenient, for now, to have all my source in one file (at least until I'm sure of the new architecture), for the same reason that someone on the list has advocated merging all the perl docs into a single file: for supereasy search and, in my case, replace. Also, as I transition into a packaged system of namespaces, I have a lot of code that expects a lot of names to be omnipresent (about 250 total subs, maybe half as object methods and half plain old subroutines); again it might be convenient to be able to put names in packages but still have them omnipresent until I'm clear how it all fits together.
But you're right, in the end I'll probably end up with packages in their own files, included with 'use' just like most normal people would do. :)
Thanks again!
__________________________________________________ ________________
New! Unlimited Netscape Internet Service.
Only $9.95 a month -- Sign up today at [url]http://isp.netscape.com/register[/url]
Act now to get a personalized email address!
Netscape. Just the Net You Need.
mcdavis941@netscape.net Guest
-
Drieux #8
Re: How to import symbols and semantics from one namespace into another
On Jan 28, 2004, at 11:24 PM, [email]mcdavis941@netscape.net[/email] wrote:
[..]ouch. Given this context it makes some reasonable sense> my circumstance is that I have a 10,000 line standalone command-line
> Perl program which I am refactoring into working as both a web app
> (Apache+Mod_perl+MySQL) and a command-line app. I'm not yet clear on
> what either the file or object architecture will be, which is why I'm
> not carving pieces out into separate files quite yet. All of the
> code written so far is pretty tightly coupled, again making it
> nontrivial to partition. It also has some long CPU-bound computation
> sequences, and I'm reluctant to make changes which would add overhead.
why you were trying to solve it all in one file. But you
may need to rethink your strategy a bit here, and work
on the slow and steady decoupling of the code so that
you wind up with two different code lines and their
supporting common collection of perl modules.
foo_cli - the classical command line code
foo_web - the web based app
both of which use the Foo::Monkey suite of modules.
This way you can work out what will really be required to
be added to the web app itself...
[..][..]> I also find that it's really convenient, for now, to have all my
> source in one file (at least until I'm sure of the new architecture),
> for the same reason that someone on the list has advocated merging all
> the perl docs into a single file: for supereasy search and, in my
> case, replace. Also, as I transition into a packaged system of
> namespaces, I have a lot of code that expects a lot of names to be
> omnipresent (about 250 total subs, maybe half as object methods and
> half plain old subroutines); again it might be convenient to be able
> to put names in packages but still have them omnipresent until I'm
> clear how it all fits together.
with 250 subs you will want to sort out which of them
have clean API's and as such can be easily pulled out as is.
By clean, I mean they are not expecting anything to have
water falled into them, nor are they doing the side effect
of setting things "globally" that were not passed into them.
I can appreciate the idea that it is easier to hunt them down
in one file in one editor - but you might want to also look
at the advantage of having more than one file open in more
than one editor...
But as japhy has already noted, if you want to put it all into
one file you can use the BEGIN block and then start sorting
out your package spaces:
SomePackage->import('foo');
foo();
FOO::Bar->foo("bed time again");
BEGIN {
package SomePackage;
require Exporter;
our @ISA = 'Exporter';
our @EXPORT = 'foo';
sub foo { print "foo!\n" }
package FOO::Bar;
sub foo { my ($me,$arg) = @_; print "have arg: $arg\n"; }
}
ciao
drieux
---
Drieux Guest



Reply With Quote

