[html-formfu] Unable to create a Callback constraint via populate()

Carl Franks fireartist at gmail.com
Wed Apr 30 16:14:22 BST 2008


2008/4/30 Michele Beltrame <mb at cattlegrid.info>:
> Hi Carl!
>
>
>  > Thanks, that's now fixed in svn trunk (r998) by switching on
>  > Storable's support for deserializing/eval-ing CODE-refs.
>
>  Great, thanks!
>
>
>  > Note that any code-ref used cannot make use of anything outside the
>  > scope of that code-ref.
>  > For example, the code-ref in the test file
>  > t/bugs/populate_element_coderef.t needs to call Test::More::ok()
>  > rather than just ok() - this is because the code is eval'ed outside of
>  > the original scope/package it originally occured in.
>
>  Is there any reason behind this design decision? I'm asking because it
>  would really be very handy to be able to pass use the CODEref as a
>  lexical closure and therefore access its context, as I used to do with
>  HTML::Widget.
>
>  That would be much useful for creating (Catalyst-related example) something
>  like:
>
>  ---------------------------------------------------------------------
>  sub populate_form {
>     my ( $self, $c ) = @_;
>
>     my $check_dupe = sub {
>         my $value = shift;
>
>         my $user = $c->model('Dbs::Users')->find($value);
>
>         return defined $user ? 0 : 1;
>     }
>
>     # Example with a constraint, but could also be a validator (which
>     # makes more sense for checking duplicate users, maybe)
>     $c->populate({
>         ......
>             constraints => [{
>                 type        => 'Callback',
>                 callback    => $check_dupe,
>                 message     => 'This username already exists',
>             }],
>         ......
>     });
>  }
>  ---------------------------------------------------------------------
>
>  Or is there another simple way to accomplish this that maybe I'm not
>  thinking of? ;-)

Unfortunately it's a side-effect of dclone(), rather than being a
design "decision" :)

The hashref argument passed to element() needs to be cloned, because
it gets butchered. If it weren't cloned, and you tried passing the
same hashref multiple times (for example, under a persistent
environment), it would break.

However, I've now changed element() so it does a shallow clone ( using
$hashref = {%$hashref} ) instead of dclone().
This avoids the immediate butchering by element(). Whether this has
any unwanted side-effects further down the line, we'll just have to
wait and see.

Carl



More information about the HTML-FormFu mailing list