####################################################### # # display-notes related to Intro to Perl, Class 4 # ####################################################### # last modified: 4-18-03, post-class # today's topic - intro to subroutines (ref: "Learning Perl", ch. 4) #------------------------------------------------------------- subroutines * or, user-defined functions; * you already know that Perl provides the user with a number of functions --- well, users can write their own, too! * FIRST: pick a nice, descriptive name for it; * (letters, digits, and underscores, BUT can't start with a digit --- the usual!) * say, my_first_subroutine * SECOND: put sub in front of it: sub my_first_subroutine * THIRD: put a set of curly braces after it, containing its BODY --- what is to be done whenever someone asks to run this subroutine; * GOOD STYLE (for ANY programming language... even Perl!): * THOU SHALT INDENT THE BODY OF SUBROUTINES - enough said; sub my_first_subroutine { # actions you want done by my_first_subroutine } * how about: sub my_first_subroutine { print "**************************\n"; print " MY FIRST PERL SUBROUTINE\n"; print "**************************\n"; } * FOURTH: where can you put this? * Anywhere in a file that you want --- it doesn't even have to be before it is first called; * (can put at the beginning, at the end, etc.) # see class4_01_subroutine1 * FIFTH: how can you now CALL this subroutine? * notice: if I create this, put it in a perl script, run the script --- nothing happens; * you have to CALL a subroutine for it to be done (also called: invoking it, running it, executing it) * one common way: put an ampersand in front of its name, now it is a Perl expression in its own right; * for THIS subroutine, whether you put () after its name or not is your choice; &my_first_subroutine; &my_first_subroutine(); # see class4_02_subroutine2 * but, usually, you shouldn't "mix" calls and subroutine definitions like I did in class4_02_subroutine2; * decide if you want to put all your subroutines first (and then your script actions), or all your script actions first (and then your subroutines); * in Perl, either option should work; #-------------------------------------------------------------------- global variables * so, consider: class4_03_greeter1 sub greeter { $cust_num += 1; print "\n***** Welcome to Perl-mart! *****\n"; print "Hello, you are customer #$cust_num today!\n"; print "*********************************\n\n"; } # call greeter several times, see what happens &greeter; &greeter(); # "regular" Perl variables are global --- I can see $cust_num here! print "\$cust_num: $cust_num\n"; $cust_num = 53; print "changed \$cust_num to: $cust_num\n"; # ...and so can greeter: &greeter(); #----------------------------------------------------------------------- subroutines can RETURN values * both subroutines so far just printed a message to the screen; * obviously, many of Perl's builtin function return a useful value; sort @my_list; # returns a list with @my_list's elements # in sorted order keys %my_hash; # returns a list of the keys in %my_hash * our subroutines can return values, too; * actually... ALL Perl functions return SOMETHING... * ...although not all have a *useful* return value... * how can this be? quite simple: * the last calculation performed in a function is also its return value! * how come we didn't notice this with my_first_subroutine and greeter? * because we called them in a "void context" --- in such a way that we didn't use the value returned; * (which you can also do whenever you wish, and we do, frequently!) * if print succeeds, for example, it returns a 1: # see class4_04_return1 $val = print "Hello!\n"; print "print returned: $val\n"; * so, notice that since both my_first_subroutine and greeter end with a print statement, they both return 1 when called! # see class4_05_return2 ***** * if you want to return a value that ISN'T the result of another function call --- just type that value as an expression; ***** # see class4_06_silly1 sub silly { print "this is a silly subroutine\n"; 13; } $val = &silly(); print "silly returned: $val\n"; ***** * note that the value of the last statement EVALUATED is what is returned! ***** # see class4_07_iffy1 sub flip_flop { if ($prev_val == 0) { $prev_val = 1; "yes"; } else { $prev_val = 0; "no"; } } print &flip_flop(), "\n"; print &flip_flop, "\n"; print &flip_flop, "\n"; print &flip_flop(), "\n"; #---------------------------------------------------------------------- arguments * you can pass values to a function, too; * if values follow a function call, they are stored by Perl in a special list, @_ * function can then use these ($_[0], scalar @_, etc.) as it wishes; # see class4_08_args1 * by the way ... @_ is LOCAL to the subroutine; * (every subroutine call gets its own, private @_) #------------------------------------------------------------------------ lexical variables (my variables) * ...because you'd like to make sure a subroutine you copy into a new script doesn't "step on" any variables in that new script! * if write: my($var1, $var2, $var3); # whatever names you like! * ...then those variables are lexical variables --- lexically scoped! * they only have meaning inside the block they are declared in! (inside the { }'s they are declared inside!) * such as a subroutine body; * or even a loop, if statement, etc.! * so if put inside a subroutine --- that subroutine cannot accidentally change a variable used "outside" of it with the same name; * the lexical variables cannot be changed outside the subroutine --- * the lexical variables cannot change things outside the subroutine; * see class4_09_my1 --- note a possible "downside" to lexical variables: you're getting a "new" version of the variable each time you run the function! (if need "old" value --- oops, gotta get it another way!) * see class4_10_my2, for a more well-behaved example of lexical variables ***** * a GOOD IDEA: to NAME a subroutine's parameters: ***** * when you expect exactly 2 parameters... my($param1, $param2) = @_; * when you expect a list of indeterminate size... my(@vals_to_add) = @_; * see class4_11_my3 #------------------------------------------------------------------------- use strict * a pragma: a hint to the compiler! * if put: use strict; ...at the top of a program or block, it'll ask compiler to look for "good programming practice", and complain if you break certain programming rules that Perl permits... #------------------------------------------------------------------- return * use it to immediately return a value from a subroutine return 3; return; # returns undef in a scalar context, # an empty list in a list context * some like to always use it, to make it clearer what a subroutine is returning; * see class4_12_return1 #------------------------------------------------------------------ omitting the & * yes, sometimes you can --- see "Learning Perl: pp. 70-71 # end of 180class4_notes.txt