[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