Schrift
[thread]8932[/thread]

Role VS. Mixin?: Die Rolle des Elchs



<< >> 5 Einträge, 1 Seite
Ronnie
 2007-04-20 01:22
#76063 #76063
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Nachdem ich mir diesen Teil des Elch-Kochbuchs betrachtet habe ist mir der Unterschied zwischen Roles und Mixins nicht klar. Ist dieser nur semantischer Natur, oder übersehe ich irgendwas völlig?\n\n

<!--EDIT|Ronnie|1177017787-->
Ronnie
 2007-04-20 01:44
#76064 #76064
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ah, dieser Artikel von chromatic hilft: http://www.oreillynet.com/onlamp....je.html
Ronnie
 2007-04-21 20:16
#76065 #76065
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Okay, hier mal ein Beispiel für die Möglichkeiten, die wir mit Perl6 und Roles bzw. Moose und Roles bekommen. Roles erlauben uns Methoden an Klassen zu binden, die bestimmte Voraussetzungen erfüllen. Man könnte Vergleichbares durch Mehrfachvererbung erreichen, aber Roles sind eleganter, da sie völlig unterschiedliche Klassen um eine bestimmte Funktionalität erweitern.

Hier ein Beispiel für eine Role:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/perl

use strict;
use warnings;

package RoleDigraph;
use Moose::Role;

requires '_as_queque';

sub as_digraph {
my $self = shift;
my @queque = @{$self->_as_queque};
my $o = 'digraph G {' . "\n";
$o .= "\t" . $_->[0] . ' -> ' . $_->[1] . ";\n" for @queque;
$o .= "}\n";
return $o;
}

1;

Wie man sieht haben wir nur eine Methode, keine Instanzvariablen etc. Die Role benötigt eine Methode _as_queque() die von der Klasse angeboten werden muss, die die Role einbinden will. Diese Klasse wird dann um die Methode as_digraph() erweitert, die aus einer Liste von Tupeln (als Queque bezeichnet) einen Digraph erzeugt, wie er mit http://www.graphviz.org/ dot visualisiert werden kann.

Hier jetzt zwei Beispiele in denen die Role in die Klasse eingebunden wird, um deren Funktionalität zu erweitern. Das Baum-Beispiel (aus einem relativ aktuellen Thread im Forum) ist nur bedingt geeignet, weil der Baum als Graph nur teilweise richtig visualisiert werden kann:
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
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

package BinTree;
use Moose;
with 'RoleDigraph';

use overload '""' => \&to_s;

has 'val' => ( is => 'rw', isa => 'Num' );
has 'l' => ( is => 'rw');
has 'r' => ( is => 'rw');

sub _set_l {
my $self = shift;
my $val = shift;

if (blessed $self->l) { $self->l->append($val); }
else { $self->l($self->new(val => $val)); }
}

sub _set_r {
my $self = shift;
my $val = shift;

if (blessed $self->r) { $self->r->append($val); }
else { $self->r($self->new(val => $val)); }
}

sub to_s {
my $self = shift;
my $v = $self->val;
my $l = blessed $self->l ? $self->l->to_s : undef;
my $r = blessed $self->r ? $self->r->to_s : undef;
return join ', ', grep defined, ($l, $v, $r);
}

sub append {
my $self = shift;
my @vals = @_;
while ( my $n = shift @vals ) {
if ($n < $self->val) { $self->_set_l($n) }
elsif ($n > $self->val) { $self->_set_r($n) }
}
}

sub _as_queque {
my $self = shift;
my $queque = shift || [];

my $v = $self->val;

if (blessed $self->l) {
push @$queque, [$v, $self->l->val];
$self->l->_as_queque($queque);
}

if (blessed $self->r) {
push @$queque, [$v, $self->r->val];
$self->r->_as_queque($queque);
}

return $queque,
}

package main;

my @list = (20, 4, 28, 9, 100, 12, 84, 10, 11);
my $tree = BinTree->new( val => shift @list );
$tree->append(@list);
$tree->append(1, 50, 200);

print $tree . "\n" x 2;
print $tree->as_digraph;

http://www.ronnie-neumann.de/trashbin/tree.png

In dem zweiten Beispiel wird ein einfaches Soziogramm aus einem Logfile erstellt:
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
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

package Event;
use Moose;

has 'source' => ( is => 'rw', isa => 'Str' );
has 'destination' => ( is => 'rw', isa => 'Str' );
has 'id' => ( is => 'rw', isa => 'Num' );

package LogAnalyzer;
use Moose;
with 'RoleDigraph';

has 'events' => ( is => 'rw', isa => 'ArrayRef' );

sub parse_line {
my $self = shift;
my $line = shift;
chomp($line);

my ($s) = $line =~ m/source:(\w+)\s*/; # we ignore the domains
my ($d) = $line =~ m/destination:(\w+)\s*/;
my ($id) = $line =~ m/id:(\w+)\s*/;

my $event = Event->new(
source => $s,
destination => $d,
id => $id
);

push @{$self->{events}}, $event;
}

sub _as_queque {
my $self = shift;
my $queque = [];

@$queque = map { [$_->source, $_->destination] } @{$self->events};

return $queque;
}

package main;

my $al = LogAnalyzer->new;
$al->parse_line($_) while (<DATA>);
print $al->as_digraph;

__DATA__
source:joe@example.com destination:bob@example.com id:685421
source:bob@example.com destination:tim@example.com id:685424
source:joe@example.com destination:tina@example.com id:685429
source:tim@example.com destination:bob@example.com id:685431
source:tina@example.com destination:bob@example.com id:685441
source:joe@example.com destination:bob@example.com id:685452

http://www.ronnie-neumann.de/trashbin/sozio.png

Wie man sieht, werden beide Klassen elegant um ein und dieselbe Methode erweitert, auch wenn es völlig unterschiedliche Klassen und Anwendungen sind.\n\n

<!--EDIT|Ronnie|1177172450-->
pq
 2007-04-22 15:49
#76066 #76066
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
sehr schön, hättest du lust, das mal ins wiki zu stellen?
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
Ronnie
 2007-04-22 16:06
#76067 #76067
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=pq,22.04.2007, 13:49]sehr schön, hättest du lust, das mal ins wiki zu stellen?[/quote]
Mit dem Wiki bin ich in der Vergangenheit nicht sonderlich gut klar gekommen. Ich kann es aber mal probieren. Nur brauche ich, glaube ich, neue Zugangsdaten. Ich wollte schrittweise noch mehr zu Moose und seinen Möglichkeiten zeigen, evtl. auch in Renées $foo-Magazin. Allerdings muss ich vieles selbst noch ausprobieren. Vielen Dank nochmal an phaylon für seine Anregungen.
<< >> 5 Einträge, 1 Seite



View all threads created 2007-04-20 01:22.