2

I'm quite new to perl and I can't seem to find any information on how one would know if a subroutine takes a parameter.

In other languages (e.g python, java, etc), it is very clear, a method/function usually looks like this:

    def my_func(arg1, arg2):
        # do something

But in perl, it's simply:

    sub my_func {
        my params = @_;
        # do something
    }

But I've seen examples where my params = @_ isn't even included, but the subroutine is called and passed an argument.

e.g

    sub my_func {
        my $self = shift;
        my $fieldstr = 'tbl'.$self->db_func.'*,';
        my $sql = "SELECT $fieldstr FROM tbl".$self->db_func.'WHERE'.$self->...;

        my $sth = $self->other_func->my_func($sql) or return undef;
    }

So I was wondering if there is some sort of guideline to know if a subroutine takes a parameter(s)?

  • Related: [Perl subroutine arguments](http://stackoverflow.com/questions/19234209/perl-subroutine-arguments) – ThisSuitIsBlackNot Oct 16 '14 at 17:38
  • Also relevant: http://perldoc.perl.org/perlsub.html#Signatures – choroba Oct 16 '14 at 17:46
  • `shift` inside a sub is the same as `shift(@_)`. – ikegami Oct 16 '14 at 18:12
  • Typically, documentation of whatever sub or method should indicate what the arguments are. (Not trying to be snarky.) – Jim Davis Oct 16 '14 at 18:26
  • Since you're going to be writing documentation *anyway* (as you mentioned in a comment on a now-deleted answer), please do your successor(s) a favor and add [POD](http://www.perlmonks.org/?node_id=252477) to the source files you examine. – ThisSuitIsBlackNot Oct 16 '14 at 18:35
  • 1
    Are you saying that you don't know Perl at all, but are required to document some Perl code? There is *no way* to know what a Perl subroutine expects in its parameter list with *reading and understanding the code*. – Borodin Oct 16 '14 at 18:40

3 Answers3

4

Please take a look at my answer to a similar question.

Perl is hyper-flexible, in that a subroutine can simply ignore excess parameters, provide defaults for missing ones, or die if the parameters aren't exactly what is expected.

Perl's author, Larry Wall, is a linguist, and the rationale behind this is that subroutines behave like imperative verbs; so just as you could say "fetch the wood", "fetch the wood from behind the shed", or "fetch the wood from behind the shed using the tractor", you can equally say

fetch($wood)
fetch($wood, $shed)
fetch($wood, $shed, $tractor)

or even

fetch($wood, {from => 'shed', using => 'tractor'})

and it is up to the subroutine to work out what is required.

Subroutine prototypes should be avoided, as they have side-effects that change the behaviour of the code in ways that aren't obvious. They are intended only for writing additional language constructs; a good example is Try::Tiny.

Community
  • 1
  • 1
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • But I need to know of a way to determine even needs a parameter. I've mentioned in one of my comments, that I'm making a system design document. So in order to accurately document each function, I would need to know while I'm looking at a specific func, if it takes a parameter. Otherwise, I'd have to keep going back to the same file and editing it each time I find that it's being called/passed an argument. –  Oct 16 '14 at 18:23
  • He's asking how to identify the parameters of a function, not how to enforce/validate them. – ikegami Oct 16 '14 at 18:23
  • @yob-v-u Again, *all* subroutines take *as many arguments* as you give it. There is nothing in the definition of a subroutine that specifies how many arguments it should be given when called, because Perl does not enforce any thing like that. Each subroutine simply receives a list, stored in the local array `@_`, of arguments that were passed on the command line. – chepner Oct 16 '14 at 18:27
  • 1
    @yob-v-u: Re *"I've mentioned in one of my comments, that I'm making a system design document"*, if that is significant to youir question then you should *edit your question* to include it. – Borodin Oct 16 '14 at 18:36
3

Arguments are passed in @_, so you'd need to look for uses of @_. For example,

  • my ($x, $y) = @_;
  • shift in a sub is the same as shift(@_)
  • $_[$i]
  • &f (but not &f()), as in sub log_warn { unshift @_, 'warn'; &log }

As a sub writer, you should use these as near the top of the sub as possible to make them obvious. The last two are usually used as optimizations or to have by-reference parameters.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • You said I need to look for uses of @_. But @_ isn't included in the function –  Oct 16 '14 at 18:24
  • 1
    Not all uses of `@_` require `@_` to be present. Read the rest of my answer, where I list three other ways `@_` can be used. – ikegami Oct 16 '14 at 18:28
1

The parameters for a subroutine call are contained in the array @_.

Two important functions for array manipulation are shift and pop. Suppose you have a list (1, 2, 3, 4). shift removes a value from the left side of the list and returns it.

my @list = ( 1, 2, 3, 4 );

my $value = shift @list;

print "$value\n";    # will print "1"
print "@list\n";     # will print "2 3 4"

pop does the same thing from the right side instead of the left:

my @list = ( 1, 2, 3, 4 );

my $value = pop @list;

print "$value\n";    # will print "4"
print "@list\n";     # will print "1 2 3"

When used inside a subroutine, pop and shift will use the @_ array by default:

some_function( 'James', 99 );    #these 2 arguments will be passed to the function in "@_"

sub some_function {
    my $name = shift;             #remove 'James' from list @_ and store it in $name
    my $age  = shift;             #remove 99 from list @_ and store it in $age
    print "Your name is $name and your age is $age\n";
}
Miller
  • 34,962
  • 4
  • 39
  • 60
Shawn Darichuk
  • 380
  • 4
  • 9
  • Can you please restate your question at the top of your examples? It's unclear what you're asking as it's written. – Jason D Oct 16 '14 at 21:50
  • @JasonD Nothing is being asked because this is an answer, not a question. – ThisSuitIsBlackNot Oct 16 '14 at 23:12
  • 2
    Please don't call functions with the `&` (see [this question](http://stackoverflow.com/questions/1347396/when-should-i-use-the-to-call-a-perl-subroutine) or [this answer](http://stackoverflow.com/a/21908568/1137055)) – dgw Oct 17 '14 at 10:59