Subroutines
Upcoming SlideShare
Loading in...5
×
 

Subroutines

on

  • 637 views

This is the seventh set of slightly updated slides from a Perl programming course that I held some years ago. ...

This is the seventh set of slightly updated slides from a Perl programming course that I held some years ago.
I want to share it with everyone looking for intransitive Perl-knowledge.
A table of content for all presentations can be found at i-can.eu.
The source code for the examples and the presentations in ODP format are on https://github.com/kberov/PerlProgrammingCourse

Statistics

Views

Total Views
637
Views on SlideShare
637
Embed Views
0

Actions

Likes
0
Downloads
4
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Subroutines Subroutines Presentation Transcript

  • Perl Programming Course SubroutinesKrassimir BerovI-can.eu
  • Contents1. What is a Subroutine2. Defining Subroutines3. Invoking Subroutines4. Subroutine arguments5. Retrieving data from calling subroutines Operator caller6. Return values. Operator wantarray7. Scope and Declarations
  • What is a Subroutine• Subroutine • a user-defined function • identifier for a code block • letters, digits, and underscores • cant start with a digit • optional ampersand (&) in front
  • Defining a Subroutine• sub NAME BLOCK sub NAME (PROTO) BLOCK sub NAME : ATTRS BLOCK sub NAME (PROTO) : ATTRS BLOCK • Without a BLOCK its just a forward declaration • Without a NAME, its an anonymous function declaration – return value: CODE ref See: perlfaq7/Whats a closure? • May optionally have attribute lists See: attributes, Attribute::Handlers • A subroutine may be defined anywhere in your program
  • Defining a Subroutine• sub NAME (PROTO) BLOCK • The function declaration must be visible at compile time • The prototype is in effect only when not using the & character • Method calls are not influenced by prototypes either • The intent is primarily to let you define subroutines that work like built-in functions • See:perlsub/Prototypes
  • Invoking Subroutines• Example:sub.pl sub hope; sub syntax($) { print "This is Subroutines slide " .($_[0]||1) ."n"; } syntax $ARGV[0]; #syntax();#Not enough arguments for... hope; hope(); &hope; nope(); #nope;#Bareword "nope" not allowed... sub hope { print "I hope you like Perl!n"; } sub nope { print "I am a dangerous Bareword.n" } my $code_ref = sub { print I am a closure.$/ }; print $code_ref,$/;#CODE(0x817094c) $code_ref->() or &$code_ref;
  • Subroutine arguments• @_ contains the parameters passed to the subroutine• if you call a function with two arguments, they will be stored in $_[0] and $_[1]• Avoid to use ($_[0] .. $_[n]) directly unless you want to modify the arguments.• The array @_ is a local array, but its elements are aliases for the actual scalar parameters
  • Subroutine arguments• Example: sub_args.pl use strict; use warnings; $ = $/; sub modify($) { print "The alias holding " .($_[0]++) ." will be modifyedn"; } modify($ARGV[0]); print $ARGV[0]; copy_arg($ARGV[0]); print $ARGV[0]; sub copy_arg { my ($copy) = @_; print "The copy holding " .($copy++) ." will NOT modify $ARGV[0]n"; }
  • Retrieving data from calling subroutines• caller EXPR caller Returns the context of the current subroutine call. • In scalar context, returns the callers package name if there is a caller and the undefined value otherwise. • In list context, returns ($package, $filename, $line) = caller; • In list context with EXPR, returns more... • The value of EXPR indicates how many call frames to go back before the current one.
  • Retrieving data from calling subroutines• Example:caller.pl use Data::Dumper; sub dump_stacktrace { print shift || Dumping stacktrace:; my $call_frame = 1; local $,=$/; my %i; while(($i{package}, $i{filename}, $i{line}, $i{subroutine}, $i{hasargs}, $i{wantarray}, $i{evaltext}, $i{is_require}, $i{hints}, $i{bitmask}, $i{hinthash}) = caller($call_frame++)){ print Data::Dumper->Dump( [%i],[call .($call_frame-1)] ); } }
  • Retrieving data from calling subroutines (2)• Example: caller2.pl package Calling; require caller.pl; run(@ARGV); sub run { print "run" called; OtherPackage::second(shift); } sub OtherPackage::second { print "second" called; my@a = ThirdPackage::third(@_); } sub ThirdPackage::third { print "third" called; dump_stacktrace(This is the stack trace:); }
  • Return values. Operator wantarray• Return values • (list, scalar, or void) depending on the context of the subroutine call • If you specify no return value: • returns an empty list in list context, • the undefined value in scalar context, • nothing in void context. • If you return one or more lists: • these will be flattened together
  • Return values. Operator wantarray (2)• Return values • A return statement may be used to specify a return value • The last evaluated statement becomes automatically the return value • If the last statement is a foreach or a while, the returned value is unspecified • The empty sub returns the empty list
  • Return values. Operator wantarray• Return values: return.pl #prints favorite pet or a list of all pets my @pets = qw|Goldy Amelia Jako|; print run($ARGV[0]); sub run { my $pref = shift||;#favorite or list of pets if($pref) { favorite() } else { local $,=$/; print pets() } } sub favorite { favorite:.$pets[1] } sub pets { return (all pets:, @pets) }
  • Return values. Operator wantarray• wantarray • Returns true if the context of the currently executing subroutine or eval is looking for a list value • Returns false if the context is looking for a scalar. • Returns the undefined value if the context is looking for no value (void context).
  • Return values. Operator wantarray• wantarray # prints favorite pet or a list of all pets, # or nothing depending on context my @pets = qw|Goldy Amelia Jako|; run(); sub run { if(defined $ARGV[0]) { if($ARGV[0]==1) { my $favorite = pets() } elsif($ARGV[0]==2) { my @pets = pets() } } else { pets() } } sub pets { local $,=$/ and print (all pets:, @pets) if wantarray; return if not defined wantarray; print favorite:.$pets[1] if not wantarray; }
  • Scope and Declarations• Variable scoping, private variables.• Scope declarations: my, local, our
  • Scope• What is scope? • Lexical/static scope can be defined by • the boundary of a file • any block – {} • a subroutine • an eval • using my • Global/package/dynamic scope can be defined by using sub, our and local declarations respectively
  • Declarations• my - declare and assign a local variable (lexical scoping)• our - declare and assign a package variable (lexical scoping)• local - create a temporary value for a global variable (dynamic scoping)
  • Declarations• my $var; A my declares the listed variables to be local (lexically) to the enclosing block, file, or eval.• If more than one value is listed, the list must be placed in parentheses.• a virable declared via my is private• See: perlfunc/my, perlsub/Private Variables via my() my $dog; #declare $dog lexically local my (@cats, %dogs); #declare list of variables local my $fish = "bob"; #declare $fish lexical, and init it my @things = (fish,cat); #declare @things lexical, and init it
  • Declarations• my $var; Example: my $dog = Puffy; { my $dog = Betty; print My dog is named . $dog; } print My dog is named . $dog; my ($fish, $cat, $parrot) = qw|Goldy Amelia Jako|; print $fish, $cat, $parrot; #print $lizard; #Global symbol "$lizard" requires explicit package name...
  • Declarations• our EXPR • associates a simple name with a package variable in the current package • can be used within the current scope without prefixing it with package name • can be used outside the current package by prefixing it with the package name
  • Declarations• our – Example: { package GoodDogs; print We are in package . __PACKAGE__; our $dog = Puffy; { print Our dog is named . $dog; my $dog = Betty; print My dog is named . $dog; } print My dog is named . $dog; }{#delete this line and experiment package BadDogs; print $/.We are in package . __PACKAGE__; #print Previous dog is named . $dog; print Your dog is named . $GoodDogs::dog; our $dog = Bobby; print Our dog is named . $dog; }
  • Declarations• local EXPR • modifies the listed variables to be local to the enclosing block, file, or eval • If more than one value is listed, the list must be placed in parentheses
  • Declarations• local EXPR (2) WARNING: • prefer my instead of local – its faster and safer • exceptions are: • global punctuation variables • global filehandles and formats • direct manipulation of the Perl symbol table itself • local is mostly used when the current value of a variable must be visible to called subroutines
  • Declarations• local – Example: use English; { local $^O = Win32; local $OUTPUT_RECORD_SEPARATOR = "n-----n";#$ local $OUTPUT_FIELD_SEPARATOR = : ;#$, print We run on, $OSNAME; open my $fh, $PROGRAM_NAME or die $OS_ERROR;#$0 $! local $INPUT_RECORD_SEPARATOR ; #$/ enable localized slurp mode my $content = <$fh>; close $fh; print $content; #my $^O = Solaris;#Cant use global $^O in "my"... } print We run on , $OSNAME;
  • SubroutinesQuestions?