in reply to How to export un-exist subroutines

Here's a metaprogramming solution... Instead of directly added regexps to the hash, we use a helper sub add_regexp to do it. add_regexp also does a little housework, including creating a sub for us (so there's no longer any need to use AUTOLOAD), and adding the name of that sub to @EXPORT_OK.

#!/usr/bin/env perl use strict; use warnings; BEGIN { package String; use Carp; our @ISA = "Exporter"; $INC{"String.pm"} = __FILE__; { my %reg; sub get_regexp { $reg{$_[1]} } sub has_regexp { exists $reg{$_[1]} } sub add_regexp { my $class = shift; my ($name, $re) = @_; croak "Already exists: $_[0]" if $class->has_regexp($name) +; $reg{$name} = $re; no strict "refs"; *{"is_$name"} = sub { !!($_[0] =~ $re) }; push our @EXPORT_OK, "is_$name"; } } __PACKAGE__->add_regexp(Url => qr[^http:]); __PACKAGE__->add_regexp(SecureUrl => qr[^https:]); }; use String qw(is_SecureUrl); print is_SecureUrl("https://github.com/"), "\n";

Or, because I like to pimp Type::Tiny...

#!/usr/bin/env perl use strict; use warnings; BEGIN { package String; use Type::Library -base; use Type::Utils; use Types::Standard qw(StrMatch); $INC{"String.pm"} = __FILE__; declare "Url", as StrMatch[qr(^http:)]; declare "SecureUrl", as StrMatch[qr(^https:)]; }; use String -all; print is_SecureUrl("https://github.com/"), "\n"; assert_SecureUrl("http://evil.com/");

In the spirit of full disclosure, I'll point out that I've changed your regexps slightly because Type::Tiny seems to have a few bugs compiling regexps containing slashes. I'll need to find a fix for that. :-/

Update: fixed in repo.

package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Replies are listed 'Best First'.
Re^2: How to export un-exist subroutines
by ryo0ka (Novice) on May 26, 2013 at 20:21 UTC
    Thank you guys, I just figured out the way after long trial with myself from when I post this topic to right now without any break:
    foreach (keys %$reg) { no strict 'refs'; my $regkey = $_ or next; my $regval = $reg->{$regkey} or next; my $sub = sub { return 1 if shift =~ /$regval/; }; *{'is_'.$regkey} = $sub; } our @EXPORT = do { no strict 'refs'; my @list; foreach (keys %Str::) { eval {my $sub = *$_{CODE};}; push @list, $_ if !$@; } @list; };
    I did not need AUTOLOAD at all. Thank you again, I'm going to read your answers from now!