Slide 1

Slide 1 text

PERL REFS EXPLAINED Friday, November 4, 2011

Slide 2

Slide 2 text

AGENDA References Complex Data Structures Functional Perl Refs Tips & Tricks Friday, November 4, 2011

Slide 3

Slide 3 text

THE PROBLEM Write a perl subroutine that takes two lists and returns the longer list Friday, November 4, 2011

Slide 4

Slide 4 text

WILL THIS WORK ? Write a perl subroutine that takes two lists and returns the longer list #!/usr/bin/perl use strict; use warnings; sub longer { my (@l1, @l2) = @_; return @l1 > @l2 ? @l1 : @l2; } Friday, November 4, 2011

Slide 5

Slide 5 text

THE PROBLEM Perl is linear All data passed to a sub accessed via @_ Perl has no way of knowing where a list ends 1 2 9 8 1 2 9 8 @l1 @l2 @_ Friday, November 4, 2011

Slide 6

Slide 6 text

A POSSIBLE SOLUTION Is this the best we can get !? sub longer_better { my $sz1 = shift; my @l1 = splice(@_, 0, $sz1); my $sz2 = shift; my @l2 = splice(@_, 0, $sz2); return @l1 > @l2 ? @l1 : @l2; } print longer_better(2, (2, 3), 3, (9, 8, 7)); Friday, November 4, 2011

Slide 7

Slide 7 text

LET’S DO BETTER Friday, November 4, 2011

Slide 8

Slide 8 text

THE NEED Pass complex data structures around to functions Build lists of lists, hashes of hashes Create higher level functions Friday, November 4, 2011

Slide 9

Slide 9 text

SCALARIZE IT Friday, November 4, 2011

Slide 10

Slide 10 text

REFERENCES A reference is a scalar “pointing to” something Anything can have a reference References allow us to extend the language, by treating everything as a scalar Friday, November 4, 2011

Slide 11

Slide 11 text

REFERENCES 2, 3, 5, 7, 9 @l $list_ref Friday, November 4, 2011

Slide 12

Slide 12 text

REFERENCES 2, 3, 5, 7, 9 @l $list_ref $another_ref $nums_ref Friday, November 4, 2011

Slide 13

Slide 13 text

HELLO REFS Use the \ operator to create a reference # create a list ref with \@ my $l_ref = \@l; # create a hash ref with \% my $h_ref = \%h; # create a scalar ref with \$ my $x_ref = \$x; # create a subroutine ref with \& my $f_ref = \&foo; Friday, November 4, 2011

Slide 14

Slide 14 text

DEREFERENCING Use the data type sigil to get the value Operation is called dereference # note that assignment operator # generates a copy operation my @copy = @$l_ref; my %copy = %$h_ref; my $copy = $$x_ref; my $res = &$f_ref; Friday, November 4, 2011

Slide 15

Slide 15 text

DIRECT DEREFERENCE Direct element access is performed with the arrow operator Note the different type of parens # Direct element access using # references my $first = $l_ref->[0]; my $val = $h_ref->{key}; my $result = $f_ref->('x', 'y'); Friday, November 4, 2011

Slide 16

Slide 16 text

REVIEW What is the difference between: $x->{4} $x->[4] $x[4] $$x[4] Friday, November 4, 2011

Slide 17

Slide 17 text

REVIEW What is printed ? use strict; use warnings; my @l = (2, 3, 5); my $l_ref = \@l; push @l, 10; print "@$l_ref\n"; Friday, November 4, 2011

Slide 18

Slide 18 text

ANONYMOUS REFS 2, 3, 5, 7, 9 $list_ref Friday, November 4, 2011

Slide 19

Slide 19 text

ANONYMOUS REFS Use [ ... ] to create a list and return a ref Use { ... } to create a hash and return a ref my $al_ref = [2, 3, 5]; my $ah_ref = { Adam => 'Eve', Bonnie => 'Clyde', }; Friday, November 4, 2011

Slide 20

Slide 20 text

ANONYMOUS REFS When an entity has no name - only a reference, we call that anonymous reference As long as some ref to it is still in scope, the entity won’t be deleted sub gen_colors { [qw/red blue green/] } my $colors = gen_colors; print $colors->[1], "\n"; Friday, November 4, 2011

Slide 21

Slide 21 text

WARNING It’s very easy to confuse the sigils Simple rule - sigil must appear only once: $ on the left means {...} or [...] on the right % or @ on the left means (...) on the right Friday, November 4, 2011

Slide 22

Slide 22 text

REVIEW What is printed ? Hint: watch the parens my @foo = [10, 20, 30]; push @foo, 50; print scalar @foo; Friday, November 4, 2011

Slide 23

Slide 23 text

THE REF KEYWORD Use ref to determine the type of reference at hand Can be helpful when implementing subroutine argument checks use strict; use warnings; my $coderef = sub { print "Hello World\n"; }; my $lref = [1,2,3,4]; my $href = { a => 1, b => 2 }; $coderef->(); print 'coderef is of type: ', ref $coderef; print 'lref is of type: ', ref $lref; print 'href is of type: ', ref $href; Friday, November 4, 2011

Slide 24

Slide 24 text

LAB Write a function that takes two lists and returns: sum(@first) - sum(@second) Write a function that takes a hash ref, key and value and adds the new (key, value) to the hash Friday, November 4, 2011

Slide 25

Slide 25 text

DATA STRUCTURES Friday, November 4, 2011

Slide 26

Slide 26 text

NESTED LISTS Use references to easily create nested and multi dimensional lists @l = ( 2, 3, [3, 3, 5], 8) Friday, November 4, 2011

Slide 27

Slide 27 text

EXAMPLE # Nested lists my $nested_ref = [1, 2, [3, 4, 3], [qw/a b c/]]; # prints 4 print $nested_ref->[2]->[1], "\n"; # prints b print $nested_ref->[3]->[1], "\n"; # prints 4 print scalar @$nested_ref; Friday, November 4, 2011

Slide 28

Slide 28 text

MANAGING DATA A data record is represented as a simple hash Complex values are stored as references Can create a list of hashrefs to store multiple records Friday, November 4, 2011

Slide 29

Slide 29 text

MANAGING DATA [ { 'friends' => [ { 'name' => 'Tim', 'age' => 21 }, { 'name' => 'Martha', 'age' => 22 } ], 'name' => 'Tom', 'age' => 18 }, $VAR1->[0]{'friends'}[0] ]; my $p1 = { name => 'Tom', age => 18 }; my $p2 = { name => 'Tim', age => 21 }; my $p3 = { name => 'Martha', age => 22 }; my @people = ($p1, $p2); $p1->{friends} = [$p2, $p3]; use Data::Dumper; print Dumper(\@people); Friday, November 4, 2011

Slide 30

Slide 30 text

SUB REF An array of sub ref Call a random sub from the array my $actions = [ sub { print "hello\n" }, sub { print 2 + 2 }, sub { die "Muhahaha" }, ]; $actions->[int rand(@$actions)]->(); Friday, November 4, 2011

Slide 31

Slide 31 text

LAB Create a hash with the following fields: name, id, favorite_colors (Array) Create an array of records specified as above Write a function to sort the array by id Friday, November 4, 2011

Slide 32

Slide 32 text

HIGHER ORDER PERL Friday, November 4, 2011

Slide 33

Slide 33 text

SUBROUTINE REFS A subroutine ref allows passing subroutines around We can now keep an array of subs, or hash of subs We can now use subs that take other subs as input We can even write subs that return other subs Friday, November 4, 2011

Slide 34

Slide 34 text

SUB REFS use List::Util qw/max/; sub max_value { my ($f1, $f2, $f3, $data) = @_; return max( $f1->($data), $f2->($data), $f3->($data)); } sub add_2 { $_[0] + 2 } sub mul_2 { $_[0] * 2 } sub triple { $_[0] * 3 } print max_value(\&add_2, \&mul_2, \&triple, 3); Friday, November 4, 2011

Slide 35

Slide 35 text

Anonymous subs are declared with sub keyword a sub without a name returns a reference Note the ; at the end of the assignment my $f_ref = sub { my ($x, $y) = @_; return $x + $y; }; # returns 5 $f_ref->(2, 3); Friday, November 4, 2011

Slide 36

Slide 36 text

Tips & Tricks Friday, November 4, 2011

Slide 37

Slide 37 text

REFS TIPS Shorten sub signature Input validation with ref Dispatch Table Friday, November 4, 2011

Slide 38

Slide 38 text

SUBROUTINE SIGNATURE When you have a lot of data to send to your subroutine, consider wrapping it in a hashref Best Practice: Send at most 3 arguments to subs sub print_data_bad { my ($name, $color, $age, $home, $work) = @_; } sub print_data_good { my ($name, $params) = @_; my $color = $params->{color} || "blue"; my $age = $params->{age} || 0; my $home = $params->{home}; my $work = $params->{work}; } print_data_good('James', { age => 18, home => 'Moon' }); Friday, November 4, 2011

Slide 39

Slide 39 text

INPUT VALIDATION Can use ref function to test input argument type croak on invalid argument use Carp; sub print_data_good { my ($name, $params) = @_; croak "invalid argument" if ref($params) ne 'HASH'; my $color = $params->{color} || "blue"; my $age = $params->{age} || 0; my $home = $params->{home}; my $work = $params->{work}; } print_data_good('James', { age => 18, home => 'Moon' }); Friday, November 4, 2011

Slide 40

Slide 40 text

DISPATCH TABLE A good replacement for long if-else blocks Call a function based on a hash key Code: dispatch.pl Friday, November 4, 2011

Slide 41

Slide 41 text

SUMMARY References move perl from a “scripting” language to a real programming language References allow complex data to be processed with ease using perl References form the base for Object Oriented Perl Friday, November 4, 2011

Slide 42

Slide 42 text

Q & A Friday, November 4, 2011

Slide 43

Slide 43 text

THANK YOU Ynon Perek [email protected] ynonperek.com Friday, November 4, 2011