際際滷

際際滷Share a Scribd company logo
Program in Perl Style    Reference




             David Young
         yangboh@cn.ibm.com
              Feb. 2011
Program in Perl Style         Reference

Reference  the awesome reference
Program in Perl Style                                   Reference

What can we do with reference?
  Dispatch table
  Higher order functions




       In computer science, a dispatch table is a table of pointers to functions or
       methods. Use of such a table is a common technique when implementing
       late binding in object-oriented programming.
Program in Perl Style                      Reference

Dispatch table
# define your functions     # Push them   into hash table
                            %dispatch =   {
sub hellow {                   hellow   => &hellow,
                               foo      => $foo,
    print hellow world;
                               bar =>   sub {
}                                           print bar foon;
                                              },
                            }

$foo = sub {

    print foo world;

}




                                          To be continued ...
Program in Perl Style                      Reference

Dispatch table - continued
  # dispatch tasks from your hash table
  $a = hellow;
  &${dispatch->{$a}}();
  # hellow world
                                 # This is your hash table

  $rb = $dispatch->{foo};      %dispatch =   {
  &$rb();                           hellow   => &hellow,
                                    foo      => $foo,
  # foo world                       bar =>   sub {
                                                 print bar foon;
                                                   },
  $rc = $dispatch->{bar};      }

  &$rc;
  # bar foo
Program in Perl Style                                  Reference

Reference  the awesome reference
  Dispatch table
  Higher order functions




   In mathematics and computer science, higher-order functions, functional forms, or
   functionals are functions which do at least one of the following:

     * take one or more functions as an input
     * output a function.
Program in Perl Style                        Reference

Higher Order Functions
sub category_defect {
    Local $_;           # just for a good habit
    my ( $column ) = @_;
    return sub {        # return a function instead a value
                my ( $condition, $line ) = @_;
                return $$line[ $column ] eq $condition ;
    }
}
Program in Perl Style                          Reference

Higher Order Functions
sub defect_by_category {
    local $_;
    my ($column, $col_value) = @_;
    my $category = &category_defect( $column ); # which return
    return sub {                                  # a function
                my (@result);
                my ($defect) = @_;
                return $defect       # invoke previous function
                      if &$category ($col_value, $defect) ;
    }
}
Program in Perl Style                       Reference

Higher Order Functions
sub defects_factory {
    local $_;
    my ($defect, @results);      # accept function as param
    my ($conditions, $defects ) = @_;
    foreach $defect ( @$defects ) {
    push @results, $defect if &$conditions ( $defect );
    }
    return @results;
}
Program in Perl Style                               Reference

Higher Order Functions
# $severity_1 holds a function reference, not a ordinary data

$severity_1 = &defect_by_category( SEVERITY, "1" );

$severity_2 = &defect_by_category( SEVERITY, "2" );

$severity_3 = &defect_by_category( SEVERITY, "3" );

$severity_4 = &defect_by_category( SEVERITY, "4" );



# transfer a function reference as parameter

@severity_1 = &defects_factory( $severity_1    , [ @defects ] );

@severity_2 = &defects_factory( $severity_2    , [ @defects ] );

@severity_3 = &defects_factory( $severity_3    , [ @defects ] );

@severity_4 = &defects_factory( $severity_4    , [ @defects ] );
Program in Perl Style Typeglobs

Typeglob is complex and dangures
Always be careful!!!
Program in Perl Style Typeglobs

Typeglobs and symble table
 You'd better to read Camel book very carefully
 before start to using it.
 $spud   = "Wow!";

 @spud   = ("idaho", "russet");

 *potato = *spud;    # Alias potato to spud using typeglob assignment

 print "$potaton"; # prints "Wow!"

 print @potato, "n"; # prints "idaho russet"
Program in Perl Style Typeglobs

It is NOT the pointer you would expect in C
although they look similar literally
 $b = 10;

 {

     local *b;   # Save *b's values

     *b = *a;    # Alias b to a

     $b = 20;    # Same as modifying $a instead

 }               # *b restored at end of block

 print $a;       # prints "20"

 print $b;       # prints "10"
Program in Perl Style Typeglobs

Efficient parameter passing
  @array = (10,20);

  DoubleEachEntry(*array); # @array and @copy are identical.

  print "@array n"; # prints 20 40



  sub DoubleEachEntry {

      # $_[0] contains *array

      local *copy = shift;   # Create a local alias

      foreach $element (@copy) {

          $element *= 2;

      }

  }
Program in Perl Style Typeglobs

 Passing Filehandles to Subroutines
   Filehandle can not be passed to subroutines as scalars
   The only way to it is through typeglobs


   open (F, "/tmp/sesame") || die $!;
   read_and_print(*F);


   sub read_and_print {      # Filehandle G
       local (*G) = @_;      # is the same as filehandle F
       while (<G>) { print; }
   }
Program in Perl Style Typeglobs

Typeglobs are not always so explicitely
  cat test.pl
  #!/usr/bin/perl                          Be very careful!!!
  $foo = 123;
                                     Implicit typeglobs will make
  $bar = 321;
                                     your code very hard to
  $ra = "foo";
  print "$ra = $$ra n";                   understand
  while ($rb = <STDIN>) {
      chomp($rb);
      print "$rb = $$rb n";
  }                            bash-4.1$ echo "bar" | perl test2.pl
                               foo = 123
                               bar = 321
Program in Perl Style Typeglobs

But anyway ---- It's powerful!!!
Program in Perl Style Typeglobs

You can even build dispatch table from a plain file
cat a.cfg                    while ($a = <>) {

h say_hellow_to_a_friend         chomp($a);

                                 ($key, $func) = split  , $a;
a accept_an_invitation
                                 $disptch{$key} = $func;
c confirm_an_invition
                             }
e send_email_to_a_friend
r refuse_an_invitation       sub command {

                             my ($cmd, arg) = @_;

Suppose you have functions   $rcmd = $disptch->{$cmd};

in above names               &$rcmd($arg) if defined &$rcmd;

                             }


                             &command("h", Tom);
Program in Perl Style

Say good-bye to your endless ...
switch ...
case ...
if elsif ...
etc.
So think again why there is no 'switch',
  'case' ... in Perl?
Maybe you don't actually need it.

More Related Content

Programming in perl style

  • 1. Program in Perl Style Reference David Young yangboh@cn.ibm.com Feb. 2011
  • 2. Program in Perl Style Reference Reference the awesome reference
  • 3. Program in Perl Style Reference What can we do with reference? Dispatch table Higher order functions In computer science, a dispatch table is a table of pointers to functions or methods. Use of such a table is a common technique when implementing late binding in object-oriented programming.
  • 4. Program in Perl Style Reference Dispatch table # define your functions # Push them into hash table %dispatch = { sub hellow { hellow => &hellow, foo => $foo, print hellow world; bar => sub { } print bar foon; }, } $foo = sub { print foo world; } To be continued ...
  • 5. Program in Perl Style Reference Dispatch table - continued # dispatch tasks from your hash table $a = hellow; &${dispatch->{$a}}(); # hellow world # This is your hash table $rb = $dispatch->{foo}; %dispatch = { &$rb(); hellow => &hellow, foo => $foo, # foo world bar => sub { print bar foon; }, $rc = $dispatch->{bar}; } &$rc; # bar foo
  • 6. Program in Perl Style Reference Reference the awesome reference Dispatch table Higher order functions In mathematics and computer science, higher-order functions, functional forms, or functionals are functions which do at least one of the following: * take one or more functions as an input * output a function.
  • 7. Program in Perl Style Reference Higher Order Functions sub category_defect { Local $_; # just for a good habit my ( $column ) = @_; return sub { # return a function instead a value my ( $condition, $line ) = @_; return $$line[ $column ] eq $condition ; } }
  • 8. Program in Perl Style Reference Higher Order Functions sub defect_by_category { local $_; my ($column, $col_value) = @_; my $category = &category_defect( $column ); # which return return sub { # a function my (@result); my ($defect) = @_; return $defect # invoke previous function if &$category ($col_value, $defect) ; } }
  • 9. Program in Perl Style Reference Higher Order Functions sub defects_factory { local $_; my ($defect, @results); # accept function as param my ($conditions, $defects ) = @_; foreach $defect ( @$defects ) { push @results, $defect if &$conditions ( $defect ); } return @results; }
  • 10. Program in Perl Style Reference Higher Order Functions # $severity_1 holds a function reference, not a ordinary data $severity_1 = &defect_by_category( SEVERITY, "1" ); $severity_2 = &defect_by_category( SEVERITY, "2" ); $severity_3 = &defect_by_category( SEVERITY, "3" ); $severity_4 = &defect_by_category( SEVERITY, "4" ); # transfer a function reference as parameter @severity_1 = &defects_factory( $severity_1 , [ @defects ] ); @severity_2 = &defects_factory( $severity_2 , [ @defects ] ); @severity_3 = &defects_factory( $severity_3 , [ @defects ] ); @severity_4 = &defects_factory( $severity_4 , [ @defects ] );
  • 11. Program in Perl Style Typeglobs Typeglob is complex and dangures Always be careful!!!
  • 12. Program in Perl Style Typeglobs Typeglobs and symble table You'd better to read Camel book very carefully before start to using it. $spud = "Wow!"; @spud = ("idaho", "russet"); *potato = *spud; # Alias potato to spud using typeglob assignment print "$potaton"; # prints "Wow!" print @potato, "n"; # prints "idaho russet"
  • 13. Program in Perl Style Typeglobs It is NOT the pointer you would expect in C although they look similar literally $b = 10; { local *b; # Save *b's values *b = *a; # Alias b to a $b = 20; # Same as modifying $a instead } # *b restored at end of block print $a; # prints "20" print $b; # prints "10"
  • 14. Program in Perl Style Typeglobs Efficient parameter passing @array = (10,20); DoubleEachEntry(*array); # @array and @copy are identical. print "@array n"; # prints 20 40 sub DoubleEachEntry { # $_[0] contains *array local *copy = shift; # Create a local alias foreach $element (@copy) { $element *= 2; } }
  • 15. Program in Perl Style Typeglobs Passing Filehandles to Subroutines Filehandle can not be passed to subroutines as scalars The only way to it is through typeglobs open (F, "/tmp/sesame") || die $!; read_and_print(*F); sub read_and_print { # Filehandle G local (*G) = @_; # is the same as filehandle F while (<G>) { print; } }
  • 16. Program in Perl Style Typeglobs Typeglobs are not always so explicitely cat test.pl #!/usr/bin/perl Be very careful!!! $foo = 123; Implicit typeglobs will make $bar = 321; your code very hard to $ra = "foo"; print "$ra = $$ra n"; understand while ($rb = <STDIN>) { chomp($rb); print "$rb = $$rb n"; } bash-4.1$ echo "bar" | perl test2.pl foo = 123 bar = 321
  • 17. Program in Perl Style Typeglobs But anyway ---- It's powerful!!!
  • 18. Program in Perl Style Typeglobs You can even build dispatch table from a plain file cat a.cfg while ($a = <>) { h say_hellow_to_a_friend chomp($a); ($key, $func) = split , $a; a accept_an_invitation $disptch{$key} = $func; c confirm_an_invition } e send_email_to_a_friend r refuse_an_invitation sub command { my ($cmd, arg) = @_; Suppose you have functions $rcmd = $disptch->{$cmd}; in above names &$rcmd($arg) if defined &$rcmd; } &command("h", Tom);
  • 19. Program in Perl Style Say good-bye to your endless ... switch ... case ... if elsif ... etc. So think again why there is no 'switch', 'case' ... in Perl? Maybe you don't actually need it.