Taking a survey of the various data validation pages out there, they largely suffer from a duplication of effort of providing and interfacing to common regular expressions. Data::FormValidator, which I maintain, also has this problem. I would like to address this by interfacing D::FV with the excellent Regexp::Common package.

Strictly speaking, no glue code is necessary, because D::FV already has support for using your own regular expressions (which could be provided by Regexp::Common).

Still, some glue code could add some value in some important ways. D::FV allows you to globally turn on data untainting. R::C generally supports this as well, but with a different syntax. Also, if a constraint has a name, it's easier to use later when defining error messages for each constraint.

SO, with that background, here's the bit of glue code I'm playing with but can't get to work. What's supposed to happen is this: When a routine named: RE_net_IPv4 is requested, the following subroutine will created automatically:

sub match_RE_net_IPv4 { my $val = shift; no strict 'refs'; my $re = &RE_net_IPv4(-keep); return ($val =~ $re) ? $1 : undef; };

Initially I thought this was a case for AUTOLOAD, but the way validator_packages works in D::FV is that the symbol table is scanned for all routines with names beginning with "match_", and they are imported into the current name space.

This seems like it will be somewhat inefficient for this case, because it seems fake "match_" routines will need to be made for all Regexp::Common routines before one is ever called!

Still, I tried to do this by creating a BEGIN block that would create the @EXPORT array on the fly. Here's the code I'm working with:

package Data::FormValidator::Constraints::Common; use 5.005; use strict; require Exporter; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @ISA = qw(Exporter); $VERSION = '0.01'; BEGIN { @EXPORT = &_build_exports_from_regexp_common; use Symbol; use Regexp::Common 'RE_ALL'; sub _build_exports_from_regexp_common { my @exports; my $package_ref = qualify_to_ref('Regexp::Common::'); my @subs = grep(/^RE_/, keys(%{*{$package_ref}})); foreach my $sub (@subs) { my $dfv_name = 'match_'.$sub; print $dfv_name; *$dfv_name = sub { my $val = shift; no strict 'refs'; my $re = &$sub(-keep); return ($val =~ $re) ? $1 : undef; }; push @exports, '&'.$dfv_name; } return @exports; } } 1;

And here's a test case to test it:

# Integration with Regexp::Common; use Test::More tests => 3; use Data::FormValidator; my %FORM = ( bad_ip => 'oops', good_ip => '127.0.0.1', ); my $results; eval { $results = Data::FormValidator->check(\%FORM, { required => [qw/good_ip bad_ip/], validator_packages => 'Data::FormValidator::Constraints::Commo +n', constraint_regexp_map => { '/_ip$/' => 'RE_net_IPv4', } }); }; warn $@ unless ok((not $@), 'runtime errors'); ok($results->('valid')->{good_ip}, 'good ip'); ok($results->('invalid')->{bad_ip}, 'bad ip');

Thanks for you help! If we can get this working well, I'll give up on adding new REs to D::FV and just add them to Regexp::Common instead. Even if something like this can't work, I think I'll better document how to use Regexp::Common RE's with Data::FormValidator.

Mark


In reply to Integrating Data::FormValidator with RegExp using symbol table manipulation by markjugg

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.