I have a regex which I wish to export from my module, the code is as follows :
package regExport;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw(re);
my re = /.../; # my regex is here
and its being imported here
use regExport qw(re);
my @li = ("man", "qwrt", "mnbv", "azx", "aeiou");
foreach my $st (@li) {
$li =~ a/b/; # I wish to test my regex on each of these strings
}
Anyone has any ideas how I would go about doing that. I'm feeling fairly confused on how to go about doing that.
CodePudding user response:
The simplest take, but which is not the best (see below), would be to make a variable with a pattern. Best use qr operator for that, and then can export the variable
package RegExport;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw($re_pattern);
our $re_pattern = qr/(\w )/i; # capture a "word" case-insensitive
1;
Note that I've capitalized the package name, per the usual Perl convention of Pascal case. (Then the file name need follow that and be RegExport.pm
.)
This is then used as
use warnings;
use strict;
use feature 'say';
use FindBin qw($RealBin);
use lib $RealBin;
use RegExport qw($re_pattern);
my $text = q(Some text with a bunch of words. In sentences.);
while ($text =~ /$re_pattern/g) {
say "Word: $1";
}
Here I expect RegExport.pm
to be in the same directory as the program. The use of $RealBin is a good way to add to the search path for included libraries a directory relative to where the program itself is (in this case, the program's very directory).
If you really want to go with a variable like this (but read on!) then there is no need to export it from its package, but can use its fully qualified name in the caller
use RegExport;
... $RegExport::re_pattern ...
This is what is sometimes done in libraries for various settings.
However, the documentation has a bit to say about this, in a section What not to export
Do not export variable names.
@EXPORT_OK = qw($svar @avar %hvar); # DON'T!
Exporting variables is not a good idea. They can change under the hood, provoking horrible effects at-a-distance that are too hard to track and to fix. Trust me: they are not worth it.
This good advice is occasionally violated in libraries, to a good effect; an example is $RealBin
used above. But if you have no overriding reasons for that then better follow it -- and use a function to return the value
package RegExport;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT_OK = qw(get_pattern);
sub get_pattern {
my @specs = @_; # any input on how to form the pattern
my $re_pattern = qr{...};
return $re_pattern;
}
1;
and now you use it as
use RegExport qw(get_pattern);
my $re = get_pattern(); # or pass extra rules for how to form it
and use $re
in a regex as a ready pattern.
Now both the users of this code and the future code maintainers are happy.
CodePudding user response:
You were close. There were just a few problems with your code:
- Variables you want to export to another package (i.e.
main
) need to be declared as package variables (withour
) rather than lexical variables (withmy
). - You're calling the match operator (
/ ... /
) rather than declaring and creating a regex. You needqr/ ... /
instead. - Although you loaded
Exporter
, you also need to make your class a subclass in order to useimport()
. - Your package needs to return a true value at the end.
So I have this in the module:
package RegExport;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($re);
our $re = qr/[aeiou]/; # my regex is here
1;
And this in the test program:
use lib '.';
use feature 'say';
use RegExport;
my @li = ("man", "qwrt", "mnbv", "azx", "aeiou");
foreach my $st (@li) {
if ($st =~ /$re/) {
say "Match: $st";
} else {
say "No match: $st";
}
}
Note that I've changed the name of your package to RegExport
. It's a tradition in Perl that standard user-defined modules start with a capital letter.