Re: How to use variables from other package?
by Chmrr (Vicar) on Apr 27, 2003 at 06:15 UTC
|
Lexical variables (those created with my) do not show up in the symbol table, and thus can't be accessed via the $Packagename::variable syntax. In this case (assuming perl 5.6.0 or later), you'll want to do:
package CNLLog;
our $_POST_CONVERSION = "postConversion";
our $_CORRECTIVE_SCRIPTS = "correctiveScripts";
..and in the other file..
print $CNLLog::_POST_CONVERSION;
Older versions of perl will need to use the use vars pragma. See perldoc vars.
Update: One should also mention the wonderful article Coping with Scoping, by MJD. See also 'our' is not 'my'.
perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER' | [reply] [d/l] [select] |
Re: How to use variables from other package?
by Ovid (Cardinal) on Apr 27, 2003 at 06:35 UTC
|
package Foo;
use base 'Exporter';
use vars qw( @ISA @EXPORT_OK $foo );
@EXPORT_OK = qw( $foo );
$foo = 3;
And then in your code:
use Foo qw($foo);
print $foo;
Note that the qw() operator is used. Those are strings being quoted, not variables. See perldoc Exporter for more information.
Cheers,
Ovid
New address of my CGI Course.
Silence is Evil (feel free to copy and distribute widely - note copyright text) | [reply] [d/l] [select] |
|
package Foo;
use vars qw( $foo );
$foo = 3;
Script:
use Foo;
print $Foo::foo;
It works for me. But is there something wrong with this method? Apart from the fact, that I have to explicity call $foo with the package name. | [reply] [d/l] [select] |
|
use Foo;
print $Foo::fooo; # woops!
One argument for using a fully qualified name is that you prevent a name clash with a variable in the current scope, although I would consider it bad style to reuse a variable name in two scopes, where it is used in both and from both. It would also indicate to me that the variable has perhaps been badly named.
As usual it depends on the situation, but you need to be aware of the pitfalls of the approach you take. One module which uses package globals to modify its behaviour is Data::Dumper, which has variables such as Purity and Terse. These have quite common names, but you wouldn't want to export them into the current package because they are only used by the Data::Dumper code.
Data::Dumper on the other hand does have a more 'modern' interface to the same functions by using an object to store the settings which has the advantage of allows different callers to use different options.
--
integral, resident of freenode's #perl
| [reply] [d/l] [select] |
|
|
|
package Foo;
use Exporter::Tidy _map => { '$foo' => \my $foo };
$foo = 3;
And then, in the code that uses the package, unchanged:
use Foo qw($foo);
print $foo;
Juerd
# { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }
| [reply] [d/l] [select] |
Re: How to use variables from other package?
by Necos (Friar) on Apr 27, 2003 at 10:52 UTC
|
I know this is a bit overkill, but, another solution altogether would be to write a function that just returns the value of your my'd variables. Something like this would work (untested):
package CNLLog;
my $_POST_CONVERSION = "postConversion";
my $_CORRECTIVE_SCRIPTS = "correctiveScripts";
sub postConversion_status {
return $_POST_CONVERSION;
}
And in your other package:
use CNLLog;
$temp = CNLLog::postConversion_status;
print $temp;
Exporter is a great module, but sometimes people don't want you stepping over their namespaces (functional or otherwise... And I know that you should use @EXPORT_OK, but not everyone does that). So, using fully-qualified function calls can be very useful.
Hope that helps some,
Theodore Charles III
Network Administrator
Los Angeles Senior High
email->secon_kun@hotmail.com
perl -e "map{print++$_}split//,Mdbnr;" | [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
|
|
Re: How to use variables from other package?
by nite_man (Deacon) on Apr 27, 2003 at 17:25 UTC
|
I would like to suggest OO way.
Package with constants:
package C;
use vars qw( $AUTOLOAD %const_values );
my %const_values = ( CONST_1 => 1,
CONST_2 => 23,
CONST_3 => 'Test',
. . .
);
use overload '``' => sub { return $const_values{shift} } ;
# All constants can be accessed as by using AUTOLOAD
sub AUTOLOAD {
no strict 'refs', 'subs';
if ($AUTOLOAD =~ /.*::([A-Z]\w+)$/) {
my $const_name = $1;
*{$AUTOLOAD} = sub {return $const_values{$const_name}};
return $const_values{$const_name};
}
return undef;
}
1;
Usage in my test.pl:
#!/usr/bin/perl -w
use C;
print "Const 1:".C->CONST_1."\n";
print "Const 2:".C->CONST_2."\n";
print "Const 3:".C->CONST_3."\n";
__DATA__
Const 1: 1
Const 2: 23
Const 3: Test
Hope that it will be usefull for you.
--------------------------------
SV* sv_bless(SV* sv, HV* stash);
| [reply] [d/l] [select] |
Re: How to use variables from other package?
by jonadab (Parson) on Apr 28, 2003 at 02:39 UTC
|
You shouldn't be using my on variables that another
piece of code somewhere else ever might need to access.
my is strictly for variables that will never need to
be accessed from anywhere else -- loop counters and
internal stuff that other code shouldn't mess with.
You've probably read or heard somewhere from someone
an oversimplistic comment to the effect that you
should declare all your variables with my, but if so
that is fundamentally wrongheaded. You should
declare variables with my when you want them
to be accessible exclusively from the current code
block (i.e., lexically scoped). (Or when you want
to create a closure, but closures are beyond the
scope of this discussion.) It especially makes
no sense to declare all your varibles with my after a
package declaration, because the package declaration
already accomplishes the thing that is usually the
major goal of lexical scoping (i.e., to keep other
code from _accidentally_ tromping your variables
or having theirs tromped by your code). There are
certainly
cases where _certain_ variables should be scoped
with my inside a package, or even most of them,
but if you're doing it to
every single varibale without thinking, don't.
The Coping with Scoping article that chmrr suggested
is (mostly) excellent, and you should read
it if there's any part of what I said above that you
don't fully understand. It neglects to explain why
you would _want_ other code to be able to expressly
alter your variables, but from your post it appears
that you already understand that part. It also does
not explain dynamic scope 100% correctly (and in fact
is dead wrong on at least one point), but you don't
need to understand dynamic scope in order to correctly
use lexical and package scope. You _do_ need to
understand the differences between package scope
and lexical scope, and it explains that very well,
so I won't repeat the explanation here.
Go read it.
{my$c;$ x=sub{++$c}}map{$ \.=$_->()}map{my$a=$_->[1];
sub{$a++ }}sort{_($a->[0 ])<=>_( $b->[0])}map{my@x=(&
$x( ),$ _) ;\ @x} split //, "rPcr t lhuJnhea eretk.as
o";print;sub _{ord(shift)*($=-++$^H)%(42-ord("\r"))};
| [reply] [d/l] |