Assign method call to hash value?

Sam Kington sam at illuminated.co.uk
Tue Jan 29 03:39:03 GMT 2013


On 29 Jan 2013, at 01:45, gvim <gvimrc at gmail.com> wrote:
I have a form validation sub thus:
> 
> sub val {
>  my $params = shift;
>  my $r = Data::FormValidator->check($params, \%register);
>  my $passed = $r->success && !$r->has_unknown;
>  my $valid = $r->valid;
>  my $missing = $r->missing;
>  my $invalid = $r->invalid;
>  my $unknown = $r->unknown;
>  return { passed => $passed, valid => $valid, missing => $missing, invalid => $invalid, unknown => $unknown };
> }
> 
> It works but is it possible to call $r->method directly when assigning a hash value, which is still a scalar context? I tried this:
> 
>  return { passed => $passed, valid => $r->valid, missing => $r->missing, invalid => $r->invalid, unknown => $r->unknown };
> 
> ... but didn't get the same result. Adding $r->method() didn't make any difference, nor did curly-quoting: {$r->method()}.

As Mike mentioned, you almost certainly want to say { ... valid => scalar $r->valid, ... } instead; checking the documentation for Data::FormValidator and seeing what it says the missing, valid and unknown methods return in list context vs scalar context, might help.

https://metacpan.org/module/Data::FormValidator#check- says "It returns its results as a Data::FormValidator::Results object" and e.g. the documentation for the missing method says

> In an array context it returns the list of fields which are missing. In a scalar context, it returns an array reference to the list of missing fields.
> 
> If called with an argument, it returns true if that field is missing, undef otherwise.

So you could replace the last 5 lines of your sub with e.g.

    return {
        passed  => $passed,
        valid   => scalar $r->valid,
        missing => scalar $r->missing,
        invalid => scalar $r->invalid,
        unknown => scalar $r->unknown,
    };

Once written like that, it becomes clear that there's some repetition going on.

There's two things you could do at this point. Depending on what you need to do later on, you might just say

    return { passed => $passed, form_validator_results => $r };

and let the calling code fish out the stuff it needs. This might be mildly more efficient if it ever turns out that calling the valid, missing, invalid and unknown methods ahead of time was wasteful if the calling code didn't need that information. Or it might not; benchmark your code, if performance is a problem, with Devel::NYTProf, and then decide.

Alternatively, say e.g.

    return {
        passed => ($r->success && !$r->has_unknown),
        map { $_ => scalar $r->$_ } qw(valid missing invalid unknown)
    };

(and you can get rid of the $passed variable earlier) to make this a simple transformation.

I forget when the use of variables as method names - for the $r->$_ bit - was introduced; it was probably perl 5.6.0, but it might be as late as 5.8.0. Either way, it should be safe for all but paleolithic environments.

Sam
-- 
Website: http://www.illuminated.co.uk/




More information about the london.pm mailing list