Schrift
[thread]5786[/thread]

Perl +OOP (Seite 2)

Tags: Ähnliche Threads

Leser: 2


<< |< 1 2 3 >| >> 27 Einträge, 3 Seiten
Ronnie
 2003-10-01 23:48
#59451 #59451
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=pq,01.10.2003, 12:50]ich kann da nur Damian Conway: Object Oriented Perl empfehlen.[/quote]
die englische, oder auch die deutschsprachige Ausgabe?
Geewiz
 2003-10-02 00:20
#59452 #59452
User since
2003-09-29
69 Artikel
BenutzerIn
[Homepage] [default_avatar]
Eine ähnliche Frage kam auch schon mal im Perl-Kloster auf, und der Diskussionsverlauf war auch sehr ähnlich. :-)

Link: Perl Monks\n\n

<!--EDIT|Geewiz|1065039872-->
Geewiz
 2003-10-02 00:22
#59453 #59453
User since
2003-09-29
69 Artikel
BenutzerIn
[Homepage] [default_avatar]
[quote=Ronnie,01.10.2003, 21:48]die englische, oder auch die deutschsprachige Ausgabe?[/quote]
Wo nichts übersetzt wird, schleichen sich auch keine Übersetzungsprobleme ein. Man sollte Bücher wo immer möglich im Original lesen. Conway auf Englisch, Shakespeare auf Klingonisch.
Geewiz
 2003-10-02 00:39
#59454 #59454
User since
2003-09-29
69 Artikel
BenutzerIn
[Homepage] [default_avatar]
[HR
Doomrunner,01.10.2003, 12:23]Für welche Zwecke haltet Ihr OOP für Vorteilhafter?

OOP ist immer da sinnvoll, wo auf bestimmte Daten bestimmte Operationen ausgeführt werden. In Form einer Klasse können dann Daten (Attribute genannt) und Operationen (Methoden genannt) vereinigt werden. Gibt es dann Situationen, wo Attribute und Methoden anders, aber verwandt und ähnlich sind, kommt Vererbung zum Einsatz.

In deinem Datumsbeispiel könnte man zB eine Basisklasse "Datum" erstellen, die Operationen wie Zuweisung, Ausgabe und Umwandlung in Unix-Timestamp kann. Ableiten könnte man Subklassen für die Datumsformate verschiedener Länder. So gäbe es in jeder Klasse der Datum-Familie die Methoden "get" und "print". Datum::English liefert damit aber das Datum in anderem Format wie Datum::Deutsch.

Das Ergebnis für den Klassen-Anwender: wenn ich mich beim Erzeugen eines Datums mal fur ein bestimmtes Format entschieden habe, kann ich -- salopp gesagt -- diese Entscheidung eigentlich wieder vergessen, denn es wird dann in jedem Fall $datum->get() und $datum->print() benutzt.

Die Programmiererin hingegen muss für die Subklassen auch nur diese beiden Methoden neu schreiben, die interne Speicherung des Datums oder die Umwandlung in Unix-Timestamp kann unverändert von der Basisklasse übernommen werden.

So macht OOP die Programmierung wiederkehrender und ähnlicher Lösungen einfacher und übersichtlicher.
[HR]Doomrunner
 2003-10-02 09:07
#59455 #59455
User since
2003-09-04
77 Artikel
BenutzerIn
[default_avatar]
Danke für die regen Beiträge. Ich finde die Sache mit der OOP sehr interessant und werde mich auf jeden Fall weiter damit beschäftigen.

Ist gerade für Dinge schön, die man eh ständig in jedem Script durchführen muss. Deshalb habe ich auch das Beispiel mit dem Datum genommen. Finde das eigentlich sehr schön. So kann man sich eine schöne Bibliothek schreiben.

Ausserdem muß ich das an der Uni demnächst eh in anderen Programmiersprachen lernen. Wieso also nicht erst in Perl?! :-)

@Geewiz: Könntest du dir vielleicht bitte die Mühe machen und einen Beispielcode dazu schreiben? Denke, dass ich da ziemlich gut von lernen könnte. DS hat das ja bis dahin schon schön bereitgestellt. Wäre bestimmt nicht sehr viel Code, den du dazuschreiben müsstest.

@DS: Ist es Sinnvoll, das gesamte Modul direkt beim "new" durchführen zu lassen? Ist es stilistisch nicht schöner das ganze getrennt zu machen? So dass ich dann z.B. $blablabla->jetzt("datum") aufrufe? Und was soll diese AUTOLOAD Methode? Wann wird die aufgerufen? Hoffe, dass die Fragen nicht zu doof sind ;-)

Danke\n\n

<!--EDIT|
Doomrunner|1065071778-->
Geewiz
 2003-10-02 12:22
#59456 #59456
User since
2003-09-29
69 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja, ein Beispiel mache ich gern:

Code: (dl )
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package Datum;
use base qw( Exporter );

our EXPORT = qw ();

sub new {
# neue Instanz erzeugen

my $class = shift;
$class = ref($class) if ref($class);

# Datumswerte werden einzeln gespeichert
my $self = {
year => 0,
month => 0,
day => 0,
};
bless $self, $class;

return $self;
}

sub set {
# Datumswerte setzen
# Parameter-Reihenfolge nach ISO

my $self = shift;
my ($y, $m, $d) = @_;

$self->{year} = $y;
$self->{month} = $m;
$self->{day} = $d;
}

sub dateformat {
# Datumsformat der Klasse liefern
return "%y-%m-%d";
}

sub get {
# Datum abfragen
# ISO-Format

my $self = shift;

my $date = $self->dateformat();

$date =~ s/%y/$self->{year}/g;
$date =~ s/%m/$self->{month}/g;
$date =~ s/%d/$self->{day}/g;

return $date;
}

sub tounixtime {
my $self = shift;

my $unixtime = ...
return $unixtime;
}

sub print {
my $self = shift;

print $self->get();
}

1;

package Datum::DE;
use base qw( Datum );

sub dateformat {
return "%m/%d/%y";
}

1;

package Datum::US;
use base qw( Datum );

sub dateformat {
return "%d.%m.%y";
}

1;

package main;

my $gerdate = new Datum::DE(2003, 10, 2);
$gerdate->print();

my $usdate = new Datum::US(2003, 10, 2);
$usdate->print();


Ich möchte vor allem darauf hinweisen, dass ich mir in den Subklassen nicht nur die Neuprogrammierung von new(), set(), get(), tounixtime() und print() sparen konnte.

Da ist noch ein verstecktes Bonbon: get() verwendet ja dateformat(), und das ist in jeder Klasse eine andere Funktion. Dennoch muss ich wegen dieser Mehrdeutigkeit get() nicht in jeder Subklasse neu schreiben. Perl kümmert sich darum, dass die dateformat() Methode der jeweils eigenen Klasse benutzt wird. Das nennt sich "Polymorphismus".

HTH!
[HR]Doomrunner
 2003-10-02 14:22
#59457 #59457
User since
2003-09-04
77 Artikel
BenutzerIn
[default_avatar]
Hey, das ist ja richtig klasse mit dem Polymorphismus. Jetzt habe ich endlich mal einen fetten Vorteil der OOP gesehen.

Habe mir auch schon meine ersten Klassen fertig gemacht und in bestehende Projekte eingebunden. Ist echt ne feine Sache, wenn man die *.pm's einfach in den lib ordner legen kann, und jedes Perl-Script die dann einbinden kann :-)
Crian
 2003-10-23 13:18
#59458 #59458
User since
2003-08-04
5873 Artikel
ModeratorIn
[Homepage]
user image
Ein Tipp - man sollte nach möglichkeit sowohl in der Klasse als auch von außerhalb nicht direkt auf den Hash zugreifen, sondern Setter / Getter dafür verwenden.

Mit einem Tipp aus Peter Wainwrght et al "professional Perl programming" spart man sich viel Arbeit, wenn man das dann so abkürzt:

Code: (dl )
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
sub _property ($$;$) {
    my $self   = shift;    # object
    my $attr   = shift;    # attribute to get or set
    my $setter = @_ == 1;  # is this method used as a setter?
    my $value  = shift;    # value for the setter

    # if we use "if (defined $value)" here, we can't set the values
    # to undef! So we have to use this:
    if ($setter) {
        my $old_value = $self->{$attr};
        $self->{$attr} = $value;
        return $old_value;
    }
    else {
        return $self->{$attr};
    }
} # sub _property


sub uhrzeit ($;$) { return shift->_property('uhrzeit', @_) }
sub stunden ($;$) { return shift->_property('stunden', @_) }
sub minuten ($;$) { return shift->_property('minuten', @_) }
sub sekunden($;$) { return shift->_property('sekunden', @_) }
sub datum   ($;$) { return shift->_property('datum', @_) }
sub tag     ($;$) { return shift->_property('tag', @_) }
sub monat   ($;$) { return shift->_property('monat', @_) }
sub jahr    ($;$) { return shift->_property('jahr', @_) }
...


:-)\n\n

<!--EDIT|Crian|1066900877-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Strat
 2003-10-23 13:55
#59459 #59459
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
Viele Sachen wurden eh schon gesagt, aber ich loesche jetzt nichts...

1.
Code: (dl )
1
2
3
4
5
6
sub new {
my $objekt = shift;
my $referenz = {};
bless($referenz,$objekt);
return($referenz);
}

wuerde ich schreiben als:
Code: (dl )
1
2
3
4
5
6
sub new {
my $class = shift;
my $referenz = {};
bless($referenz,$class);
return($referenz);
}

denn der erste Parameter ist die Klasse (genauer gesagt: das Package), und das Objekt wird erst durch bless erzeugt

2. Du verwendest localtime(time) in skalarem Kontext, was eine Zeichenkette zurueckgibt. Ich weiss nicht, ob die unter allen Umstaenden immer im gleichen Format zurueckkommt, habe jedoch gelernt, auf solche Sachen moeglichst wenig zu vertrauen. Ich verwende da lieber:
Code: (dl )
1
2
3
my @zeit = localtime(time);
$zeit[4]++; # monat beginnt bei 0 fuer januar
$zeit[5]+=1900; # jahr 0 ist 1900

Dann hast du in @zeit: (sek, min, stunde, tag, monat, jahr, wochentag, tagDesJahres, IstSommerzeitAktiv)
$zeit[6] : 0 ist Sonntag, 1 ist Montag, ...

3. Namensraeume immer Gross schreiben, also Crs, weil die kleine schreibweise (crs) fuer pragmata (wie strict, warnings, ...) reserviert ist.

4.
return bless(&jetzt,ref($klasse) || $klasse || _ _PACKAGE_ _);
das ist natuerlich ein Overkill; er ermoeglicht, dass die Leute den Konstruktor irgendwie aufrufen koennen, und immer ein korrektes Objekt zurueckkommt; ich weiss jedoch nicht, ob das immer sinnvoll ist. Wenn jemand meine Klasse als reine funktion aufrufen will, soll ihm das teil solange um die Ohren fliegen, bis er lernt: my $object = Class->new(...)
also return bless($object, $klasse);

Code: (dl )
sub _property ($$;$) {

ich glaube mal gehoert zu haben, dass Prototypen bei einem Methodenaufruf nicht ausgewertet werden, sondern nur bei einem funktionalen Aufruf ohne das fuehrende &
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
pq
 2003-10-23 14:09
#59460 #59460
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
[quote=Crian,23.10.2003, 11:18]
Code: (dl )
1
2
sub _property ($$;$) {
    my $self   = shift;    # object
[/quote]
und die prototypen kannst du gleich rausnehmen, das haben wir ja gestern
gelernt, dass die hier nichts bewirken =)
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
<< |< 1 2 3 >| >> 27 Einträge, 3 Seiten



View all threads created 2003-10-01 14:23.