_learning perl_, ch8, 4.I.2002, nh FUNCTIONS (subroutines) (sub) sub functionname { # technically the subroutine's name is statement1; # &functionname (with an '&') statement2; } # return value returned to caller * definitions can be anywhere in the program, usually at end * definitions are GLOBAL * variables within the subroutine are GLOBAL! (unlike C) invoking: functionname(); ======== $a = 3 + functionname(); &c. return values: the return value of a subroutine is the value of the ============= return statement or of the last expression evaluated in the subroutine. sub sum_of_a_and_b { return $a + $b; } @c = list_of_a_and_b; sub list_of_a_and_b { return ($a,$b); #@c gets ($a,$b) } arguments: can pass arguments to a subroutine ========= subroutine invocation followe by a list within parenthesis, causing the list to be automaticall assigned to a special LOCAL variable @_ for the duration of the subroutine (whose elements are called by $_: sub say { print "$_[0], $_[1]; # prints first two arguments } or, generally, sub add { foreach (@_) { # for an unspecified # of args $sum += $_; } return $sum; } -> if you want to keep arguments *private* to the subroutine, and not clobber previous verisons of other variables, use the my() operator: sub add { my($sum); # makes $sum local, different from global foreach (@_) { # $sum $sum += $_; } # also much easier to do than always } # referring to $_[0], $_[1], &c. -> if you don't explicitly give the values passed in to the @_ array, they start out as 'undef', just like any undefined varaiable. so instead, you have to do: sub bigger_than { my($n,@values) # or, instead of these two lines: ($n,@values) = @; # my($n,@values) = @_; etc.; } semiprivate variables using LOCAL: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ local() extends the subroutines' variables to hold true still within other subroutines called from the first routine whereas my() does not. def: 'local' variables are visible to functions called from === within the block in which those variables are declared. $value = "original" tellme(); {local|my}spoof(); tellme(); sub {local|my}spoof { {local|my} ($value) = "temporary"; tellme(); } sub tellme { print "current value is $value\n"; } LOCAL() MY() ------------------------------------------------------- current value is original current value is original current value is temporary current value is original current value is original current value is original because my() is thoroughly private, and does not retain value when passed to a subsubroutine. * local has no restrictions on what it can be * can even declare $_, $1, and @ARGV with local (can't with my) `-> wise to declare 'local $_;" * local variables are really global in disguise: "that is, the value of the global variable is saved and temporarily replaced with the locally delcared value." (p. 98) file-level my() variables: ========================= if you type : 'use strict' at the beginning of your program, it makes you define variables before you use them. do this with my(): use strict; my $a = 6; # with strict, can't just say $a = 6; advantages: (1) program runs slightly faster ---------- (2) catch mistakes faster (won't be able to accidentally reference a nonexistent value when you just ment to type the first one -- $aa when you meant $a)