http://www.perlmonks.org?node_id=803124

ganeshwari has asked for the wisdom of the Perl Monks concerning the following question:

Can we strict the subroutine in perl to receive number of arguments ? Normally, we can pass any number of arguments and subroutine will have all the passed arguments in @_ variable, from that we can take how many ever arguments we need. But we need to tell explicitly to the calling place that only limited / number of arguments that we need to pass for the subroutine call. Is there any way can help it ?

Replies are listed 'Best First'.
Re: Limit number of Sub routine argument list
by zwon (Abbot) on Oct 25, 2009 at 09:16 UTC
    use Carp; ... sub mysub { croak "Too many arguments for mysub" if @_ > $limit; ... }
Re: Limit number of Sub routine argument list
by afoken (Chancellor) on Oct 25, 2009 at 09:19 UTC

    Why do you think that you need this feature?

    What keeps you from checking the size of @_ in the subroutine?

    sub iWantFourArguments { @_==4 or die "Call me with four arguments. Died"; # ... }

    Note that prototypes won't help you here, you can bypass them using &subname(...) and they aren't checked at all when subs are invoked as methods.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Limit number of Sub routine argument list
by almut (Canon) on Oct 25, 2009 at 09:28 UTC

    Maybe like this?  (You didn't say what is supposed to happen if there are more than a certain number of arguments, i.e. ignore, warn, die,... at runtime or compile-time...)

    #!/usr/bin/perl sub foo { $#_ = 3 if @_ > 3; # limit to 4 args print "$_\n" for @_; print "---\n"; } foo(1,2,3); foo(1,2,3,4); foo(1,2,3,4,5); __END__ 1 2 3 --- 1 2 3 4 --- 1 2 3 4 ---

    (obviously, what I've shown implements the 'ignore' variant)

      Or
      #!/usr/bin/perl -w use strict; use Params::Validate qw' validate_pos '; Main( @ARGV ); exit( 0 ); sub Foo { validate_pos( @_, 1, 1, 1 ); print "$_\n" for @_; print "---\n"; } sub Main { Foo(1,2,3); Foo(1,2,3,4); Foo(1,2,3,4,5); } __END__ 1 2 3 --- 1 2 3 --- 4 parameters were passed to main::Foo but 3 were expected at - line 12 main::Foo(1, 2, 3, 4) called at - line 21 main::Main() called at - line 7
Re: Limit number of Sub routine argument list
by JavaFan (Canon) on Oct 25, 2009 at 10:57 UTC
    Can we strict the subroutine in perl to receive number of arguments ?
    Runtime? Compile time? Is @a considered to be one argument, or as many arguments as @a has elements?

    Runtime is easy:

    sub foo { unless (@_ <= 4) { die "foo allows at most 4 arguments"; } ... }
    Compile time, you can do:
    sub foo (;$$$$) { ... }
    The disadvantage of the latter is that it evaluates all the arguments to the sub in scalar context, and hence there's no flattening of lists. That is,
    @bar = qw[red blue green yellow brown pink]; foo @bar;
    is not an error - it calls foo with a single argument, 6; the number of elements in @bar.
      thanks for your replies. I need to handle this in compile time only. But as Alexander told we can bypass this by calling the subroutine as &subroutine(..). Is there way to handle this ?
        But as Alexander told we can bypass this by calling the subroutine as &subroutine(..). Is there way to handle this ?
        Not on the level of Perl itself. You may be able to do something by inspecting the op-tree. Perhaps perlcritic can help you as well, but that requires a separate stage.
Re: Limit number of Sub routine argument list
by Anonymous Monk on Oct 25, 2009 at 09:09 UTC
    In the sense that anything is possible, sure.