|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
[Perl 5.8.0] package A ... use B; ... print $B::var; <<< error ... Is there some trick to "use"ing one package from within another package? Variables defined within B don't seem to be accessible within A, although they are accessible from the main namespace in the file that "use"s A.
|
|
|
|
Joined: Jan 2000
Posts: 5,073
Admin Emeritus
|
Admin Emeritus
Joined: Jan 2000
Posts: 5,073 |
Depends on how $B::var was declared... package B; use strict; my $nope = 0; our $maybe = 1; use vars qw($probably); $probably = 1;
package A; use strict; print $B::probably; print $B::maybe; print $B::nope; This ends up printing "11"... no zero. No error either. Thus: Stuff that's really supposed to be shared by package B will be shared. %) Can you give a little more detail on what you're trying to do, and how it's failing to work?
UBB.classic: Love it or hate it, it was mine.
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
Thanks I was declaring the variable using "my" within the package, which I suppose hid it from being referenced outside the package. I changed it to "our", and it works now. I was never fully clear on exactly what "our" does, although I've read the manual's description of it many times. Here's my application: I have a package MyDefs.pm that I'm using to define config variables that other packages will reference. Here's part of it: package MyDefs;
use strict; use warnings; use re 'taint'; # suppress untainting by regexes
# paths our $home_dir = 'c:'; our $dest_base_dir = "$home_dir/backup"; our $lock_filename = $dest_base_dir/backup_lock"; our $list_filename = 'backup.lst'; Then in other packages, I reference the variables like this: use MyDefs(); open(my $fh_lock, '>', $MyDefs::lock_filename) or die "open: $!"; Does that seem like reasonable coding practice? I had forgotten how complicated Perl is, compared to PHP. 
|
|
|
|
Joined: Jan 2000
Posts: 5,073
Admin Emeritus
|
Admin Emeritus
Joined: Jan 2000
Posts: 5,073 |
Well, personally I'd just use a hash... if a module was needed, the hash would just get exported via Exporter. Perl is only as complicated as you want to make it. my creates a var usable within the current scope. If a var is my'd from inside a file, but not inside a sub, then it's available from everything inside that file. The var can't be accessed from outside of that file, in that case. our is the same, but it allows outside access in many cases. However, I avoid our completely, as it requires 5.6+ and tends to do unintended/spooky things. All of my vars that need to be globals are done so via use vars.
UBB.classic: Love it or hate it, it was mine.
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
Well... I prefer objects and object tables as data fields shortly: our() creates global class variables while my() creates private variables. And a Quote from Damian Conway' s OOPerl Book: quote:
It may help to think of the two types of variables-package and lexical-in the way the Ancient Greeks thought of their gods. Ancient Greece had big general-purpose gods like Uranus, Zeus, Aphrodite, and Atropos, who existed for all time and could appear anywhere without warning. These are analogous to package variables*.
Then there were the small, specialized gods like the spirits of trees, or doorsteps, or hearths. These gods were restricted to a well-defined domain-a tree, a building, the fireplace -and existed only for a specific period-the life of the tree, the occupation of the building, the duration of a fire. These are like lexical variables: localized and transient.
*The big Greek gods even came in "packages": $Titans::Uranus, $Olympians::Zeus, $Olympians::Aphrodite, $Fates::Atropos.
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
Is "use vars" safe to use? The current Perl documentation says that's obsolete, and "our" is supposed to be used instead. My interpretion of "our" is that it's roughly analogous to "extern" in C/C++. I.e., it doesn't allocate space for a variable, but rather brings a variable defined elsewhere into the current scope. But I'm not sure if that's really accurate. To refresh my memory, I dug out an old Perl script I wrote a couple of years ago to see how I handled this situation. Here's an extract that illustrates the method. Some of this I had to figure out by trial and error, and may not be the best way of doing it. fsConfig.pm - configuration module - defines class fsConfig package fsConfig;
use strict; use re 'taint';
# constants use constant MAX_ID => 999_999; # warning - don't change this use constant FTP_TIMEOUT => 15; # seconds use constant MAX_SEARCH_RESULTS => 100; # max number of items returned by search
# class constructor sub load { my $invocant = shift;
my $self = { ... 'submissions_mode' => 'restricted', ... };
my $class = ref($invocant) || $invocant; return bless($self, $class); }
# accessor methods
...
sub submissions_mode { my $self = shift; return $self->{'submissions_mode'}; }
...
1; main.cgi - example module that accesses configuration parameters #!/usr/bin/perl -wT
use strict; use re 'taint'; # suppress untainting by regexes
use fsConfig();
# instantiate configuration object and store it in a global variable $::Config = fsConfig::->load() or die 'Failed to load configuration data';
# suppress warning 'name used only once' (?) our $Config;
...
# example of accessing configuration constant: print "The FTP-timeout parameter is " . $Config->FTP_TIMEOUT . "n";
# example of accessing configuration variable: print "The submissions-mode is " . $Config->submissions_mode() . "n";
... Critique is welcome 
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
you can use anything until you see "deprecated" also if you dont care about archaic perl distributions you can use it...
|
|
|
|
Joined: Jan 2000
Posts: 5,073
Admin Emeritus
|
Admin Emeritus
Joined: Jan 2000
Posts: 5,073 |
Wow... you're playing with the :: namespace directly. That takes guts...
UBB.classic: Love it or hate it, it was mine.
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
uhm... it's not different than $Config = foo if you're under the main package...
But, $::Config & then our $Config is not meaningfull... it must be our $Config = foo...
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
My understanding is that $::Config is equivalent to $main::Config, and is necessary to make the variable global, so that it's available to any other modules that are "use"-d by the main.cgi module. The above code works. That's what I meant by having to resort to trial and error. I remember having to do some experimention to come up with that. But I'll play around with it some more.
|
|
|
|
Joined: Jan 2000
Posts: 5,073
Admin Emeritus
|
Admin Emeritus
Joined: Jan 2000
Posts: 5,073 |
$::Config exists in the core namespace... only things that are generally considered to be magic live there, as they get inherited into everything.
$main::Config is a completely different namespace...
UBB.classic: Love it or hate it, it was mine.
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
dont think so. :: is the package main. you can also use it like main::. It has nothing to do with CORE http://www.perldoc.com/perl5.8.0/pod/func/package.html quote:
If the package name is null, the main package as assumed. That is, $::sail is equivalent to $main::sail (as well as to $main'sail, still seen in older code).
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
Hmmmm .... "If the package name is null, the main package is assumed. That is, $::sail is equivalent to $main::sail." Programming Perl, 3rd Edition, p. 291. Also stated at http://perldoc.com/perl5.8.0/pod/perlmod.html#Packages Is that incorrect? ---- Edit : Burak posted the same thing while I was in the process of posting this. I would delete this post, but don't have access to do so. 
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
quote: Originally posted by Burak: But, $::Config & then our $Config is not meaningfull... it must be our $Config = foo... The only reason I added "our $Config" was to suppress warning messages like these that occur for references to $Config: Variable "$Config" is not imported at main.plx line 15. Global symbol "$Config" requires explicit package name at main.plx line 15.Do you mean that "our $Config" should be replaced with "our $Config = $::Config" ? That works too, but it doesn't appear to matter which one of those I use, the code executes the same way. But like I said, I don't fully understand "our". P.S. I just checked, and other modules that are "use"-d by main.cgi have the following, so I see what you're saying:
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
no. I'm saying this:
our $Config = fsConfig->load() or die '...';
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
Ok, but ...
$Config is intended to be a global variable, initialized in main.cgi, and accessible by other modules that are "use"-d by main.cgi. How would the other modules access $Config?
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
as $::Config or $main::Config if you have to call it inside a module. I've tested your code like this: #!/usr/bin/perl -w use strict; use CGI (); $::Config = CGI->new; our $Config;
require "req.pl"; require Req;
package Test;
printf "Test: %s-%sn", ref($Config),ref($::Config); req.pl printf "req: %s-%sn", ref($Config),ref($::Config);
1; Req.pm: package Req; printf "Req: %s-%sn", ref($Config),ref($::Config);
1; output: quote:
req: CGI-CGI Req: -CGI Test: CGI-CGI
inside a file you can use it in all packages, but if you use() or require() a module you cant... It also works on simple code files...
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
So you're defining the global as $::Config = CGI->new; our $Config; rather than as . I can see that the former would work. It was the attempt to use the latter that I didn't understand.
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
no. I'm testing your sample code to see the behaviour  As you can see your usage fails when you call a module outside... I mean you have to use it like $::Config to be sure...
|
|
|
|
Joined: May 2000
Posts: 1,356
Addict
|
Addict
Joined: May 2000
Posts: 1,356 |
sorry, I wasnt clear about the code I wrote...
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
Burak & Charles: Thanks for your help. I think I've re-familiarized myself with Perl adequately for the time being. For what I'm doing now, I didn't really need global "variables", but only constants, so I've set up the config module like this: package MyDefs;
... use constant DEST_BASE_DIR => 'c:/backup'; use constant LOCK_FILENAME => "@{[DEST_BASE_DIR]}/backup_lock"; use constant LIST_FILENAME => 'backup.lst'; use constant CMD_FILENAME => 'backup.cmd'; ...
1; Then in other modules, I can reference the constants like this: ... use MyDefs(); ... open(my $fh_lock, '>', MyDefs::LOCK_FILENAME); ... my $cmd = "$dest_dir/@{[MyDefs::CMD_FILENAME]}"; ...
|
|
|
|
Joined: Jan 2000
Posts: 5,073
Admin Emeritus
|
Admin Emeritus
Joined: Jan 2000
Posts: 5,073 |
That works, though I still think you should be using Exporter... that way you could use MyDefs and get LOCK_FILENAME and the rest just plain imported.
UBB.classic: Love it or hate it, it was mine.
|
|
|
|
Joined: Aug 2000
Posts: 335
Member
|
Member
Joined: Aug 2000
Posts: 335 |
If you mean so that I wouldn't have to qualify the constants (LOCK_FILENAME instead of MyDefs::LOCK_FILENAME), I prefer specifying the package name in the references. I think that it reduces the likelihood of name collisions. 
|
|
|
Donate to UBBDev today to help aid in Operational, Server and Script Maintenance, and Development costs.
Please also see our parent organization VNC Web Services if you're in the need of a new UBB.threads Install or Upgrade, Site/Server Migrations, or Security and Coding Services.
|
|
Posts: 449
Joined: February 2008
|
|
Forums63
Topics37,575
Posts293,930
Members13,823
|
Most Online6,139 Sep 21st, 2024
|
|
Currently Online
Topics Created
Posts Made
Users Online
Birthdays
|
|
|
|