Is it possible to write a module in a way that when the module is used with no explicit import all subroutines are imported and when it is used with explicit import only theses explicit imported subroutines are available?
#!/usr/bin/env perl6
use v6;
use Bar::Foo;
# all subroutines are imported
sub-one();
sub-two();
sub-three();
#!/usr/bin/env perl6
use v6;
use Bar::Foo :sub-one, :sub-two;
sub-one();
sub-two();
# sub-three not imported
Give your subs both the special label :DEFAULT as well as a dedicated one when exporting, eg
unit module Bar;
sub one is export(:DEFAULT, :one) { say "one" }
sub two is export(:DEFAULT, :two) { say "two" }
Now, you can import all of them with a plain use Bar, or can select specific ones via use Bar :one;
Related
Is there any benefit (w.r.t performance/memory usage) in including use mylibrary conditionally (assuming mylibrary is used only if condition is true) compared to adding use mylibrary on top of the script unconditionally?
# Script 1 (Unconditional use)
use mylibrary;
if($condition)
{
# Do something with mylibrary
}
# Script 2 (Conditional use)
if($condition)
{
use mylibrary;
# Do something with mylibrary
}
use is a compile-time construct. In your two cases, mylibrary is actually being imported in both of your "Unconditional" and "Conditional" cases. If you want to import a library conditionally, use require, a run-time construct, instead.
if ($condition) {
require mylibrary;
# mylibrary->import;
# ...
}
In such a case you lose some of the compile-time benefits of use. For example, require does not call mylibrary->import at compile time, as use does. You can call import yourself if you want, as I show above, but anything import does that has an effect at compile time will not have that effect when called at run time.
Suppose your module mylibrary exports a function foo. Then this works:
use strict;
use mylibrary; # exports function foo()
foo;
But this is an error:
use strict;
require mylibrary;
mylibrary->import; # too late to notify Perl's parser about the foo() function
foo; # error; unknown function
As to whether there's any benefit to doing so, there can be if mylibrary is expensive to import. Most of the time, probably not.
You can achieve conditional loading, including the side benefits of the use (the calling of ->import, and execution at compilation time) with the if pragma: http://perldoc.perl.org/if.html
use if $Config{usethreads}, 'Library::Requiring::Threads';
One caveat, of course, is that the if expression is executed at compile time, so everything it depends on must also be known and available at compile time.
I am trying to create my own module in perl that provides functions for data analysis out of a database.
I have several functions in EDL::Functions, eg. EDL::Functions::Average.
package EDL::Functions;
use warnings;
use strict;
package EDL::Functions::Average;
use parent "EDL::Functions";
sub new{...}
sub execute {...}
1) What do i have to add so use EDL::Functions; automatically imports all modules in EDL::Functions? Currently i have to import all submodules (in EDL::Functions)in order to make it work:
BEGIN {
our $VERSION = 5.20;
use EDL::Functions::Average;
use EDL::Functions::GetAllValues;
use EDL::Functions::GetValueStart;
use EDL::Functions::GetValueEnd;
use EDL::Functions::Min;
use EDL::Functions::Max;
use EDL::Functions::Median;
}
2) I want to make sure that if someone else builds his own function module the compilation will fail if it doesn't have the functions new and execute. How can i achieve that?
Thanks for your help!
It should work
perl -I ./ -MEDL::Functions -e 'EDL::Functions::Average->new();'
returns "I'm new".
cat EDL/Functions.pm
package EDL::Functions;
use warnings;
use strict;
package EDL::Functions::Average;
use parent "EDL::Functions";
sub new{ print "I'm new"; }
sub execute { print "Executing something";}
1;
But I prefere different structure, not declare several packages in one pm file. It'll save time for other devs and follows common practice, so EDL::Functions::Average should be at EDL/Functions/Average.pm
This question already has answers here:
Perl - Package/Module Issues
(4 answers)
Closed 9 years ago.
I am trying to do simple module usage in Perl:
Flame/Text.pm:
package Flame::Text;
sub words { … }
1;
Flame/Query.pm:
package Flame::Query;
use Flame::Text qw(words);
sub parse_query { words(shift); }
parse_query 'hi';
1;
Why am I getting the following error message?
Undefined subroutine &Flame::Query::words called at Flame/Query.pm line 3.
The following works just fine:
package Flame::Query;
use Flame::Text;
sub parse_query { Flame::Text::words(shift); }
parse_query 'hi';
1;
You never imported or exported the words subroutine from the Flame::Text package. A statement use Some::Module #args is equivalent to:
BEGIN {
require Some::Module;
Some::Module->import(#args);
}
that is, the import method is called with the specified arguments. This method would usually export various symbols from one package into the calling package.
Don't write your own import, rather you can inherit one from the Exporter module. This module is configured by storing exportable symbols in the #EXPORT_OK global variable. So your code would become:
package Flame::Text;
use parent 'Exporter'; # inherit from Exporter
our #EXPORT_OK = qw/words/; # list all subs which you want to export upon request
sub words { ... }
Now, use Flame::Text 'words' will work as expected.
You need to do something like this
package Flame::Text;
use Exporter 'import'; # gives you Exporter's import() method directly
#EXPORT_OK = qw(words); # symbols to export on request
as perl doesn't export (or pollute) the namespace by default
http://perldoc.perl.org/Exporter.html
don't forget to
use strict; use warnings;
in all things perl
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
I know the title sounds funny, but I found this snippet somewhere:
my MyPackage $p1 = MyPackage->new;
What role does the name of the package serve in front of $p1?
EDIT: I'm running perl 5.10.1.
It checks for a package with the same name, and, as of now, is tied to the fields pragma which helps check for typos in field names.
For example:
package MyPackage;
use fields qw/ foo bar /;
sub new { fields::new(shift) }
Then if you try to run
use MyPackage;
my MyPackage $p1 = MyPackage->new;
print $p1->{notpresent}, "\n";
you get
No such class field "notpresent" in variable $p1 of type MyPackage at ...
From http://perldoc.perl.org/functions/my.html:
my TYPE EXPR : ATTRS
A my declares the listed variables to be local (lexically) to the enclosing block, file, or eval. If more than one value is listed, the list must be placed in parentheses.
The exact semantics and interface of TYPE and ATTRS are still evolving. TYPE is currently bound to the use of fields pragma, and attributes are handled using the attributes pragma, or starting from Perl 5.8.0 also via the Attribute::Handlers module.
In addition to use by fields, the lexical type is used by the experimental types pragma (available from CPAN).