Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5;...

54
Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman' );

Transcript of Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5;...

Page 1: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

Take control

Introductie in het wijzigen van standaard Perl gedrag

use Workshop::Perl::Dutch 5;date( '2008-02-29' );author( abeltje => 'Abe Timmerman' );

Page 2: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 2

Technieken

• overload

• tie

• CORE::GLOBAL

• Attribute::Handlers

Page 3: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 3

overload gebruikers?

Page 4: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 4

overload

• stringify– String functies

• Numify– Rekenkundige

bewerkingen– Rekenkundige functies

• overload::constant()

Page 5: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 5

overload API

• Operator overloading met sub

• Unary operators:– 1 argument

• Binary operators– 3 argumenten

• 1ste altijd een object• 2de object of constante• 3de geeft aan of 1ste en 2de zijn verwisseld

Page 6: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 6

Coords.pmpackage Coords;

sub new { my( $class, $x, $y ) = @_; bless { _x => $x || 0, _y => $y || 0 }, $class;}

sub move { my( $self, $dx, $dy ) = @_; ref $dx eq __PACKAGE__ and ( $dx, $dy ) = ( $dx->{_x}, $dx->{_y} ); $self->{_x} += $dx; $self->{_y} += $dy; return $self;}

sub as_string { my( $self ) = @_; return sprintf "(%d, %d)", $self->{_x}, $self->{_y};}

Page 7: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 7

Coords.pmpackage Coords;

use overload q{""} => \&as_string, fallback => 1;

sub new { my( $class, $x, $y ) = @_; bless { _x => $x || 0, _y => $y || 0 }, $class;}

sub move { my( $self, $dx, $dy ) = @_; ref $dx eq __PACKAGE__ and ( $dx, $dy ) = ( $dx->{_x}, $dx->{_y} ); $self->{_x} += $dx; $self->{_y} += $dy; return $self;}

sub as_string { my( $self ) = @_; return sprintf "(%d, %d)", $self->{_x}, $self->{_y};}

Page 8: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 8

Testing Coords.pm

use Test::More 'no_plan';

my $c = Coords->new( 150, 150 );is $c, $c->as_string, "overloaded stringify: $c";

$c->move( -50, 50 );is $c, "(100, 200)", "->move(-50,50): $c";

my $m = Coords->new( 50, -50 );$c->move( $m );is $c, "(150, 150)", "->move$m: $c";

# overload/coords/1fase/ -> prove -lv t/*.t

Page 9: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 9

Using '+' to moveuse Test::More 'no_plan';

my $c1 = Coords->new( 150, 150 );is $c1, $c1->as_string, "overloaded stringify: $c1";

my $c2 = Coords->new( -50, 50 );is $c2, $c2->as_string, "overloaded stringify: $c2";

my $r2 = $c1 + $c2;isa_ok $r2, 'Coords';is $r2, "(100, 200)", "overloaded addition: $r2";

Page 10: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 10

Using '+' to moveuse Test::More 'no_plan';

my $c1 = Coords->new( 150, 150 );is $c1, $c1->as_string, "overloaded stringify: $c1";

my $c2 = Coords->new( -50, 50 );is $c2, $c2->as_string, "overloaded stringify: $c2";

my $r1 = $c1->copy;isa_ok $r1, 'Coords';is $r1, $c1, "->copy: $r1";

$r1->move( $c2 );is $r1, "(100, 200)", "->move$c2: $r1";

my $r2 = $c1 + $c2;isa_ok $r2, 'Coords';is $r2, "(100, 200)", "overloaded addition: $r2";

Page 11: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 11

Using '+' to movepackage Coords;

use overload q{""} => \&as_string,

fallback => 1;

sub new { my( $class, $x, $y ) = @_; bless { _x => $x || 0, _y => $y || 0 }, $class;}

sub copy { return bless { _x => $_[0]->{_x}, _y => $_[0]->{_y} }, ref $_[0]; }

sub move { my( $self, $dx, $dy ) = @_; ref $dx and ( $dx, $dy ) = ( $dx->{_x}, $dx->{_y} ); $self->{_x} += $dx; $self->{_y} += $dy; return $self;}

sub as_string { my( $self ) = @_; return sprintf "(%d, %d)", $self->{_x}, $self->{_y};}

Page 12: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 12

Using '+' to movepackage Coords;

use overload q{""} => \&as_string, q{+} => \&add_move, fallback => 1;

sub new { my( $class, $x, $y ) = @_; bless { _x => $x || 0, _y => $y || 0 }, $class;}

sub copy { return bless { _x => $_[0]->{_x}, _y => $_[0]->{_y} }, ref $_[0]; }

sub move { my( $self, $dx, $dy ) = @_; ref $dx and ( $dx, $dy ) = ( $dx->{_x}, $dx->{_y} ); $self->{_x} += $dx; $self->{_y} += $dy; return $self;}

sub add_move { my( $a1, $a2 ) = @_; ref $a2 or die "Cannot move() with constants!"; $a1->copy->move( $a2 );}

sub as_string { my( $self ) = @_; return sprintf "(%d, %d)", $self->{_x}, $self->{_y};}

Page 13: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 13

Meer informatie

• perldoc overload

Page 14: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 14

tie() gebruikers?

Page 15: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 15

• Geef een object de interface van een Perl variabele type

• Mogelijke typen:– Scalar– Array– Hash– Handle

• Toegang tot het onderliggende object met behulp van tied()

tie()

Page 16: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 16

• API:– TIEARRAY constructor– FETCH, STORE– FETCHSIZE, STORESIZE– CLEAR, EXTEND– EXISTS, DELETE– PUSH, POP,– SHIFT, UNSHIFT, SPLICE– UNTIE, DESTROY

TIEARRAY API

Page 17: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 17

TIEARRAY

• Geef een object de interface van een array

• In het voorbeeld: gebruik een scalar als array– substr() <-> push/pop/unshift/shift/slice

Page 18: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 18

CharArray (src1)package CharArray;use warnings;use strict;

sub TIEARRAY { my $class = shift; ref $_[0] or die "Usage: tie my @a, CharArray => \$scalar;"; bless $_[0], $class;}

sub UNTIE { }

sub FETCHSIZE { my $self = shift; defined $$self ? length( $$self ) : 0;}

Page 19: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 19

CharArray (src2)sub FETCH { my( $self, $index ) = @_; $index > length $$self and $$self .= "" x ( 1 + $index - length $$self ); defined $$self ? substr $$self, $index, 1 : undef;}sub STORE { my( $self, $index, $value ) = @_; $index > length $$self and $$self .= "" x ( 1 + $index - length $$self ); substr $$self, $index, 1, $value;}sub PUSH { my $self = shift; $$self .= join "", @_; length $$self;}sub POP { my $self = shift; my $last = substr $$self, -1, 1; $$self = substr $$self, 0, length( $$self ) - 1; $last;}1;

Page 20: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 20

Testing CharArray.pm#! /usr/bin/perluse warnings;use strict;

use Test::More 'no_plan';

use_ok 'CharArray';

{ my $orig = 'value'; tie my @ca, 'CharArray', \$orig; is $ca[0], 'v', "First value '@ca' (${ tied( @ca ) })"; push @ca, 's'; is @ca, 6, "new length (${ tied( @ca ) })";

my $sorted = join "", sort @ca; is $sorted, 'aelsuv', "sorting the array works ($sorted)";

untie @ca; is $orig, 'values', "still the changed value in original ($orig)";}

# tie/array/ -> prove -lv t/*.t

Page 21: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 21

• API:– TIEHANDLE constructor– schrijven

• PRINT, PRINTF• WRITE

– lezen• READLINE• READ, GETC

– CLOSE– UNTIE, DESTROY

TIEHANDLE API

Page 22: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 22

TIEHANDLE (output)

• Output– STDOUT, STDERR– Iedere andere GLOB

• Methods:– TIEHANDLE()– PRINT– PRINTF

Page 23: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 23

CatchOut.pmpackage CatchOut;use strict;use warnings;

our $VERSION = 0.04;

# tie *HANDLE, CatchOut => <\*TIEDHANDLE | \$buf>sub TIEHANDLE { my $class = shift; ref $_[0] eq __PACKAGE__ and return $_[0]; ref $_[0] eq 'SCALAR' or die "Usage:\n\ttie *HANDLE, CatchOut => <\*TIEDHANDLE | \$buf>"; bless $_[0], $class;}

sub PRINT { my $self = shift; $$self .= join "", @_;}

sub PRINTF { my $self = shift; my( $fmt, @args ) = @_; $$self .= sprintf $fmt, @args;}

1;

Page 24: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 24

Testing CatchOut.pm#! perluse warnings;use strict;

use Test::More 'no_plan';

use_ok 'CatchOut';

{ my $outbuf; { local *OUT; tie *OUT, 'CatchOut', \$outbuf; print OUT "Testline\n"; untie *OUT; } is $outbuf, <<' __EOTEST__', "Caught the right output";Testline __EOTEST__}

Page 25: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 25

TIEHANDLE (input)

• Input– STDIN– Elke andere GLOB

• Methods:– TIEHANDLE– READLINE

Page 26: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 26

FeedIn.pmpackage FeedIn;use warnings;use strict;

our $VERSION = 0.01;

# tie *FH, FeedIn => $text;sub TIEHANDLE { my( $class, $store ) = @_; bless \$store, $class;}

sub READLINE { my $self = shift; defined $$self or return; length $$self or return; if ( ! defined $/ ) { # slurp-mode my $all = $$self; $$self = undef; return $all; } if ( wantarray ) { my @lines = grep length $_ => $$self =~ m{(.*?(?:$/|\z))}sg; $$self = undef; return @lines; } else { return defined $$self =~ s{(.*?(?:$/|\z))}{}s ? $1 : undef; }}1;

Page 27: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 27

Testing FeedIn.pm#! perluse warnings;use strict;use Test::More 'no_plan';use_ok 'FeedIn';{ local *IN; tie *IN, 'FeedIn', "regel 1\nregel 2"; my @line = <IN>; is scalar @line, 2, "2 lines in list-context";

is $line[0], "regel 1\n", "Read a line '$line[0]'"; is $line[1], "regel 2", "Read a line '$line[1]'";}{ local *IN; tie *IN, 'FeedIn', "regel 1\nregel 2"; my @line; while ( <IN> ) { push @line, $_ } is scalar @line, 2, "2 lines in list-context";

is $line[0], "regel 1\n", "Read a line '$line[0]'"; is $line[1], "regel 2", "Read a line '$line[1]'";}{ local *IN; tie *IN, 'FeedIn', "regel 1\nregel 2"; my $lines = do { local $/; <IN> }; is $lines, "regel 1\nregel 2", "Slurp-mode";}

Page 28: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 28

Meer informatie

• perldoc perltie

Page 29: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 29

CORE::GLOBAL gebruikers?

Page 30: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 30

CORE::GLOBAL::

• Herdefinieren interne functies– prototype CORE::– In de compileer fase (BEGIN)

• Origineel altijd nog beschikbaar– CORE::

Page 31: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 31

CORE::GLOBAL::gmtime#! /usr/bin/perluse warnings;use strict;

BEGIN { # 29 Feb 2008 12:00:00 GMT *CORE::GLOBAL::gmtime = sub (;$) { my $stamp = @_ ? $_[0] : 1204286400; CORE::gmtime( $stamp ); };}

printf "[ empty] %s\n", scalar gmtime( );printf "[time()] %s\n", scalar gmtime( time );

Page 32: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 32

Een test case voor open()

• Ik wil de volgende soort code testen:– open my $fh, '<', '/proc/cpuinfo'

• Herdefinieer – CORE::GLOBAL::open

• Gebruik een tied handle voor invoer– FeedIn.pm

Page 33: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 33

MyOpen.pmpackage MyOpen;use warnings;use strict;

our $VERSION = 0.01;

sub core_open (*;$@) { my( $handle, $mode, $file, @list ) = @_;

# make sure filehandles are in their own package my $pkg = caller; if ( defined $handle and !ref $handle ) { # bareword handle no strict 'refs'; $handle = *{ "$pkg\:\:$handle" }; } elsif ( !defined $handle ) { # undefined scalar, provide GLOBref $_[0] = $handle = do { no strict 'refs'; \*{ sprintf "%s::NH%d%d%d", $pkg, $$, time, rand 100 }; }; }

# convert to two argumented open() defined $file and $mode .= " $file"; CORE::open( $handle, $mode );};

# prepare open() for runtime overrideBEGIN { *CORE::GLOBAL::open = \&core_open }

1;

Page 34: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 34

Testing MyOpen.pm#! perluse warnings;use strict;

use Test::More 'no_plan';

BEGIN { use_ok 'MyOpen' }ok defined &CORE::GLOBAL::open, "CORE::GLOBAL::open() defined";

my $content;{ CORE::open( my $fh, '<', $0 ) or die "Cannot CORE::open($0): $!"; isa_ok $fh, 'GLOB'; $content = do { local $/; <$fh> }; close $fh; like $content, qr/BEGIN { use_ok 'MyOpen' }/, "contains MyOpen";}{ open my $fh, '<', $0 or die "Cannot open($0): $!"; isa_ok $fh, 'GLOB'; my $file = do { local $/; <$fh> }; close $fh; is $file, $content, "contents still the same";}

Page 35: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 35

Bringing it togther (1/2)#! perluse warnings;use strict;

use Test::More 'no_plan';

BEGIN { use_ok 'MyOpen' }ok defined &CORE::GLOBAL::open, "CORE::GLOBAL::open() defined";

use_ok 'FeedIn';{ no warnings 'redefine'; local *CORE::GLOBAL::open = \&tied_open; open my $fh, '<', $0 or die "Cannot tied_open($0): $!"; isa_ok tied( $fh ), 'FeedIn'; my $file = do { local $/; <$fh> }; close $fh;

is $file, "open: $0", "tied_open() returned '$file'";}

Page 36: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 36

Bringing it together (2/2)sub tied_open (*;$@) { my( $handle, $mode, $file ) = @_;

# make sure filehandles are in their own package my $pkg = caller; if ( defined $handle and !ref $handle ) { # bareword handle no strict 'refs'; $handle = *{ "$pkg\:\:$handle" }; } elsif ( !defined $handle ) { # undefined scalar, provide a GLOB $_[0] = $handle = do { no strict 'refs'; *{ sprintf "%s::NH%d%d%d", $pkg, $$, time, rand 100 }; }; }

# convert to two argumented open() defined $file and $mode .= " $file";

# do the magic-tie for open "< $0" or pass to CORE::open() if ( $mode =~ m/^(?:<\s*)?($0)/ ) { tie $handle, FeedIn => "open: $1"; } else { CORE::open( $handle, $mode ); }}

Page 37: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 37

Meer informatie

• perldoc perlsub

Page 38: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 38

Attribute::Handler gebruikers?

Page 39: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 39

Attribute::Handlers

• Perl heeft syntax voor attributes– :my_attribute(data)

• Perl heeft twee geïmplementeerde attributes– :lvalue– :ATTR

• Via :ATTR is de attribute implementatie uit te breiden– Een attribute is een sub met die naam die

het :ATTR attribute heeft

Page 40: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 40

Types voor een attribute

• Deze typen kunnen een attribute krijgen– SCALAR– ARRAY– HASH– CODE (sub)

Page 41: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 41

Aandachtspunten

• De handler sub moet bekend zijn in de aanroepende namespace– use base– Declareer in UNIVERSAL::

• Argumenten aan de handler sub– Aanroepende package– Referentie naar de symbol table (CODE)– Referentie naar de variabele/code– Attribute naam– Data die aan het attribute wordt mee gegeven– Fase voor de handler (BEGIN,CHECK,INIT,END)

Page 42: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 42

Een attribute voor tie()package Tie_OddEven;use strict;use warnings;

our $VERSION = 0.01;

use Attribute::Handlers;

sub OddEven :ATTR(SCALAR) { my( $pkg, $symbol, $referent, $attr, $data ) = @_; tie $$referent, __PACKAGE__, $data;}sub TIESCALAR { my $class = shift; bless \(my $self = shift), $class;}sub FETCH { my $self = shift; return $$self % 2 == 0 ? 'even' : 'odd';}sub STORE { my $self = shift; $$self = shift;}1;

Page 43: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 43

Voorbeeld code voor gebruik#! /usr/bin/perluse warnings;use strict;

use lib 'lib';use Tie_OddEven;

tie my $oe, Tie_OddEven => 0;while ( 1 ) { print "Number: "; chomp( my $input = <> ); last unless $input =~ /^-?\d+$/; $oe = $input; printf "$input is $oe (%d)\n", ${ tied $oe };}

Page 44: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 44

Voorbeeld code voor gebruik#! /usr/bin/perluse warnings;use strict;

use lib 'lib';use base 'Tie_OddEven';

my $oe :OddEven(0);while ( 1 ) { print "Number: "; chomp( my $input = <> ); last unless $input =~ /^-?\d+$/; $oe = $input; printf "$input is $oe (%d)\n", ${ tied $oe };}

Page 45: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 45

Oorspronkelijke attributepackage Tie_OddEven;use strict;use warnings;

our $VERSION = 0.01;

use Attribute::Handlers;

sub OddEven :ATTR(SCALAR) { my( $pkg, $symbol, $referent, $attr, $data ) = @_; tie $$referent, __PACKAGE__, $data;}sub TIESCALAR { my $class = shift; bless \(my $self = shift), $class;}sub FETCH { my $self = shift; return $$self % 2 == 0 ? 'even' : 'odd';}sub STORE { my $self = shift; $$self = shift;}1;

Page 46: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 46

Een UNIVERSAL:: attributepackage Universal_OddEven;use strict;use warnings;

our $VERSION = 0.01;

use Attribute::Handlers;

sub UNIVERSAL::OddEven :ATTR(SCALAR) { my( $pkg, $symbol, $referent, $attr, $data ) = @_; tie $$referent, __PACKAGE__, $data;}sub TIESCALAR { my $class = shift; bless \(my $self = shift), $class;}sub FETCH { my $self = shift; return $$self % 2 == 0 ? 'even' : 'odd';}sub STORE { my $self = shift; $$self = shift;}1;

Page 47: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 47

Oorspronkelijke voorbeeld#! /usr/bin/perluse warnings;use strict;

use lib 'lib';use base 'Tie_OddEven';

my $oe :OddEven(0);while ( 1 ) { print "Number: "; chomp( my $input = <> ); last unless $input =~ /^-?\d+$/; $oe = $input; printf "$input is $oe (%d)\n", ${ tied $oe };}

Page 48: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 48

Gebruik UNIVERSAL attribute#! /usr/bin/perluse warnings;use strict;

use lib 'lib';use Universal_OddEven;

my $oe :OddEven(0);while ( 1 ) { print "Number: "; chomp( my $input = <> ); last unless $input =~ /^-?\d+$/; $oe = $input; printf "$input is $oe (%d)\n", ${ tied $oe };}

Page 49: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 49

Oorspronkelijke attributepackage Tie_OddEven;use strict;use warnings;

our $VERSION = 0.01;

use Attribute::Handlers;

sub OddEven :ATTR(SCALAR) { my( $pkg, $symbol, $referent, $attr, $data ) = @_; tie $$referent, __PACKAGE__, $data;}sub TIESCALAR { my $class = shift; bless \(my $self = shift), $class;}sub FETCH { my $self = shift; return $$self % 2 == 0 ? 'even' : 'odd';}sub STORE { my $self = shift; $$self = shift;}1;

Page 50: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 50

Een attribute en autotiepackage Auto_OddEven;use strict;use warnings;

our $VERSION = 0.01;

use Attribute::Handlers autotie => { '__CALLER__::OddEven' => __PACKAGE__};

sub TIESCALAR { my $class = shift; bless \(my $self = shift), $class;}sub FETCH { my $self = shift; return $$self % 2 == 0 ? 'even' : 'odd';}sub STORE { my $self = shift; $$self = shift;}1;

Page 51: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 51

Gebruik autotie attribute#! /usr/bin/perluse warnings;use strict;

use lib 'lib';use Auto_OddEven;

my $oe :OddEven(0);while ( 1 ) { print "Number: "; chomp( my $input = <> ); last unless $input =~ /^-?\d+$/; $oe = $input; printf "$input is $oe (%d)\n", ${ tied $oe };}

Page 52: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 52

Meer informatie

• perldoc Attribute::Handlers

Page 53: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 61

Vragen?

Page 54: Take control Introductie in het wijzigen van standaard Perl gedrag use Workshop::Perl::Dutch 5; date( '2008-02-29' ); author( abeltje => 'Abe Timmerman'

28/2/2008 Take control 62

Dank je wel!