in reply to RFC named parameter syntactic sugar

I'd prefer more people used the plain my %p = @_ because then its just a step to the left, you can say use Params::Validate; ... my %p = validate( @_, ... ). It makes adding proper argument handling code /so/ easy.

Replies are listed 'Best First'.
Re^2: RFC named parameter syntactic sugar
by snowhare (Friar) on Oct 19, 2005 at 14:10 UTC

    Params::Validate has too many features, (I know that sounds odd, but read on). It is also slow.

    Too Many Features?

    Yah. In trying to solve the generalized problem of parameter validation (which makes it darn useful - but only in specialized situations), it makes the simple cases complex. This is precisely the problem that my idea of adding some syntactic sugar proposes to address.

      I wasn't aware til you posted that there was a validate_with() function. Usually, Params::Validate is as concise as you said you desired. I've also never desired to have case-insensitive named parameters. I suppose that might be desireable. It looks like you'd want to have used the Params::Validate::validate_options() function to set that sort of policy for your package if that that's really common. Then it looks like you can go back to the normal, concise calling form.

      So... my experience is that if you want simple cases, that's simple to use. I've wanted slightly more complex things like named validation for my parameters - then I've just made named constants for those.

      # Restrict row ids to potential or all valid IDs # -1 1..inf use constant ROW_ID => { regex => qr/^$RE{num}{int}$/, callbacks => { valid => sub { local $_ = shif +t; $_ == -1 or $_ >= 1 +} } }; # Restrict row ids to things that are actually valid. # 1 .. inf use constant VALID_ROW_ID => { regex => qr/^$RE{num}{int}$/, callbacks => { valid => sub { local $_ += shift; defined() + && $_ >= 1 } } }; sub example_method { my $self = shift; my %p = validate_pos( @_, { handle => 1, thing => 1, something_else => VALID_ROW_ID } ); ... }
      The mistake Params::Validate makes is that it doesn't allow you to create what your simple case is. There should be a set of import parameters that specify exactly what the default handling for validate() should be, thus allowing you to customize it on a per-file basis. Or, allow the spec to be read from a datastore (such as a config file or files), allowing it to be global for a project. Oh, and that customization has to allow me to set callbacks when and where I need them, for custom validation and error-handling. And I have to be able to override the config file(s) in the use line.

      THAT would be the featureset that would get me to use it. Otherwise, it's just too much trouble for very little gain.


      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

        What, this doesn't cover it?

        use Params::Validate; Params::Validate::validate_options( normalize_keys => sub { map { local $_ = uc; s/^-//; $_ } @_ } );
        The mistake Params::Validate makes is that it doesn't allow you to create what your simple case is.

        That's not quite true. There is the validation_options function, which sets per-package defaults.

        Params::Validate::validation_options( normalize_keys => sub { $_[0] =~ s/^-//; lc $_[0] } );

        You can also define parameter specs up front and re-use them. (Or put them in a config file/module for reuse across an app.)

        my %specs_for = ( foo => # specify a type { type => ARRAYREF }, bar => # specify an interface { can => [ 'print', 'flush', 'frobnicate' ] }, baz => { type => SCALAR, # a scalar ... # ... that is a plain integer ... regex => qr/^\d+$/, callbacks => { # ... and smaller than 90 'less than 90' => sub { shift() < 90 }, }, ); sub wibble { my %args = validate( @_, { foo => $specs_for{foo}, bar => $specs_for{baz}, }); # ... }

        So with very little up-front work, you can create re-usable parameter validation specs with a preset default case.

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.