in reply to Re^3: Adding attributes to values?
in thread Adding attributes to values?

Yes that is one possible solution to the problem and one that is used by one of the modules that are alread on CPAN. It does however have some problems.

  1. Makes it possible that some hard to find bugs are introduced. For instance a function that takes a list of elements and processes them in someway. If that list contains just one item and that item is a hash ref, the item is interpreted as a named argument which is not what is intended. This can give some strange behaviour and the bug can be hard to track down for the module user.
  2. It creates a special case that can be somewhat un-intuitive for people using the module to create subroutine signatures.

Replies are listed 'Best First'.
Re^5: Adding attributes to values?
by rminner (Chaplain) on Oct 21, 2007 at 11:00 UTC
    In that case you might simply pass all named args inside a hash_ref and all positional args inside an array reference. Downside of all this is of course an extreme amount of diffrently shaped brackets getting used ...
    sub get_args { if (scalar(@_) == 1) { if (ref($_[0]) eq 'HASH') { return "got named args!\n"; } elsif (ref($_[0]) eq 'ARRAY') { return "got positional args\n"; } else { die "argument wasn't a hash or array reference!\n"; } } else { die "got more than one arg!\n"; } } sub named_or_positional { print get_args(@_); } named_or_positional({foo => 'avalue' , bar => ['a', 'b']}); named_or_positional(['whatever' , 'we', 'are', 'passing']); named_or_positional('whatever' , 'we', 'are', 'passing');

    Then you would have to check whether there is a single hash_ref or a single array_ref for determining whether it's positional or named. Any other case than a single hash or array ref would have to be considered a error.

    If you don't mind the additional overhead of square/curled brackets, then it would allow you simple differentiation of named an positional args.

      That was a good idea. Thanks!

      I think that the syntactical overhead would be acceptable, I just have to put some more thought into it to see if there is anything I am missing.

      Update: After giving it a bit more thought I think I will try a different approach. The extra square brackets does not conform with how people expect argument passing to be performed in Perl and some might therefore find it confusing. I will instead try an approach where the named arguments has must contain a special key marking it as an named arguments hash. Like this:

      my_func( { key => 'value', ..... $NAMED_ARGS => '' } );

      I think that might be a better solution since people can pass parameters just like they normally would, but get the option of passing them by name if they are inclinded to do so.