Perl From Ground level and Up Lecture 2 October 22 2007 By Shmuel Fomberg
Parameters Passing Using the @_ array October 22 2007 Shmuel Fomberg func(5, $x, (7, 4), [$y, %h]); # @_ = (5, $x, 7, 4, [$y, %h]) sub func {   my $x1 = shift; # $x1 is 5   $_[0] = 3; # $x now is 3! (do not use this, normally)   my ($x2, $x3) = @_; # multiple params   …
Perl script life cycle Compilation use statement  –  executed Compiling Module Running the module BEGIN blocks executed Script runs End of program Global variables destruction END blocks executed October 22 2007 Shmuel Fomberg
Perl script life cycle October 22 2007 Shmuel Fomberg #!/usr/bin/perl -w use strict; BEGIN {print &quot;one &quot;} use A; END {print &quot;two &quot;} print &quot;three &quot;; package A; BEGIN {print &quot;four &quot;} END {print &quot;five &quot;} print &quot;six &quot;; 1; #  <- note here Output: one four six three two five  Test.pl A.pm
What is a Class? Class is a package More exactly, Class is the name of the package October 22 2007 Shmuel Fomberg Class->func(…); my $name = ‘Class’; $name->func(…); In both cases: Class::func(‘Class’, …) Can even do: my $fname = ‘func’; $name->$fname(…);
What is a Class? October 22 2007 Shmuel Fomberg Class variables are the package variables Only full-names are supported package Class; our $var = 5; …  elsewhere in the program: print $Class::var;
Class inheritance Inheritance is dictated by the @ISA array Functions are searched DFS October 22 2007 Shmuel Fomberg package Class; our @ISA = qw{ClassP1 ClassP2}; use base qw{ClassP1 ClassP2}; func(…); #will search …  elsewhere in the program: Class->func(…); #will search Class::func(…); # will not search Class->ClassP2::func(…); # explicit
Class inheritance UNIVERSIAL is the father of all. October 22 2007 Shmuel Fomberg Class->can(‘func’); Class->isa(‘ClassP1); UNIVERSIAL::isa(‘Class’, ‘ClassP1’); All functions are virtual To run parent ’ s function use SUPER SUPER refer to the parents of the current package package Class; SubClass->SUPER::func(…);
The SUPER meta class October 22 2007 Shmuel Fomberg A B C D E $class->func(...) $class->SUPER::func(...) package C; sub mysub {   my $class = shift;   # $class eq ‘E’   …..
What is an Object? Object is a reference to anything, with a label We use hash, for flexibility label  –  name of a package Assigning label to a ref done using the  ‘ bless ’  command October 22 2007 Shmuel Fomberg my $self = bless {}, ‘Class’; $self is the usual name for  ‘ this ’ So, in the beginning of every method: my $self = shift; my ($self, $param1, …) = @_;
What is an Object? Object variables  –  keys/values in the refered hash. October 22 2007 Shmuel Fomberg $obj->{var1} = 5; Inheritance, SUPER  –  Exactly like the Class. $obj->isa(‘ClassP1’); if ref($obj) and $obj->isa(‘ClassP1’); $obj->func(…); $self->SUPER::func(…); Class::func($obj, …);
Creating an Object At the parent Class: October 22 2007 Shmuel Fomberg sub new {   my ($class, params…) = @_;   my $self = { keys and values… };   return bless $self, $class; } In the sub-class: sub new {   my ($class, params…) = @_;   $self = $class->Parent::new(params…);   # do more initialization   return $self; }
Destroying an Object When no one refers to an object, it id deleted $obj->DESTROY is called Have to manually call $self->SUPER::DESTROY October 22 2007 Shmuel Fomberg sub DESTROY {   my $self = shift;   # do whatever   $self->SUPER::DESTROY(); }
Problems? October 22 2007 Shmuel Fomberg NOT SCALABLE Object variable are just keys in hash - spelling error will created bugs You have to know and hard-code the Class-variable package  The new will not support multi-inheritance
How Should it be done Define a root class with a constructor, _Init and DESTROY October 22 2007 Shmuel Fomberg package Root; use base qw/Class::Accessor Class::Data::Inheritable/; sub new {   my ($class, @params) = @_;   my $self = bless {}, $class;   $self->_Init(@params);   return $self; } sub _Init {} sub DESTROY {}
How Should it be done Every new class will be: October 22 2007 Shmuel Fomberg package MyClass; use base qw/Root/; __PACKAGE__->mk_accessors(qw(name role salary)); sub _Init {   my ($self, $salary, $name) = @_;   $self->SUPER::_Init($name);   $self->salary($salary); } sub DESTROY { # if needed   my $self = shift;   ... do something ...   $self->SUPER::DESTORY; }
How Should it be done What about Class data? October 22 2007 Shmuel Fomberg package MyClass; use base qw/Root/; Stuff->mk_classdata(‘Color'); # Declare the location of the data file for this class. Stuff->Color(‘blue'); # Or, all in one shot: Stuff->mk_classdata(Color => ‘blue');
Unit Test Sanity Test your modules and functions Protect you from un-intentionally breaking some expected behavior Should be fast and easy For example, if we have function sum: October 22 2007 Shmuel Fomberg 5 == sum(3,2)
Perl Standard Unit Test Test::Simple is.. simple. October 22 2007 Shmuel Fomberg use Test::Simple tests => 2; my $foo = &quot;x&quot;; ok( $foo eq &quot;x&quot;, 'foo is X' ); ok( $foo ne &quot;Y&quot;, 'foo is not Y'); 1..2 ok 1 - foo is X ok 2 - foo is not Y
A bit more advanced techniques What if the function needs an object as parameter? Construct a fake object What if the function relies on other modules / functions? Prevent loading the module (%INC) and write dummy functions $INC{'PLSTAF.pm'} = &quot;c:/perl/lib/dummy.pm&quot;; use in BEGIN block functions swapping / overriding *Module::func = \&MyOverride; October 22 2007 Shmuel Fomberg

Perl from the ground up: objects and testing

  • 1.
    Perl From Groundlevel and Up Lecture 2 October 22 2007 By Shmuel Fomberg
  • 2.
    Parameters Passing Usingthe @_ array October 22 2007 Shmuel Fomberg func(5, $x, (7, 4), [$y, %h]); # @_ = (5, $x, 7, 4, [$y, %h]) sub func { my $x1 = shift; # $x1 is 5 $_[0] = 3; # $x now is 3! (do not use this, normally) my ($x2, $x3) = @_; # multiple params …
  • 3.
    Perl script lifecycle Compilation use statement – executed Compiling Module Running the module BEGIN blocks executed Script runs End of program Global variables destruction END blocks executed October 22 2007 Shmuel Fomberg
  • 4.
    Perl script lifecycle October 22 2007 Shmuel Fomberg #!/usr/bin/perl -w use strict; BEGIN {print &quot;one &quot;} use A; END {print &quot;two &quot;} print &quot;three &quot;; package A; BEGIN {print &quot;four &quot;} END {print &quot;five &quot;} print &quot;six &quot;; 1; # <- note here Output: one four six three two five Test.pl A.pm
  • 5.
    What is aClass? Class is a package More exactly, Class is the name of the package October 22 2007 Shmuel Fomberg Class->func(…); my $name = ‘Class’; $name->func(…); In both cases: Class::func(‘Class’, …) Can even do: my $fname = ‘func’; $name->$fname(…);
  • 6.
    What is aClass? October 22 2007 Shmuel Fomberg Class variables are the package variables Only full-names are supported package Class; our $var = 5; … elsewhere in the program: print $Class::var;
  • 7.
    Class inheritance Inheritanceis dictated by the @ISA array Functions are searched DFS October 22 2007 Shmuel Fomberg package Class; our @ISA = qw{ClassP1 ClassP2}; use base qw{ClassP1 ClassP2}; func(…); #will search … elsewhere in the program: Class->func(…); #will search Class::func(…); # will not search Class->ClassP2::func(…); # explicit
  • 8.
    Class inheritance UNIVERSIALis the father of all. October 22 2007 Shmuel Fomberg Class->can(‘func’); Class->isa(‘ClassP1); UNIVERSIAL::isa(‘Class’, ‘ClassP1’); All functions are virtual To run parent ’ s function use SUPER SUPER refer to the parents of the current package package Class; SubClass->SUPER::func(…);
  • 9.
    The SUPER metaclass October 22 2007 Shmuel Fomberg A B C D E $class->func(...) $class->SUPER::func(...) package C; sub mysub { my $class = shift; # $class eq ‘E’ …..
  • 10.
    What is anObject? Object is a reference to anything, with a label We use hash, for flexibility label – name of a package Assigning label to a ref done using the ‘ bless ’ command October 22 2007 Shmuel Fomberg my $self = bless {}, ‘Class’; $self is the usual name for ‘ this ’ So, in the beginning of every method: my $self = shift; my ($self, $param1, …) = @_;
  • 11.
    What is anObject? Object variables – keys/values in the refered hash. October 22 2007 Shmuel Fomberg $obj->{var1} = 5; Inheritance, SUPER – Exactly like the Class. $obj->isa(‘ClassP1’); if ref($obj) and $obj->isa(‘ClassP1’); $obj->func(…); $self->SUPER::func(…); Class::func($obj, …);
  • 12.
    Creating an ObjectAt the parent Class: October 22 2007 Shmuel Fomberg sub new { my ($class, params…) = @_; my $self = { keys and values… }; return bless $self, $class; } In the sub-class: sub new { my ($class, params…) = @_; $self = $class->Parent::new(params…); # do more initialization return $self; }
  • 13.
    Destroying an ObjectWhen no one refers to an object, it id deleted $obj->DESTROY is called Have to manually call $self->SUPER::DESTROY October 22 2007 Shmuel Fomberg sub DESTROY { my $self = shift; # do whatever $self->SUPER::DESTROY(); }
  • 14.
    Problems? October 222007 Shmuel Fomberg NOT SCALABLE Object variable are just keys in hash - spelling error will created bugs You have to know and hard-code the Class-variable package The new will not support multi-inheritance
  • 15.
    How Should itbe done Define a root class with a constructor, _Init and DESTROY October 22 2007 Shmuel Fomberg package Root; use base qw/Class::Accessor Class::Data::Inheritable/; sub new { my ($class, @params) = @_; my $self = bless {}, $class; $self->_Init(@params); return $self; } sub _Init {} sub DESTROY {}
  • 16.
    How Should itbe done Every new class will be: October 22 2007 Shmuel Fomberg package MyClass; use base qw/Root/; __PACKAGE__->mk_accessors(qw(name role salary)); sub _Init { my ($self, $salary, $name) = @_; $self->SUPER::_Init($name); $self->salary($salary); } sub DESTROY { # if needed my $self = shift; ... do something ... $self->SUPER::DESTORY; }
  • 17.
    How Should itbe done What about Class data? October 22 2007 Shmuel Fomberg package MyClass; use base qw/Root/; Stuff->mk_classdata(‘Color'); # Declare the location of the data file for this class. Stuff->Color(‘blue'); # Or, all in one shot: Stuff->mk_classdata(Color => ‘blue');
  • 18.
    Unit Test SanityTest your modules and functions Protect you from un-intentionally breaking some expected behavior Should be fast and easy For example, if we have function sum: October 22 2007 Shmuel Fomberg 5 == sum(3,2)
  • 19.
    Perl Standard UnitTest Test::Simple is.. simple. October 22 2007 Shmuel Fomberg use Test::Simple tests => 2; my $foo = &quot;x&quot;; ok( $foo eq &quot;x&quot;, 'foo is X' ); ok( $foo ne &quot;Y&quot;, 'foo is not Y'); 1..2 ok 1 - foo is X ok 2 - foo is not Y
  • 20.
    A bit moreadvanced techniques What if the function needs an object as parameter? Construct a fake object What if the function relies on other modules / functions? Prevent loading the module (%INC) and write dummy functions $INC{'PLSTAF.pm'} = &quot;c:/perl/lib/dummy.pm&quot;; use in BEGIN block functions swapping / overriding *Module::func = \&MyOverride; October 22 2007 Shmuel Fomberg