1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | use strict; use DataRow; # importeer de functies van DataRow.pm # snel alle records uit een tabel in xml formaat naar het scherm printen: my $pages = DataRow->select( from => 'pages' ); # doet de query 'select * from pages' en geeft de rows als arrayref terug print "<pages>" for my $page (@{$pages}) { print $page->toXML; } print "</pages>"; my $user = DataRow->new( ID => 23, dbTable => 'users' ); my $usercopy = $user->createCopy; # creeer een kopie van de user print $user->getField( field => 'name' ); # print de naam van de user $usercopy->setField( email => 'email@domain.com', #pas het email adres aan password => 'secretpassword', #en update wachtwoord ); $usercopy->save; # opslaan en het staat in de database, onder een nieuw ID! |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | use strict; # dit zorgt er oa voor dat alle variabelen altijd gedefinieerd moeten worden sub new { # het eerste argument van de functie is in perl altijd de naam van de aangeroepen class (in dit geval "DataRow") my $classname = shift; my $args = { # de argumenten met default values ID => 0, fields => {}, # een hashref met <naam> => <value> paren dbTable => undef, # de tabel in de database die bij dit object hoort @_, # @_ is een array met de argumenten die meegegeven zijn }; # $self is het eigenlijke object, wat in wezen niks meer is dan een associatieve arrayref (hashref in perl lingo) # we stoppen er gewoon de meegegeven argumenten in my $self = { ID => $args->{ID}, fields => $args->{fields}, dbTable => $args->{dbTable}, }; bless $self, $classname; # we "blessen" de hashref met de classname "DataRow", het is nu officieel een DataRow object return $self; # en we retourneren het zojuist gemaakte nieuwe object } 1; # een package bestand moet in perl altijd met een "true" (1) eindigen |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | use strict; use DataRow; # importeer de functies van DataRow.pm use Data::Dumper; # een handige en onmisbare utility om inhoud van variabelen te printen my $page = DataRow->new( fields => { title => 'Titel van pagina 1', description => 'blaat', content => 'Lorem ipsum, quia dolor sit, amet, consectetur, adipisci velit.' }, dbTable => 'pages' ) print Dumper $page; # print de structuur en inhoud |
De implementatie in perl is inderdaad anders dan in sommige andere talen, het is er pas later "ingeklust" maar is wel volledig en heel elegant (vind ik persoonlijk). Je kan er alles mee wat je moet kunnen, dus kun je ook subclasses maken waarvan je erg flexibel kan overerven, hier kom ik misschien later nog op terug in deze tutorial.quote:Op dinsdag 22 januari 2008 22:11 schreef Wolfje het volgende:
Is perl wel een echte object georienteerde taal? Het ziet er namelijk uit als wat geknutsel om een oo effect te krijgen. De naam 'package' doet vermoeden dat je dat woord ook kunt gebruiken om een aantal methodes te groeperen onder een gezamenlijke naam. En 'new' lijkt een doodgewone methode.
Kun je in perl dan ook subclasses maken?
Omdat ik controle wil hebben over wat ik in mijn object krijg, en je niet zomaar bagger erin kan stoppen.quote:Op woensdag 23 januari 2008 08:15 schreef slakkie het volgende:
Waarom bless je niet $args? $self is een copy ervan.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | USE ooptutorial; CREATE TABLE `albums` ( `ID` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL, `image_url` varchar(255) default NULL, `release_date` date NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `artists` ( `ID` int(10) unsigned NOT NULL auto_increment, `name` varchar(255) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `songs` ( `ID` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) default NULL, `albumID` int(10) unsigned default NULL, `artistID` int(10) unsigned default NULL, PRIMARY KEY (`ID`), KEY `fk_artistID` (`artistID`), KEY `fk_albumID` (`albumID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | my $self = shift; $args = { reload => 0, @_, }; return unless ($self->{ID} && $self->{dbTable}); # zonder ID of dbTable kunnen we niet laden! if (!$self->{isLoaded} || $args->{reload}) { # alleen laden als ie nog niet is geladen, of als reload=1 # construeer de sql # "join" werkt net als implode in php, hier wordt automatisch de juiste sql query mee gemaakt my $sql = "select " . join (",", keys %{$self->{fields}}) . " from " . $self->{dbTable} . " where ID = ?;"; # query voorbereiden en uitvoeren met $self->{ID} als argument my $sth = $dbh->prepare($sql); $sth->execute($self->{ID}) or die $sth->errstr; # als er een resultaat is, vul dan het object met data uit de DB if (my $ref = $sth->fetchrow_hashref()) { $self->setField( $ref ); $self->{isLoaded} = 1; return $self; # als returnvalue het object zelf } } } sub save { my $self = shift; return unless ($self->{dbTable}); # zonder tabel kunnen we niet opslaan! if ($self->{ID}) { # het object bestaat al in de database, doe dus een replace incl ID my $sql = " replace into " . $self->{dbTable} . " (". join(",", sort keys %{$self->{fields}}) . ") values (?, "; # placeholder voor ID $sql .= ' ?,' x scalar keys %{$self->{fields}}; # maak een placeholder voor elk field in $self->{fields} chop $sql; # de laatste komma willen we niet, dus erafchoppen $sql .= ');'; my $sth = $dbh->prepare($sql); $sth->execute($self->{ID}, map { $self->getField( field => $_ ) } sort keys %{$self->{fields}} ) or die $sth->errstr; } else { # nog geen ID bekend, het object bestaat dus nog niet, doe een insert my $sql = " insert into " . $self->{dbTable} . " (" .join(",", sort keys %{$self->{fields}}) . ") values ("; $sql .= '?,' x scalar keys %{$self->{fields}}; chop $sql; $sql .= ');'; my $sth = $dbh->prepare($sql); $sth->execute( map { $self->getField( field => $_ ) } sort keys %{$self->{fields}} ) or die $sth->errstr; $self->{ID} = $sth->{mysql_insertid}; } return $self->{ID}; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | my $self = shift; my $args = { field => undef, @_, }; $self->load; # als het object nog niet geladen is dan doen we dat hier alsnog return $self->{fields}->{$args->{field}}; } sub getFields { # geeft de hele fields hashref terug my $self = shift; $self->load; return $self->{fields}; } sub setField { # wijzig een of meerdere velden in het object my $self = shift; my $fields = {}; if (scalar @_ > 1) { # meer dan 1 element: list met name => value paren $fields = {@_}; } elsif (scalar @_ == 1) { # 1 element: een hashref met name => value paren ($fields) = @_; } for my $key (keys %{$fields}) { if (exists $self->{fields}->{$key}) { # zet het veld alleen als het gedefinieerd is $self->{fields}->{$key} = $fields->{$key}; $self->{lastModified} = time; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | use vars qw(@ISA); use strict; @ISA = qw(DataRow); # importeer alle functies van de package DataRow use DataRow; sub new { # we herdefinieren de constructor functie my $classname = shift # deze is hier dus "Artist"! my $args = { name => 'unnnamed artist', @_, }; # de basis van een Artist object is een DataRow object my $self = DataRow->new( fields => { name => $args->{name}, }, @_, # in @_ zitten ook alle evt overige argumenten, die gooien we gewoon allemaal mee naar DataRow->new ); bless $self, $classname; # maak er nu een echt Artist object van } 1; |
1 2 3 4 5 6 7 | use strict; use Artist; my $artist = Artist->new( name => 'Miles Davis' ); $artist->save; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | use vars qw(@ISA); use strict; @ISA = qw(DataRow); # importeer alle functies van de package DataRow use DataRow; sub new { # we herdefinieren de constructor functie my $classname = shift # deze is hier dus "Album"! my $args = { title => 'unnnamed album', image_url => '/albums/default.jpg', release_date => undef, @_, }; my $self = DataRow->new( fields => { title => $args->{title}, image_url => $args->{image_url}, release_date => $args->{release_date}, }, @_, # in @_ zitten ook evt andere argumenten, die gooien we gewoon mee naar DataRow->new ); bless $self, $classname; # maak er nu een echt Album object van } 1; |
1 2 3 4 5 6 7 8 9 10 11 12 | foreach my $value (@array) { if ($value) { printf "TRUE: $value \n"; } else { if (defined $value) { print "FALSE: '$value'\n"; next; } print "FALSE\n"; } } |
Eens. Sowieso denk ik dat mensen die het bovenstaande een beetje kunnen lezen al OO kunnen programmeren. Als je een complete leek bent snap je er niks van, want dan snap je nog geeneens wat een functie is, wat return types zijn, wat parameters zijn, etcetera.quote:Op donderdag 24 januari 2008 10:30 schreef Anthraxx het volgende:
Persoonlijk vind ik het handiger om OOP uit te leggen met een taal die daar wel voor ontworpen is, en niet met een taal dat het er later bij heeft gehackt (zoals PHP en Perl).
Deze tutorial is niet voor totale leken maar voor mensen die wel een beetje kunnen scripten maar het OO denken niet onder de knie krijgen.quote:Op donderdag 24 januari 2008 10:34 schreef Aibmi het volgende:
[..]
Eens. Sowieso denk ik dat mensen die het bovenstaande een beetje kunnen lezen al OO kunnen programmeren. Als je een complete leek bent snap je er niks van, want dan snap je nog geeneens wat een functie is, wat return types zijn, wat parameters zijn, etcetera.
Omdat PHP een ranzige kuttaal is?quote:Misschien dat een enkele PHP-scripter dit niet snapt, maar dan vraag ik me af waarom dit voorbeeld niet in PHP is
PHP'er? Ik?quote:Op donderdag 24 januari 2008 11:18 schreef slacker_nl het volgende:
Perl is geen ranzige kuttaal! Vieze PHP'er.
Perl heeft zeker z'n toepassingen, maar om het nu een mooie taal te noemen...quote:Op donderdag 24 januari 2008 11:43 schreef Farenji het volgende:
Perl is mijn lievelingstaal, niet zonder reden, maar we gaan hier niet discussieren daarover.
Tja, als je echt OO wilt uitleggen dan kan je dat beter doen aan de hand van b.v. Java. Met als voordeel dat dat een taal is die echt bedoelt is om OO in te proggen en dat de syntax ook nog enigszins leesbaar is, zeker in vergelijking met die Perl meuk.quote:Wat ik me afvraag: moet ik hier nog tijd in steken of heeft iedereen zoiets van: "mwoa"? Want dan houd ik mijn kwaliteitscode wel lekker voor mezelf!
Voordeel van een echt OO taal is dat alles OO is, dus zonder losse functies als join/chop/keys die natuurlijk methoden op een object horen te zijn.quote:Op donderdag 24 januari 2008 20:19 schreef Aaargh! het volgende:
Tja, als je echt OO wilt uitleggen dan kan je dat beter doen aan de hand van b.v. Java. Met als voordeel dat dat een taal is die echt bedoelt is om OO in te proggen en dat de syntax ook nog enigszins leesbaar is, zeker in vergelijking met die Perl meuk.
Of primitivesquote:Op vrijdag 25 januari 2008 13:39 schreef SuperRembo het volgende:
Voordeel van een echt OO taal is dat alles OO is, dus zonder losse functies als join/chop/keys die natuurlijk methoden op een object horen te zijn.
PHP is nog triester dan Perl.quote:Op donderdag 24 januari 2008 20:02 schreef Farenji het volgende:
Ok, dat is dan duidelijk.
Stelletje php dummies.
Tja ik vrees inderdaad dat ik al te lang met perl werk - dan vergeet ik dat vreselijke geworstel dat ik in het begin had om bijv iets als references te begrijpen. Maar als ik helemaal onderaan begonnen met uitleggen was dan had ik 10 keer zoveel ruimte nodig gehad. Dan verwijs ik liever naar Leer hier Perlquote:Op vrijdag 25 januari 2008 13:39 schreef SuperRembo het volgende:
Als je OO wil uitleggen dan zou ik met een eenvoudiger voorbeeld beginnen. Ik ken Perl een beetje, maar hier zie ik door de (cryptische) string/hash/etc handling de OO niet meer. Al het gedoe als "my $classname = shift" in een "constuctor" en "my $self = shift" in een "method" sneeuwt daardoor onder.
Dit is het objectmodel:quote:Voor dat je met die lappen code komt, had je eigenlijk moeten uitleggen hoe de objectenstructuur in gedachten hebt. Een diagrammetje erbij zou verhelderend werken. Ik vraag me af of deze structuur OO-technisch gezien wel handig in elkaar steekt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | my $self = shift; return $self->SUPER::getChildren( key => 'artistID', class => 'Song', ); } sub getAlbum { my $self = shift; return $self->SUPER::getParent( key => 'albumID', class => 'Album', ); } |
1 2 3 4 5 6 7 8 | my $self = shift; my @albums = map { $_->getAlbum } @{$self->getSongs}; return \@albums; } |
Niks mis met null termininated literals.quote:Voordeel van een echt OO taal is dat alles OO is, dus zonder losse functies als join/chop/keys die natuurlijk methoden op een object horen te zijn.
|
Forum Opties | |
---|---|
Forumhop: | |
Hop naar: |