I was appalled to discover today that one of my perl modules uses another module, but doesn't import it.
However, I was shocked when I realized that this has never caused any problems!
The code is something like:
package This;
# no import for OTHER !!
sub new {
... implementation ...
my $something = OTHER->new(#arguments); # no error!
... more implementation ...
}
So what gives? None of This's imports import OTHER -- that was the first thing I checked.
Could it be that if the code that imports This also imports OTHER, OTHER is available to This?
Clarification of question:
X, Y, and Z are modules.
in X: use Y;
in X: use Z;
Y does not use Z
Does Y have access to the functions and methods in Z (and vice versa)?
Your use of the term "import" is a bit misleading.
Does Y have access to Z without importing it (and vice versa)?
Yes, more or less. useing a module just loads it into the current script; all used modules are loaded into the same script, so can see each other (provided they're used in the right order).
But true imports — the things that a module actually exports, so that they're copied into the useing module's namespace — will only be copied into the useing module's namespace.
For example, consider this Perl script:
use Time::HiRes 'time';
package Foo;
sub time1() { return time(); } # calls the built-in time() function
sub time2() { return Time::HiRes::time(); }
package main;
print Foo::time1(), "\n"; # prints (e.g.) 1323048440
print Foo::time2(), "\n"; # prints (e.g.) 1323048440.80571
print time(), "\n"; # prints (e.g.) 1323048440.8061
It uses the Time::HiRes module, and tells it to export Time::HiRes::time into the current namespace (the main namespace), overwriting the built-in time. (Time::HiRes::time is like time, but it has sub-second resolution; it'll give something like 1323048440.80571 instead of just 1323048440.) So package Foo can see Time::HiRes, and anything within Time::HiRes, such as its time; but it has to explicitly specify that, by explicitly writing Time::HiRes::time.
(Note: I wrote the above as a single script, for simplicity of description, but the same thing happens when Foo is defined in Foo.pm and loaded using use Foo;.)
Yes, at least when you use indirect package and object syntax. From calls like
OtherPackage->method()
$anOtherPackageObject->method()
Perl can resolve a fully qualified subroutine name (&OtherPackage::method in both of the above cases) and invoke the subroutine from anywhere.
Related
I have Perl code which relies on Term::ReadKey to get the terminal width. My installation is missing this module, so I want to provide a default if the module isn't present rather than throw an exception.
How can I conditionally use an optional module, without knowing ahead of time whether it is available.
# but only if the module is installed and exists
use Term::ReadKey;
...
How can I accomplish this?
Here's a bare-bones solution that does not require another module:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
Note that all the answers below (I hope they're below this one! :-) that use eval { use SomeModule } are wrong because use statements are evaluated at compile time, regardless of where in the code they appear. So if SomeModule is not available, the script will die immediately upon compiling.
(A string eval of a use statement will also work (eval 'use SomeModule';), but there's no sense parsing and compiling new code at runtime when the require/import pair does the same thing, and is syntax-checked at compile time to boot.)
Finally, note that my use of eval { ... } and $# here is succinct for the purpose of this example. In real code, you should use something like Try::Tiny, or at least be aware of the issues it addresses.
Check out the CPAN module Module::Load::Conditional. It will do what you want.
The classic answer (dating back to Perl 4, at least, long before there was a 'use') was to 'require()' a module. This is executed as the script is run, rather than when compiled, and you can test for success or failure and react appropriately.
if (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}
or
if (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}
Note: the 1; only executes if require Term::... loaded properly.
And if you require a specific version of the module:
my $GOT_READKEY;
BEGIN {
eval {
require Term::ReadKey;
Term::ReadKey->import();
$GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
};
}
# elsewhere in the code
if ($GOT_READKEY) {
# ...
}
use Module::Load::Conditional qw(check_install);
use if check_install(module => 'Clipboard') != undef, 'Clipboard'; # class methods: paste, copy
using if pragma and Module::Load::Conditional core module.
check_install returns hashref or undef.
this module is also mentioned in the see also section of the pragma's documentation:
Module::Load::Conditional provides a number of functions you can use to query what modules are available, and then load one or more of them at runtime.
This is an effective idiom for loading an optional module (so long as you're not using it in a code base with sigdie handler),
use constant HAS_MODULE => defined eval { require Module };
This will require the module if available, and store the status in a constant.
You can use this like,
use constant HAS_READLINE => defined eval { require Term::ReadKey };
my $width = 80;
if ( HAS_READLINE ) {
$width = # ... code, override default.
}
Note, if you need to import it and bring in the symbols you can easily do that too. You can follow it up.
use constant HAS_READLINE => defined eval { require Term::ReadKey };
Term::ReadKey->import if HAS_READLINE;
This method uses constants. This has the advantage that if you don't have this module the dead code paths are purged from the optree.
I think it doesn't work when using variables.
Please check this link which explains how it can be used with variable
$class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
The require function will look for the "Foo::Bar" file in the #INC array and will complain about not finding "Foo::Bar" there. In this case you can do:
eval "require $class";
I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm
Something like below
A.pm:
if (condition1) { $x = 'PASSED'; }
if (condition2) { $x = 'FAILED'; }
B.pm:
if ($x=='PASSED') { $y=1; } else { $y=0; }
I tried using require ("A.pm"); in B.pm but it gives me an error global symbol requires an explicit package name which means it is not able to read the variable from require. Any inputs would help
I have a variable $x which currently has a local scope in A.pm and I want to use the output of $x (which is usually PASSED/FAILED) in an if else statement in B.pm
We could show you how to do this, but this is a really bad, awful idea.
There's a reason why variables are scoped, and even global variables declared with our and not my are still scoped to a particular package.
Imagine someone modifying one of your packages, and not realizing there's a direct connection to a variable name $x. They could end up making a big mess without even knowing why.
What I would HIGHLY recommend is that you use functions (subroutines) to pass around the value you need:
Local/A.pm
package Local::A;
use strict;
use warnings;
use lib qw($ENV{HOME});
use Exporter qw(import);
our #EXPORT_OK = qw(set_condition);
sub set_condition {
if ( condition1 ) {
return "PASSED";
elsif ( condition2 ) {
return "FALSED";
else {
return "Huh?";
}
1;
Here's what I did:
I can't use B as a module name because that's an actual module. Therefore, I used Local::B and Local::A instead. The Local module namespace is undefined in CPAN and never used. You can always declare your own modules under this module namespace.
The use lib allows me to specify where to find my modules.
The package command gives this module a completely separate namespace. This way, variables in A.pm don't affect B.pm.
use Exporter allows me to export subroutines from one module to another. #EXPORT_OK are the names of the subroutines I want to export.
Finally, there's a subroutine that runs my test for me. Instead of setting a variable in A.pm, I return the value from this subroutine.
Check your logic. Your logic is set that $x isn't set if neither condition is true. You probably don't want that.
Your module can't return a zero as the last value. Thus, it's common to always put 1; as the last line of a module.
Local/B.pm
package Local::B;
use lib qw($ENV{HOME});
use Local::A qw(set_condition);
my $condition = set_contition();
my $y;
if ( $condition eq 'PASSED' ) { # Note: Use `eq` and not `==` because THIS IS A STRING!
$y = 1;
else {
$y = 0;
}
1;
Again, I define a separate module namespace with package.
I use Local::A qw(set_condition); to export my set_condition subroutine into B.pm. Now, I can call this subroutine without prefixing it with Local::A all of the time.
I set a locally scoped variable called $condition to the status of my condition.
Now, I can set $y from the results of the subroutine set_condition. No messy need to export variables from one package to another.
If all of this looks like mysterious magic, you need to read about Perl modules. This isn't light summer reading. It can be a bit impenetrable, but it's definitely worth the struggle. Or, get Learning Perl and read up on Chapter 11.
After you require A;, you can then access the variable by giving it an explicit package name like the error message says.
in B.pm:
my $y = $A::x eq 'PASSED ? 1 : 0
The variable $x will have to be declared with our instead of my.
Finally, use eq instead of == for doing string comparisons.
Lets say you have a parent Perl class in one file:
#!/usr/bin/perl
package Foo;
use strict;
use warnings;
use Data::Dumper;
sub new{
my $class = shift;
my %self = ();
return bless %self, $class;
}
1;
and a subclass in a different file:
#!/usr/bin/perl
package Bar;
use base "Foo";
1;
Will the subclass inherit the use statements from the parent? I know the method new will be inherited.
Basically I am trying to reduce the amount of boilerplate in my code and I can't find a clear answer to this question.
You asked in a comment about Test::Most and how it reduces boilerplate. Look at its import method. It's loading the modules into its namespace, adding those symbols to #EXPORT, then re-calling another import through a goto to finally get them into the calling namespace. It's some serious black magic that Curtis has going on there, although I wonder why he just didn't use something like import_to_level. Maybe there are some side effects I'm not thinking about.
I talk quite a bit about this sort of thing in Avoid accidently creating methods from module exports in The Effective Perler. It's in a different context but it's some of the same issues.
Here's a different example.
If some other module loads a module, you have access to it. It's not good to depend on that though. Here are three separate files:
Top.pm
use 5.010;
package Top;
use File::Spec;
sub announce { say "Hello from top!" }
1;
Bottom.pm
package Bottom;
use parent qw(Top);
sub catfiles { File::Spec->catfile( #_ ) }
1;
test.pl
use 5.010;
use Bottom;
say Bottom->catfiles( qw(foo bar baz) );
say File::Spec->catfile( qw( one two three ) );
I only load File::Spec in Top.pm. However, once loaded, I can use it anywhere in my Perl program. The output shows that I was able to "use" the module in other files even though I only loaded it in one:
Bottom/foo/bar/baz
one/two/three
For this to work, the part of the code that loads the module has to load before any other part of the code tries to use that module. As I said, it's a bad idea to depend on this: things break if the loading sequence changes or the loading module disappears.
If you want to import symbols, however, you have to explicitly load the module you want while you are in the package you want to import into. That's just so the exporting module defines the symbols in that package. It's not something that depends with scope.
Ah, good question!
Will the subclass inherit the use statements from the parent?
Well this depends on what you mean by inherit. I won't make any assumptions until the end, but the answer is maybe. You see, perl mixes the ideas of Classes, and Namespaces -- a package is a term that can describe either of them. Now the issue is the statement use all it does is force a package inclusion, and call the targets import() sub. This means it essentially has unlimited control over your package - and by way of that your class.
Now, compound this with all methods in perl being nothing more than subs that take $self as a first argument by convention and you're left with perl5. This has an enormous upside for those that know how to use it. While strict is a lexical pragma, what about Moose?
package BigMooseUser;
use Moose;
package BabyMooseUser;
our #ISA = 'BigMooseUser';
package Foo;
my $b = BabyMooseUser->new;
print $b->meta->name;
Now, where did BabyMooseUser get the constructor (new) from? Where did it get the meta class from? All of this is provided from a single use Moose; in the parent class (namespace). So
Will the subclass inherit the use statements from the parent?
Well, here, in our example, if the effects of the use statement are to add methods, than certainly.
This subject is kind of deep, and it depends if you're talking about pragmas, or more obscure object frameworks, or procedural modules. If you want to mitigate a parents namespace from affecting your own in the OO paradigm see namespace::autoclean.
For boilerplate reduction, I have a couple of strategies: Most of my classes are Moose classes, which takes care of OO setup and also gives me strict and warnings. If I want to have functions available in many packages, I'll create a project specific MyProject::Util module that uses Sub-Exporter to provide me with my own functions and my own interface. This makes it more consistent, and if I decide to change the Dumper (for example) later for whatever reason, I don't have to change lots of code. That'll also allow you to group exports. A class then usually looks something like this:
package Foo;
use Moose;
use MyProject::Util qw( :parsing :logging );
use namespace::autoclean;
# class implementation goes here
1;
If there's other things you regard as boilerplate and want to make simpler to include, it of course depends on what those things are.
A pragmatic answer to your problem: Either use, or look at how Modern::Perl does it to enforce strict and warnings.
You can get a definitive answer by examining the symbol tables for each package:
# examine-symbol-tables.pl
use Bar;
%parent_names = map{$_ => 1} keys %Foo::;
%child_names = map{$_ => 1} keys %Bar::;
delete $parent_names{$_} && ($common_names{$_} = delete $child_names{$_}) foreach keys %child_names;
print "Common names in symbol tables:\n";
print "#{[keys %common_names]}\n\n";
print "Unique names in Bar symbol table:\n";
print "#{[keys %child_names]}\n\n";
print "Unique names in Foo symbol table:\n";
print "#{[keys %parent_names]}\n\n";
$ perl inherit.pl
Common names in symbol tables:
BEGIN
Unique names in Bar symbol table:
ISA isa import
Unique names in Foo symbol table:
Dumper new VERSION
What is the difference between package, module and class in object oriented Perl?
Modules are a single file, a .pm file that provides code. That could be no packages, a single package, or more than one package. A module doesn't really care what is in it, so it can be code that inserts itself into the same namespace, a more-traditional set of subroutines in a library or define Perl's idea of a class.
A package, also known as a namespace, contains its own variables and subroutines. It's a way of segregating different parts of your program. You create the package and put your code into it:
package SomePackage;
sub some_subroutine { ... } # really SomePackage::some_subroutine
You load the module to get access to the package:
use SomePackage; # read and compile the module file
SomePackage::some_subroutine( ... );
A Perl class is a package and its associated behavior. The methods in a class are just normal subroutines, although when we treat the subroutines as methods, the first parameter is the thing (a package name or object, also known as the referent) that called method:
package SomeClass;
sub class_method { my( $class, #args ) = #_; ... }
sub instance_method { my( $self, #args ) = #_; ... }
Since the class is just a package like any other package and probably lives in a module, you access it the same way with use:
use SomeClass;
my $i = SomeClass->class_method( ... );
The OO arrow syntax does some special stuff to let the some_method subroutine know that it's being called as a method. Perl puts the referent (the SomeClass in this case) as the first argument. Additionally, when using the OO syntax, Perl knows to use its inheritance features.
Methods called with '->' get the referent as the first parameter to the method, so this call:
SomeClass->new('world');
is syntactically the same as if you had called it with the class name as the first parameter:
SomeClass::new( 'SomeClass' ,'world'); # no inheritance this way
That works the same for objects too. When an object is the referent:
my $i = SomeClass->new();
$i->bar( 'world');
the object is the first parameter as the method:
SomeClass::bar($i, 'world');
Perl doesn't have classes. It has namespaces that you change with package. For the complete details of Perl OOP, see Intermediate Perl or Object Oriented Perl. You can also see the perltoot and perlboot documentation. In short, Perl fakes what people expect "real" classes to be with packages, normal subroutines, and references.
A module is a distributable piece of code contained in a file. See perlmod.
I say more about this in my post for The Effective Perler, Find a module's release managers. I don't get into the OO stuff, but I talk about the other terms around "module".
I have Perl code which relies on Term::ReadKey to get the terminal width. My installation is missing this module, so I want to provide a default if the module isn't present rather than throw an exception.
How can I conditionally use an optional module, without knowing ahead of time whether it is available.
# but only if the module is installed and exists
use Term::ReadKey;
...
How can I accomplish this?
Here's a bare-bones solution that does not require another module:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
Note that all the answers below (I hope they're below this one! :-) that use eval { use SomeModule } are wrong because use statements are evaluated at compile time, regardless of where in the code they appear. So if SomeModule is not available, the script will die immediately upon compiling.
(A string eval of a use statement will also work (eval 'use SomeModule';), but there's no sense parsing and compiling new code at runtime when the require/import pair does the same thing, and is syntax-checked at compile time to boot.)
Finally, note that my use of eval { ... } and $# here is succinct for the purpose of this example. In real code, you should use something like Try::Tiny, or at least be aware of the issues it addresses.
Check out the CPAN module Module::Load::Conditional. It will do what you want.
The classic answer (dating back to Perl 4, at least, long before there was a 'use') was to 'require()' a module. This is executed as the script is run, rather than when compiled, and you can test for success or failure and react appropriately.
if (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}
or
if (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}
Note: the 1; only executes if require Term::... loaded properly.
And if you require a specific version of the module:
my $GOT_READKEY;
BEGIN {
eval {
require Term::ReadKey;
Term::ReadKey->import();
$GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
};
}
# elsewhere in the code
if ($GOT_READKEY) {
# ...
}
use Module::Load::Conditional qw(check_install);
use if check_install(module => 'Clipboard') != undef, 'Clipboard'; # class methods: paste, copy
using if pragma and Module::Load::Conditional core module.
check_install returns hashref or undef.
this module is also mentioned in the see also section of the pragma's documentation:
Module::Load::Conditional provides a number of functions you can use to query what modules are available, and then load one or more of them at runtime.
This is an effective idiom for loading an optional module (so long as you're not using it in a code base with sigdie handler),
use constant HAS_MODULE => defined eval { require Module };
This will require the module if available, and store the status in a constant.
You can use this like,
use constant HAS_READLINE => defined eval { require Term::ReadKey };
my $width = 80;
if ( HAS_READLINE ) {
$width = # ... code, override default.
}
Note, if you need to import it and bring in the symbols you can easily do that too. You can follow it up.
use constant HAS_READLINE => defined eval { require Term::ReadKey };
Term::ReadKey->import if HAS_READLINE;
This method uses constants. This has the advantage that if you don't have this module the dead code paths are purged from the optree.
I think it doesn't work when using variables.
Please check this link which explains how it can be used with variable
$class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
The require function will look for the "Foo::Bar" file in the #INC array and will complain about not finding "Foo::Bar" there. In this case you can do:
eval "require $class";