Schrift
[thread]10937[/thread]

Erst Schritte OOP

Tags: Ähnliche Threads

Leser: 2


<< |< 1 2 >| >> 11 Einträge, 2 Seiten
styx-cc
 2007-12-01 19:00
#103356 #103356
User since
2006-05-20
533 Artikel
BenutzerIn

user image
Halli hallo,
da ich gerade mal ne Woche schulfrei habe, wollte ich mich was Perl angeht etwas weiterbilden und die OOP (mit der ich bis auf ein wenig Java noch nie was zu tun hatte) erlernen. Dazu habe ich mir das Buch "Perl-Objekte, Referenzen & Module" unters Kopfkissen gepackt und versuche nun die Uebung aus Kapitel 9 zu meistern.
Erstmal der Source von der ersten Uebung, auf die die zweite aufsetzt:
Code (perl): (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
#!/usr/bin/perl -w
use strict;

{package Animal;
  sub named {
    my $class = shift;
    my $name = shift;
    bless \$name, $class;
  }

  sub name {
    my $self = shift;
    #is self an object or a class
    ref $self ? $$self : "unnamed $self";
  }

  sub speak {
    my $self = shift;
    print $self->name ." goes ". $self->sound() .".\n";
  }
}

{package Horse;
  use base qw/Animal/;
  sub sound {'neiggghhhh'};
}

{package Mouse;
  use base qw/Animal/;
  sub sound {'Meep'};
  #overwrite speak
  sub speak {
    my $class = shift;
    $class->SUPER::speak(@_);
    print "[But you can barely hear it]\n";
  }
}

print "Choose between the following animals,\nseperate them by space:\n";
my %animals = (Horse => 0, Mouse => 0);
print join(" ", sort keys %animals) ."\n\n";
chomp(my $user_animals = <STDIN>);

my @user_animals = split/ /, $user_animals;
for (@user_animals) {
  $_ = ucfirst($_);
   if(exists($animals{$_})) {$animals{$_}++};
}

while ( my ($key, $value) = each(%animals) ) {
  my $tmp = $key->named('Test');
  $tmp->speak for(1..$value);
}


Das funktioniert auch alles ganz toll, es geht nur darum Tiere mit verschiedenen Namen und Ausgaben zu erzeugen, aber zwei Punkte der Uebungsaufgabe bekomme ich alleine nicht hin.
Die Aufgabe lautet (auf den oben gelisteten Source bezogen):
[ul]
[li]Auf der Ebene wie "Animal" eine Klasse "Person" hinzufuegen[/li]
[li]Beide Klassen v. neuer Klasse "LivingCreature" erben lassen[/li]
[li]Erweitern der Methode speak, so dass ein Parameter uebergeben werden kann, indem festgelegt wird was gesagt wird - Tiere duerfen keine Parameter entgegen nehmen[/li]
[li]Benutzungsfehler wie z.B. eine vergessene Definition v. sound abfangen[/li]
[/ul]

Also hab ich mich ebend hingesetzt und das produziert:
Code (perl): (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
#!/usr/bin/perl -w
use strict;

{package LivingCreature;
  sub named {
    my $class = shift;
    my $name = shift;
    bless \$name, $class;
  }

  sub name {
    my $self = shift;
    #is self an object or a class
    ref $self ? $$self : "unnamed $self";
  }

  sub speak {
    my $self = shift;
    my $sound = shift;
    if($self eq '') {
    
    }
    print $self->name ." goes ". $self->sound($sound) .".\n";
  }
}

{package Person;
  use base qw/LivingCreature/;
  sub sound {
    my $self = shift;
    my $sound = shift;
    $sound ? $sound : 'Hmmm';
  }
}

{package Animal;
  use base qw/LivingCreature/;
}

{package Horse;
  use base qw/Animal/;
  sub sound {'neiggghhhh'};
}

{package Mouse;
  use base qw/Animal/;
  sub sound {'Meep'};
  #overwrite speak
  sub speak {
    my $class = shift;
    $class->SUPER::speak(@_);
    print "[But you can barely hear it]\n";
  }
}

my $p1 = Person->named('Edgar');
my $h1 = Horse->named('Mr. Ed');
my $p2 = 'Person';

$h1->speak;
$p1->speak;
$p1->speak('Hello World :D');
$p2->speak;
$p2->name;


So, nun habe ich drei Fragen:
1.
Code (perl): (dl )
1
2
3
20:     if($self eq '') {
21:     
22:     }

wie kann ich da abfragen, ob ein Animal oder eine Person spricht bzw. ist das ueberhaupt die richtige Stelle um das zu pruefen?

2. Wie kann ich die Benutzungsfehler abfangen, wenn man in einer Unterklasse z.B. vergisst sound zu definieren (ein Tipp reicht mir, dann hab ich wenigstens noch was zu tun)?

3. Wenn einem Animal ein Parameter fuer die Methode speak (Animal::speak(@args)) bekommt habe ich mir gedacht zu warnen und das Programm zu beenden. Wie warne ich am besten?
Ich seh immer wieder dieses croak, kann mir jemand erklaeren was es damit auf sich hat? Das frage ich mich schon ewigkeiten.
Oder einfach mit einem die()?
Oder ein print und exit?

Und wenn jemand große Langeweile hat, kann er mir ja auch noch sagen was fuer Schoenheitsreperaturen noetig sind damit das vernueftig aussieht, wuerde mich freuen.

Vielen Dank fuer die Muehe sich das durchgelesen zu haben ;-)

MfG
Pörl.
styx-cc
 2007-12-01 19:26
#103358 #103358
User since
2006-05-20
533 Artikel
BenutzerIn

user image
So, das mit dem sound hab ich so halbwegs schoen hinbekommen, aber gefaellt mir irgendwie immer noch nicht:
Ich hab in der Klasse "LivingCreature" "Carp" mit use eingebunden und folgende Methode hinzugefuegt:
Code: (dl )
1
2
3
4
  sub sound {
my $self = shift;
croak($self->name ." hasn't got a sound-method");
}


An die stelle kommt das Programm ja nur, wenn die Unterklasse keine Methode sound bereithaelt (hoffe ich)

MfG

edit: In Bezug auf "croak" und Carp bin ich auch etwas schlauer geworden..

The Carp routines are useful in your own modules because they act like die() or warn(), but with a message which is more likely to be useful to a user of your module.[...]
http://perl.active-venture.com/lib/Carp.html
Pörl.
Lightman
 2007-12-01 20:47
#103361 #103361
User since
2007-01-31
57 Artikel
BenutzerIn
[default_avatar]
Mal eine Off-Topic-Frage: Für was sollen eigentlich die geschweiften Klammern am Anfang und Ende jedes Blockes gut sein?
Code (perl): (dl )
1
2
3
4
{package Horse;
    use base qw/Animal/;
    sub sound {'neiggghhhh'};
}
styx-cc
 2007-12-01 20:54
#103362 #103362
User since
2006-05-20
533 Artikel
BenutzerIn

user image
Musst du mal den autor meines buches fragen =)
Pörl.
Mates
 2007-12-01 22:23
#103365 #103365
User since
2006-08-15
21 Artikel
BenutzerIn
[default_avatar]
Hmm gut zu wissen, das das geht. Denn wenn es keine sonderlichen Nachteile bringt, ists zum programmieren mit entsprechenden Editoren ganz praktisch, da kannst dann solche Gruppen "minimieren" und die Übersicht verbessern
renee
 2007-12-01 23:03
#103368 #103368
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Lightman+2007-12-01 19:47:49--
Mal eine Off-Topic-Frage: Für was sollen eigentlich die geschweiften Klammern am Anfang und Ende jedes Blockes gut sein?
Code (perl): (dl )
1
2
3
4
{package Horse;
    use base qw/Animal/;
    sub sound {'neiggghhhh'};
}


Das ist dafür da, die Gültigkeit von Variablen einzuschränken.

Vergleiche:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/perl

use strict;
use warnings;

package Test;
my $i = 9;

package main;
print $i;


mit:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/perl

use strict;
use warnings;

{
    package Test;
    my $i = 9;
}

package main;
print $i;


Es empfiehlt sich, immer die packages auf einen möglichst kleinen Block zu beschränken...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2007-12-01 23:06
#103369 #103369
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
styx-cc+2007-12-01 18:00:24--
So, nun habe ich drei Fragen:
1.
Code (perl): (dl )
1
2
3
20:     if($self eq '') {
21:     
22:     }

wie kann ich da abfragen, ob ein Animal oder eine Person spricht bzw. ist das ueberhaupt die richtige Stelle um das zu pruefen?


Code (perl): (dl )
1
2
3
if( $self->isa( 'Person' ){
    print "\$self ist eine Person\n";
}


Quote
2. Wie kann ich die Benutzungsfehler abfangen, wenn man in einer Unterklasse z.B. vergisst sound zu definieren (ein Tipp reicht mir, dann hab ich wenigstens noch was zu tun)?

Du kannst in der Elternklasse eine "default"-sound-Methode definieren, die stirbt wenn sie aufgerufen wird. Denn das heißt, dass die Subklasse kein "sound" definiert hat

Quote
3. Wenn einem Animal ein Parameter fuer die Methode speak (Animal::speak(@args)) bekommt habe ich mir gedacht zu warnen und das Programm zu beenden. Wie warne ich am besten?
Ich seh immer wieder dieses croak, kann mir jemand erklaeren was es damit auf sich hat? Das frage ich mich schon ewigkeiten.
Oder einfach mit einem die()?
Oder ein print und exit?

Die Antwort hast Du Dir ja selbst gegeben ;)
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
pq
 2007-12-02 04:23
#103377 #103377
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
croak() ist ist da ganz nützlich, denn es gibt dir den kompletten stacktrace mit aus.

edit: stimmt nicht ganz, was croak(), longmess() und shortmess() jeweils ausgeben, ist
etwas esoterisch, abhängig davon, ob der stacktrace über packages hinweggeht. croak()
gibt dir in den meisten fällen nur die callerzeile aus (statt wir bei die() die zeile selbst), was
oft nützlicher ist. mit cluck() kriegst du den kompletten stacktrace.
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
styx-cc
 2007-12-02 05:08
#103378 #103378
User since
2006-05-20
533 Artikel
BenutzerIn

user image
Vielen Dank, klappt wunderbar, alle Fragen geloest =)

MfG

edit:
Guten Morgen!
Pörl.
Gast Gast
 2007-12-02 17:04
#103383 #103383
Lightman+2007-12-01 19:47:49--
Mal eine Off-Topic-Frage: Für was sollen eigentlich die geschweiften Klammern am Anfang und Ende jedes Blockes gut sein?
Code (perl): (dl )
1
2
3
4
{package Horse;
    use base qw/Animal/;
    sub sound {'neiggghhhh'};
}

Erweiternd zu renees Antwort: Hier wird das package nur innerhalb des Blockes verändert, sodass nach dem Block __PACKAGE__ wieder main ist.

MfG Horst
<< |< 1 2 >| >> 11 Einträge, 2 Seiten



View all threads created 2007-12-01 19:00.