I am creating a Perl equivalent to my Python project.
Description:
I have a base module "base.py" that is used by all my scripts via "from base import *"
The base module has common subroutines/functions that can be executed inside the scripts
My attempt for Perl was placing inside each script "use base.pm". However the subroutines in Perl were not locally imported to the script so I needed to make a call to the "base" module each time I wanted to execute a subroutine. What is the Perl equivalent to Python's "from base import *"?
A few things:
The Local namespace is good to use for your local modules. Perl specifically reserves Local for this purpose. No official module will ever be in the Local namespace.
Perl is not Python. Perl will do things a bit differently. Sometimes there's an exact equivalent, sometimes not. This does not have an exact equivalent. Close, but not exact.
Method #1: Don't Export Any Functions
All functions you defined in your modules are available if you prefix the full namespace to it. This is the easiest way to define and use functions from your modules and is the least likely to cause problems. It's easy to see where a function came from, and you won't have a problem with two modules using the same function name.
I have a module called Local::Base that has a single function in it. My program can use this function, by simply referring it as Local::Base::foo:
My Program
use strict;
use warnings;
use feature qw(say);
use Local::Base;
my $foo_string = Local::Base::foo("string");
say "Foo: $foo_string";
Local/Base.pm
package Local::Base;
use strict;
use warnings;
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
Method #2: Use the Exporter Pragma to Specify What to Automatically Export
Perl has a special pragma called Exporter that allows me to specify which modules will automatically be imported into my program.
This is not like Python where I can specify any defined function. Instead, I have to list the ones I want to export. This has a disadvantage over Python's way: In Python, if I write a new function, it's automatically imported without me having to do anything. It also has a big advantage over Python's way: In Python, if I write a new function, it's automatically imported without me having to do anything whether I wanted it imported or not. You can imagine if I wrote a private function I didn't want people to use. In Python, it would automatically be available. In Perl, it wouldn't be unless I specified it:
My Program
use strict;
use warnings;
use feature qw(say);
use Local::Base;
my $foo_string = foo("string");
say "Foo: $foo_string";
Local/Base.pm
package Local::Base;
use strict;
use warnings;
use Exporter 'import';
our #EXPORT = qw(foo);
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
Now, whenever I use Local::Base, the foo function is automatically imported.
Notice that I list all functions I want to export in the #EXPORT array. (Also note I declare that array with an our instead of a my. That our means the #EXPORT is a PACKAGE variable.). Also notice the qw(...) syntax. This is quote word. All words are separate elements of an array. You don't use commas:
my #array = ("one", "two", "three");
my #array = qw(one two three);
Both of these are equivalent. You also may see it this way:
my #array = qw/one two three/;
I like the parentheses, but the forward slashes tend to be the standard.
Method #3: Be Nice When Exporting
It is not recommended you use automatic exporting any more. Older modules like File::Copy still do it, but newer modules make you import your stuff. This also uses the Exporter pragma, but I specify #EXPORT_OK instead of just #EXPORT.
Now, when I specify I want to use Local::Base, I have to specify the functions I want to import into my program:
My Program
use strict;
use warnings;
use feature qw(say);
use Local::Base qw(foo);
my $foo_string = foo("string");
say "Foo: $foo_string";
Local/Base.pm
package Local::Base;
use strict;
use warnings;
use Exporter 'import';
our #EXPORT_OK; = qw(foo);
sub foo {
my $string = shift;
return qq(I've foo'd "$string"!);
}
1;
This forces the user to document the functions in your module they want to use. This way, they know where imported functions came from. It enforces good programming practice. Plus, if you use multiple modules and they have similar function names, you can make sure you use the one from the module you want. (Remember, you can still specify the package name prefixed before the function if you want to use the other one).
What if I am a Python programmer and I don't care about good programming practices? (Wait, that didn't come out quite right...) You can still (sort of) do it the Python way by specifying a Regular Expression (after all this is Perl):
use Local::Base '/.+/';
This will export all modules listed in both #EXPORT and #EXPORT_OK that match this regular expression. Since this matches everything, it will import everything you listed in #EXPORT and #EXPORT_OK. It won't import all functions. It will only import the functions in the #EXPORT and #EXPORT_OK arrays. Of course, you can specify any regular expressions and even ant-regular expressions. This will export all exportable functions except those with bar in the name:
use Local::Base '!/bar/';
Take a look at the Exporter pragma, and see what other goodies it has. For example, you can group functions into tags. That way, users can specify a particular set of functions with just a tag. See Math::Trig for a good example.
Hope this helps.
Sorry for the long answer, but I'm married with kids. Like, I'm doing anything else on New Years Eve.
You generally specify which functions to import just as a list of names:
use List::Util 'max', 'min';
Most modules that export things will follow these semantics:
use MyBase; # imports default exports (if any)
use MyBase 'baz'; # imports only baz
use MyBase (); # import nothing
Inside the module, an import class method is called that can choose what to export, usually having a default list but using the list passed if there is one. The Exporter module exists to help you do this:
package MyBase;
use Exporter 'import';
our #EXPORT = ( 'foo', 'bar' );
our #EXPORT_OK = ( 'baz', 'quux' );
There is also a facility for grouping exports by tag and allowing importing a whole group easily, see the Exporter docs. Variables can also be exported, not just subs.
With that background, to finally answer your question:
For modules that use Exporter (not all do), you can specify imports with a regular expression enclosed in //:
use List::Util '/./';
First of all base.pm is a very bad name as it is a core module. Second, exportable functions must be declared as such (usually), see Exporter for examples.
Related
I am stuck while creating a perl Moose module.
I have a global pm module.
package XYZ;
require Exporter;
our #ISA = qw(Exporter); ## EDIT missed this line
our #EXPORT_OK = qw($VAR);
my $VAR1 = 1;
our $VAR = {'XYZ' => $VAR1};
1;
I want to get $VAR in a Moose module I'm creating
package THIS;
use Moose;
use YAML::XS;
sub get_all_blocks{
my ($self) = #_;
require $self->get_pkg(); # this returns the full path+name of the above package
# i cannot use use lib+use since the get_pkg starts complaining
our $VAR;
print YAML::XS::Dump($XYZ::VAR); # this works
print YAML::XS::Dump($VAR); # this does not work
# i cannot use the scope resolution since XYZ would keep changing.
}
1;
Can someone please help me with accessing variable?
EDIT: Missed one line in the package XYZ code.
I cannot touch the package XYZ since it is owned/used by someone else, I can just use it :(
Exporting variables may easily lead to trouble.
Why not
package XYZ;
use strict;
use warnings;
use Exporter qw(import);
our #EXPORT_OK = qw(get_var);
my $VAR = '...'; # no need for "our" now
sub get_var { return $VAR }
...
1;
and then
package THIS;
use warnings;
use strict;
use XYZ qw(get_var);
my $var = get_var();
...
1;
See Exporter.
As for what you tried to do, there are two direct problems
$VAR from XYZ is never imported into THIS. If you need symbols from other packages you need to import them.† Those packages have to make them available first, so you need to add it to #EXPORT_OK as well.
Like above but with $VAR instead of get_var()
package XYZ;
...
use Exporter qw(import);
our #EXPORT_OK = qw($VAR);
our $VAR = '...'; # need be "our" for this
with
package THIS;
...
use XYZ qw($VAR);
print "$VAR\n";
Now $VAR can be used directly, including being written to (unless declared constant); that can change its value under the feet of yet other code, which may never even know about any of it.
Another way is to use #EXPORT and then those symbols are introduced into every program that says use Package;. I strongly recommend to only use #EXPORT_OK, when callers need to explicitly list what they want. That also nicely documents what is being used.
Even once you add that, there is still a variable with the same name in THIS, which hides (masks, shadows) the $XYZ::VAR. So remove our $VAR in THIS. This is an excellent example of one problem with globals. Once they're introduced we have to be careful about them always and everywhere.
But there are far greater problems with sharing variables across modules.
It makes code components entangled and the code gets harder and harder to work with. It runs contrary to principles of well defined scopes and modular design, it enables action at a distance, etc. Perl provides many good tools for structuring code and we rarely need globals and shared variables. It is telling that the Exporter itself warns against that.
Note how now my $VAR in XYZ is not visible outside XYZ; there is no way for any code outside XYZ to know about it or to access it.‡ When it is our then any code in the interpreter can write it simply as $XYZ::VAR, and without even importing it; that's what we don't want.
Of course that there may be a need for or good use of exporting variables, what can occasionally be found in modules. That is an exception though, to be used sparingly and carefully.
† Unless they're declared as package globals under a lexical alias via our in their package, in which case they can be used anywhere as $TheirPackageName::varname.
‡ This complete privacy is courtesy of my.
You do not want our $VAR; in THIS's namespace. That creates a lexical reference to $THIS::VAR. Not what you want.
Instead, you need to use properly:
use XYZ qw($VAR);
However, XYZ doesn't have an import to run here, so you need to update that. There are two ways to fix XYZ to do this - one is to import import, e.g., use Exporter qw(import);, the other is to derive off Exporter, e.g., use parent qw(Exporter);. Both of these will get XYZ->import(...) to work properly.
Once XYZ is useing Exporter correctly, then the use XYZ qw($VAR); line will cause perl to implicitly load XYZ and call XYZ->import(qw($VAR)), which will import that variable into your namespace.
Now, having answered your question, I will join others in suggesting that exporting variables is a very bad code smell, and probably is not the best / cleanest way to do what you want.
I am thinking of using the following perl modules from Cpan:
CSS-Minifier
Javascript-Minifier
I note from the documentation that I need to call the "minify" method for both.
I know I must be missing something obvious as a Perl newbie, but wouldn't they collide?
I suppose the question is how do I specify the "minify" for each module separately so that the CSS module works on CSS only and the JS module works on JS only?
Perl modules include subroutines. Usually, the reason to use a module is to make use of the subroutines from that module. A module will have its own package name and the subroutines from that module will exist in that package. So a simple module might look like this:
package MyModule;
sub my_sub {
print "This is my sub\n";
}
If I load that module in my code, then I have to call the subroutine using its fully qualified name (i.e. including the package name).
use MyModule;
MyModule::my_sub();
That gets repetitive quite quickly, so many modules will export their subroutines into your package. They do that using special arrays called #EXPORT and #EXPORT_OK.
If I put the name of a subroutine into #EXPORT then it automatically gets imported whenever that module is used.
package MyModule;
our #EXPORT = ('my_sub');
sub my_sub {
print "This is my sub\n";
}
I can then use it like this:
use MyModule;
my_sub();
Alternatively, I can use #EXPORT_OK which defines optional exports. Users can ask for subroutines in #EXPORT_OK to be imported - but it doesn't happen automatically. You ask for an option export to be imported by including the name in the use statement.
package MyModule;
our #EXPORT_OK = ('my_sub');
sub my_sub {
print "This is my sub\n";
}
I can now do this:
use MyModule ('my_sub');
my_sub();
There's one more trick that might be useful. You can turn off automatic imports with an empty list on the use statement. Assume we have the #EXPORT version of the module:
use MyModule (); # Turn off imports
my_sub(); # Doesn't work
MyModule::my_sub(); # works
Now we have the knowledge we need to look at your specific problem. The simplest solution is to turn off all automatic imports and use the fully-qualified names of both of the subroutines.
use CSS::Minifier ();
use JavaScript::Minifier();
CSS::Minifier::minify();
JavaScript::Minifier::minify();
But we can be a bit cleverer. The documentation for both modules suggests that both imports are optional so that you need to explicitly import the subroutines.
use CSS::Minifier ('minify');
use JavaScript::Minifier('minify');
This would obviously be a bad thing to do, as you can't import two subroutines with the same name!
However, looking at the source code to the modules, I see that the documentation for JavaScript::Minifier is wrong (Edit: I've submitted a report about this error). CSS::Minifier has this line of code:
our #EXPORT_OK = qw(minify);
But JavaScript::Minifier has this:
our #EXPORT = qw(minify);
So the export is automatic from JavaScript::Minifier and optional from CSS::Minifier. So the simplest approach to take would be:
use JavaScript::Minifier; # Automatically imports minify
use CSS::Minifier; # Doesn't import option export minify
You could then use the two subroutines like this:
minify(); # Automatic export from JavaScript::Minifier
CSS::Minifier::minify(); # Fully-qualified name from CSS::Minifier
I suspect, however, that this is a bad approach as it's hard to be sure where the unqualified version of minify() comes from. I'd therefore recommend turning off all imports from the two modules and using the fully-qualified names for both subroutines.
To call it separately if both exported, use :
CSS::Minifier::minify();
or
JavaScript::Minifier::minify();
You can use the fully qualified names to reference subroutines and remove ambiguity. And create shorter names with aliases.
use CSS::Minifier;
use JavaScript::Minifier;
BEGIN {
*minify_css = \&{CSS::Minifier::minify};
*minify_js = \&{JavaScript::Minifier::minify};
}
minify_css(...);
minify_js(...);
I need to modify a bunch of scripts to do the equivalent of a straight C style "include" of a moderate number of variables. After the "use" to pull these in it should act exactly as if a line like this had been included:
my $os_name = "Windows"; #declares the variable AND sets its value
So that they may be used in the "calling" script. There is a little bit of logic in the module that conditionally sets the values of these variables. The scripts all have "use strict". A typical "caller" has:
use strict;
use File::Basename;
use lib dirname (__FILE__);
use os_specific;
print "DEBUG os_name $os_name\n";
and the module (os_specific.pm) has:
package os_specific;
use warnings;
use strict;
use Exporter;
our #EXPORT = qw($os_name);
our $os_name="Windows";
1
But it doesn't work, there are compile stage warnings like:
Global symbol "$os_name" requires explicit package name at caller.pl.
So the declaration of the variable in the module is not effective at the caller's scope.
Can this be done, or must each of these variables also be declared in caller.pl? (All responses please employ "use strict" - without that it can be done using a "require". That doesn't work with "use strict" though because it throws a compile time error.)
I know the variables from the module can be used as "$os_specific::os_name", the question is how to set this up so that they can be used as just "$os_name".
Thanks.
The problem is that you aren't inheriting any functionality from Exporter because you haven't set the #ISA package variable.
Your module should look like this, after fixing the package name (packages should use upper and lower case letters only, by convention) and should be in the file OSSpecific.pm
package OSSpecific;
use strict;
use warnings;
use Exporter;
our #ISA = qw/ Exporter /;
our #EXPORT = qw/ $os_name /;
our $os_name = "Windows";
1;
You need an explicit import method in your package, as demonstrated in Exporter.
You also need to fix the casing of your package name, the filename, and your use statement so they all match.
OS_Specific.pm:
package OS_Specific;
use warnings;
use strict;
use Exporter qw(import);
And the other file:
use OS_Specific;
Check out perlstyle for useful guidelines on picking package names:
Perl informally reserves lowercase module names for "pragma" modules like integer and strict. Other modules should begin with a capital letter and use mixed case, but probably without underscores due to limitations in primitive file systems' representations of module names as files that must fit into a few sparse bytes.
EDIT
Sorry for the confusion, here is my updated question.
I am using FindBin in my perl script like this:
use FindBin qw($Bin);
use lib "$Bin/../lib";
use multi_lib qw(say_hello_world);
This works:
multi_lib::say_hello_world();
but this does not:
say_hello_world();
EDIT 2
This is how multi_lib.pm looks:
package multi_lib;
use strict;
use warnings;
use 5.010;
require Exporter;
my #ISA = qw(Exporter); # removing `my` causes an error!
my #EXPORT_OK = qw(say_hello_world); # removing `my` causes an error!
sub say_hello_world {
say "hello world!";
}
p.s.
I have no idea what does #ISA stand for and if adding the my is OK... I followed the preldoc for Exporter.
Edit 3
I think I solved it by moving #EXPORT_OK before use strict. I am used to put use strict right at the beginning of my scripts but I guess this is not the way to go here (?). Anyway, this works:
use Exporter 'import';
#EXPORT_OK = qw(say_hello_world);
use strict;
...
I would still appreciate some explanations as to what exactly is going on here and what is the recommended way of exporting subroutines (like I did?).
You can't do that. lib's import() routine modifies #INC instead of trying to export anything.
But in any case, there are no functions in lib.pm that are suitable for external use. What are you really trying to accomplish?
Updated answer for updated question:
No, you cannot use my() on #EXPORT_OK; it needs to be globally visible so Exporter can use it.
Say our #EXPORT_OK; instead. The same is true for #ISA; the package variable #ISA controls inheritance, a lexical #ISA does nothing. I prefer not inheriting from Exporter, though; you do this (except with very old Exporter) by just importing Exporter's import routine:
use Exporter 5.57 'import';
The error you got that prompted you to add my() was because you specified use strict; (which, among other things, requires that variables be properly declared unless they are package variables qualified by package name or special global variables). our() is the equivalent to my() that declares variables as package variables instead of lexicals, so they are accessible from outside the scope in which they are declared. It's better to properly declare them with our() than to just move them above use strict; to get around the error.
That's not the way libraries work. You need to set your library location then load a module (.pm) from it that contains the subroutine you want.
I would like to imprt a specific
subroutine (aka say_hello_world) from
lib, but this does not work:
use lib "$Bin/../lib" qw(say_hello_world);
The use lib just points you to the directory where the files are, you need to specify the file as well. If your subroutine is in a file Example.pm then you need
use Example qw(say_hello_world);
Also note that the FindBin part needs to be inside a BEGIN block:
BEGIN {
use FindBin qw($Bin);
use lib "$Bin/../lib";
};
use Example qw(say_hello_world);
Is there a standard way to code a module to hold global application parameters to be included in every other package? For instance: use Config;?
A simple package that only contains our variables? What about readonly variables?
There's already a standard Config module, so choose a different name.
Say you have MyConfig.pm with the following contents:
package MyConfig;
our $Foo = "bar";
our %Baz = (quux => "potrzebie");
1;
Then other modules might use it as in
#! /usr/bin/perl
use warnings;
use strict;
use MyConfig;
print "Foo = $MyConfig::Foo\n";
print $MyConfig::Baz{quux}, "\n";
If you don't want to fully qualify the names, then use the standard Exporter module instead.
Add three lines to MyConfig.pm:
package MyConfig;
require Exporter;
our #ISA = qw/ Exporter /;
our #EXPORT = qw/ $Foo %Baz /;
our $Foo = "bar";
our %Baz = (quux => "potrzebie");
1;
Now the full package name is no longer necessary:
#! /usr/bin/perl
use warnings;
use strict;
use MyConfig;
print "Foo = $Foo\n";
print $Baz{quux}, "\n";
You could add a read-only scalar to MyConfig.pm with
our $READONLY;
*READONLY = \42;
This is documented in perlmod.
After adding it to #MyConfig::EXPORT, you might try
$READONLY = 3;
in a different module, but you'll get
Modification of a read-only value attempted at ./program line 12.
As an alternative, you could declare in MyConfig.pm constants using the constant module and then export those.
Don't use global variables for configuration and don't sotre configuration as code. I have an entire chapter in Mastering Perl about this.
Instead, make a configuration class that any other package can use to access the configuration data. It will be much easier in the long run to provide an interface to something you may want to change later than deal with the nuttiness you lock yourself into by scattering variables names you have to support for the rest of your life.
A config interface also gives you the benefit of composing new answers to configuration questions by combining the right bits of actual configuration data. You hide all of that behind a method and the higher levels don't have to see how it's implemented. For instance,
print "Hello!" unless $config->be_silent;
The be_silent answer can be triggered for multiple reasons the higher-level code doesn't need to know about. It could be from a user switch, that the program detected it is not interactive, and so on. It can also be flipped by options such as a debugging switch, which overrides all other preferences. No matter what you decide, that code line doesn't change because that statement only cares about the answer, not how you got the answer.