markjugg has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I maintain the Data::FormValidator module and am interested in some feedback on the some interface updates. You don't have to be a Data::FormValidator user to have some good feedback on this, but it might help understanding what's going on.

One important constraint I have is that I need to keep backwards compatibility.

Here's a summary of what I want to do and what I've run into. Data::FormValidator allows you to construct and call validation routines that take more than one value as input, using a hash key called "params". To optimize for the common case of using values from the input hash, the current interface for passing params looks like this:

params => ['field_to_validate','other_field_to_include' ],

You have to be sure to include the name of the field you want to validate.

Recently a patch was added to make this more flexible, so that any value that was passed by reference here would be taken literally.

I've now realized this design still has some significant limitations. These include:

1. Does not work with constraint_regexp_map. It would be nice to have the logic of: "For all fields that end in _image", apply this constraint. Because you have to explicitly pass in the current field name being validated, this won't work.

2. No access to D::FV object. This would be handy in some cases, as illustrated below.

These issues came to light as I was developing Data::FormValidator::Upload , a plug-in module to providing validation for files uploaded with CGI.pm. To illustrate the interface issues, Here's an illustration of how it currently works, and a sketch of how I might like it work.

# Notice that the name of the image field has to be repeated in each c +onstraint # and the query object has to be passed in to access the "upload" rout +ine, although # this is potentially already accessible through D::FV. constraints => { image_name => [ { constraint => 'file_format', params => [\'image_name',$q], }, { constraint => 'file_max_bytes', params => [\'image_name',$q,\100], }, { constraint => 'image_max_dimensions', params => [\'image_name',$q,\200,\200], }, ], } # A possible solution: Something that looks like "param" # but has access to the field name and the D::Fv object. constraints => { image_name => [ { constraint => 'file_format', oo_params => [], }, { constraint => 'file_max_bytes', oo_params => [\100], }, { constraint => 'image_max_dimensions', oo_params => [\200,\200], }, ], }

So I could add something like "oo_params" described above, Partly I'm concerned about a name that clarifies what's going on somehow. (I although thought of "args", but it feels the same to me as "params". )

I guess the real issue from an implementation stand point is that I want to make the current field name and the D::FV object available to the routines that want them, without changing how the current ones work. Perhaps this could also be acheived by calling some funtion within the constraint that would return these bits of information.

Suggestions?

Replies are listed 'Best First'.
Re: RFC: Data::FormValidator params interface enhancement
by adrianh (Chancellor) on Apr 20, 2003 at 23:47 UTC

    How about marking the validation routine rather than the parameters, so you would have:

    constraints => {    image_name => [    {        constraint_method => 'file_format',    },    {        constraint_method => 'file_max_bytes',        params => [\100],    },    {        constraint_method => 'image_max_dimensions',        params => [\200,\200],    },    ],

    you could either add a method to D::FV that allows you to find out the name of the field whose contraints are currently being checked (which would involve rewriting the validation subroutines), or make it a convention that the first two args are always the D::FV object and the name of the field being checked.

    So:

       foo => { constraint_method => 'bar', params => \@args },

    would translate to either:

       foo => { constraint => 'bar', params => [$dfv, @args]] },

    or

       foo => { constraint => 'bar', params => [$dfv, 'foo', @args] },

    (where $dfv is the D::FV object in question)

    I'd prefer the former since you would then have a direct mapping to the Perl method calling convention:

    bar($dfv, @args); $dfv->bar(@args);

      adrianh,

      Thanks for your response. I think we may have a winner here. I think your solution could be both intuitive to a user as well as sensible to implement. I like the combination of "constraint_method" paired with a new function to get the name of the routine currently be validated.

      I hope I'll discover that I only need to add code to the new routines I'm creating and not all the existing ones.

      -mark