Home > Blockchain >  how to export a regex in module and how to use it to test something
how to export a regex in module and how to use it to test something

Time:11-06

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:

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 (with our) rather than lexical variables (with my).
  • You're calling the match operator (/ ... /) rather than declaring and creating a regex. You need qr/ ... / instead.
  • Although you loaded Exporter, you also need to make your class a subclass in order to use import().
  • 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.

CodePudding user response:

The simplest take, but which is not the best, would be to make a variable with a pattern, best by qr operator and export that

package RegExport;

use strict;
use warnings;

use Exporter qw(import);
our @EXPORT_OK = qw($re);

my $re = qr{pattern};

1;

Note that I've capitalized the package name, per the usual convention of Pascal case. (Then the file name need follow that and be RegExport.pm.)

This is then used as

use RegExport qw($re);

and you can use $re in patterns. If you really want to go with a variable (but read on!) then youo don't even 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 very good advice is ocassionally violated in libraries, to a good effect. But if you have no overriding reasons for it better follow it -- and use a function to return the value instead.

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 maintainers are happy. And so is the documentation.

  • Related