Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Perl References Explained

ynonperek
November 03, 2011

Perl References Explained

ynonperek

November 03, 2011
Tweet

More Decks by ynonperek

Other Decks in Programming

Transcript

  1. THE PROBLEM Write a perl subroutine that takes two lists

    and returns the longer list Friday, November 4, 2011
  2. 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
  3. 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
  4. 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
  5. THE NEED Pass complex data structures around to functions Build

    lists of lists, hashes of hashes Create higher level functions Friday, November 4, 2011
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. REVIEW What is printed ? Hint: watch the parens my

    @foo = [10, 20, 30]; push @foo, 50; print scalar @foo; Friday, November 4, 2011
  15. 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
  16. 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
  17. NESTED LISTS Use references to easily create nested and multi

    dimensional lists @l = ( 2, 3, [3, 3, 5], 8) Friday, November 4, 2011
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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