Previous Thread
Next Thread
Print Thread
Rate Thread
Joined: Aug 2000
Posts: 335
Member
Member
Offline
Joined: Aug 2000
Posts: 335
[Perl 5.8.0]

Code
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.

Sponsored Links
Joined: Jan 2000
Posts: 5,073
Admin Emeritus
Admin Emeritus
Joined: Jan 2000
Posts: 5,073
Depends on how $B::var was declared...

Code
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
Offline
Joined: Aug 2000
Posts: 335
Thanks smile

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:

Code
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:

Code
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. frown

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. wink

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 smile

shortly: our() creates global class variables while my() creates private variables.

And a Quote from Damian Conway' s OOPerl Book:

Quote
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.

Sponsored Links
Joined: Aug 2000
Posts: 335
Member
Member
Offline
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

Code
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) &#0124;&#0124; $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

Code
#!/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 smile

Joined: May 2000
Posts: 1,356
Addict
Addict
Joined: May 2000
Posts: 1,356
you can use anything until you see "deprecated" smile

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
Offline
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. smile

I remember having to do some experimention to come up with that. But I'll play around with it some more.

Sponsored Links
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
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
Offline
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. wink

Joined: Aug 2000
Posts: 335
Member
Member
Offline
Joined: Aug 2000
Posts: 335
Quote
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". smile

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:

Code
our $Config = $::Config;

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
Offline
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:

Code
#!/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

Code
printf "req: %s-%sn", ref($Config),ref($::Config);

1;
Req.pm:
Code
package Req;
printf "Req: %s-%sn", ref($Config),ref($::Config);

1;
output:

Quote
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
Offline
Joined: Aug 2000
Posts: 335
So you're defining the global as
Code
$::Config = CGI->new;
our $Config;
rather than as
Code
our $Config = CGI->new;
.

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 smile 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
Offline
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. smile

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:

Code
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:

Code
...
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
Offline
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. wink


Link Copied to Clipboard
Donate Today!
Donate via PayPal

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.
Recommended Hosts
We have personally worked with and recommend the following Web Hosts:
Stable Host
bluehost
InterServer
Visit us on Facebook
Member Spotlight
isaac
isaac
California
Posts: 1,157
Joined: July 2001
Forum Statistics
Forums63
Topics37,573
Posts293,925
Members13,849
Most Online5,166
Sep 15th, 2019
Today's Statistics
Currently Online
Topics Created
Posts Made
Users Online
Birthdays
Top Posters
AllenAyres 21,079
JoshPet 10,369
LK 7,394
Lord Dexter 6,708
Gizmo 5,833
Greg Hard 4,625
Top Posters(30 Days)
Top Likes Received
isaac 82
Gizmo 20
Brett 7
WebGuy 2
Top Likes Received (30 Days)
None yet
The UBB.Developers Network (UBB.Dev/Threads.Dev) is ©2000-2024 VNC Web Services

 
Powered by UBB.threads™ PHP Forum Software 8.0.0
(Preview build 20221218)