Chapter 11. Subroutines
Now it’s time for more sophisticated subroutines. You were introduced
to them in Chapter 5 but you only saw enough to
support the upcoming chapters. Now that you’ve seen Arrays and Hashes, there’s much more you can do with
subroutine signatures.
A Basic Subroutine
When you run a subroutine you get some sort of result: the last evaluated
expression. That’s the return
value. This sets basic routines apart from the simpler Blocks you saw in Chapter 5. A Routine knows how to send a value back
to the code that called it. This subroutine returns a different Str if the argument is odd or
even:
sub odd-or-even {
if ( @_[0] %% 2 ) { 'Even' }
else { 'Odd' }
}
odd-or-even( 2 ); # Even
odd-or-even( 137 ); # OddWithout a signature the arguments show up in @_. Each subroutine
has its own version of that variable so it doesn’t conflict with any other
subroutine’s @_. This code calls one
subroutine that calls another. top-call
shows its @_ before and after show-args:
top-call( <Hamadryas perlicus> );
sub show-args { say @_ }
sub top-call {
put "Top: @_[]";
show-args( <a b c> );
put "Top: @_[]";
}Even though both use @_ they are
separate. The @_ in top-call isn’t disturbed by show-args:
Top: Hamadryas perlicus [a b c] Top: Hamadryas perlicus
The subroutine definition is lexically scoped. If you need it for only part of the code
you can hide it in a Block. Outside the Block that subroutine is not
visible:
{ put odd-or-even( 137 ); sub odd-or-even { ... } # only defined in this block ...