Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]12603[/thread]

Decorator in Perl?

Leser: 22


<< |< 1 2 >| >> 19 Einträge, 2 Seiten
Ronnie
 2008-10-08 16:45
#115275 #115275
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
In Python kann man relativ einfach Decorator für Funktionen definieren. Ein Decorator ist nichts gänzlich anderes als ein Wrapper um eine Funktion. Ein vereinfachtes Beispiel in Perl sähe so aus:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl

use strict;
use warnings;

sub hello_world {
    my $from = shift;
    return "Hello World from " . $from;
}

sub decorate_h1 {
    my $sub     = shift;
    return sub { my @args = @_; return "<h1>" . $sub->(@args) . "</h1>" };
}

my $hello_headline = decorate_h1(\&hello_world);

print $hello_headline->("Perl"), "\n";

Das ist natürlich kein richtiger Decorator, sondern nur ein Wrapper. Für einen Decorator wäre es notwendig mit der erzeugten anonymen Funktion die Symboltabelle von hello_world zu überschreiben.

Ich hatte lange vermutet, dass die Attribute in Perl als Decorator verwendet werden, bin aber aus der Doku nicht schlau geworden. Hat jemand ein Beispiel wie man einen Decorator sinnvollerweise in Perl implementiert? Muss man wirklich die Symboltabelle manipulieren, oder geht es auch eleganter?
Ronnie
 2008-10-08 17:03
#115276 #115276
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Eine Möglichkeit die ursprünglische Funktion zu ersetzen habe ich schon gefunden:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
sub real_decorate_h1 {
    my $sub     = shift;
    my $subname = Sub::Identify::sub_name( $sub );
    Sub::Install::reinstall_sub({
        code => sub { my @args = @_; return "<h1>" . $sub->(@args) . "</h1>" },
        as   => $subname,
    });
    return;
}

Lieber wäre mir das ganze aber wenn es syntaktisch so möglich wäre:
Code (perl): (dl )
1
2
3
sub hello_world :decorate_h1 {
    # yada yada yada
}

So das man bedarfsweise nur das Attribut entfernen muss?!
LanX-
 2008-10-08 17:13
#115277 #115277
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Hi Ronnie

ich weiß nicht hundertprozentig was Decoratoren von anderen Konstrukten mit sub_refs auszeichnet, ein Beipsiel in Python würde mir vielleicht helfen.

Aber hast du mir nicht Higher Order perl ans Herz gelegt?

Als ich's im Buchladen durchgeblättert habe fanden sich da zig Ansätze um Funktionen zu manipulieren, AFAIR wurde auch eine Metafunktion gebastelt die dir die Frickelarbeit abnimmt, sodass du syntaktische Einfachheit hast.

Irgendwo da wo auch was über Currying stand ...

Bye
Rolf
LanX-
 2008-10-08 17:20
#115278 #115278
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
OK nach näherer Ansicht deines Codes, denke ich du willst ungefähr sowas

sub decorate (\&decorator, \&func) {}

Mit Prototypgeschick wirds syntaktisch einfach, du schreibst dann nur noch so was

decorate {...code ...} &func;

das ändern der Symboltabelle passiert dann intern in decorate().
Ronnie
 2008-10-08 17:22
#115279 #115279
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Hallo Rolf,
LanX-+2008-10-08 15:13:38--
ich weiß nicht hundertprozentig was Decoratoren von anderen Konstrukten mit sub_refs auszeichnet, ein Beipsiel in Python würde mir vielleicht helfen.

Code: (dl )
1
2
3
4
5
6
@memoized
def fib(n):
if n==1 or n==2:
return 1
else:
return fib(n-1) + fib(n-2)

Wenn man den Decorator @memoized weg lässt, würde die Funktion klassisch rekursiv ablaufen. Mit Decorator wird gecached (Beispiel findet sich auch im HOP in Perl).
LanX-+2008-10-08 15:13:38--
Aber hast du mir nicht Higher Order perl ans Herz gelegt?

Als ich's im Buchladen durchgeblättert habe fanden sich da zig Ansätze um Funktionen zu manipulieren, AFAIR wurde auch eine Metafunktion gebastelt die dir die Frickelarbeit abnimmt, sodass du syntaktische Einfachheit hast.

Ja, mein zweiter Post macht im Prinzip schon genau das was es soll. Jetzt geht es nur noch um ein wenig syntactic-sugar.

Gruß,
Ronnie

PS.: Wir sollten mal über einen neuen darmstadt.pm Termin nachdenken!
LanX-
 2008-10-08 17:34
#115280 #115280
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Termin:
ich wollte einfach für nächsten Donnerstag einladen, Probleme?

Wahrscheinlich treffe ich Alech heut abend und kann ihn auch fragen.

Thread:
Beim obigen Beispiel bin ich mir mit dem Prototype nicht sicher,
kann sein dass man die backslashes weglassen kann. Ziel ist es
explizites Sub und Referenzieren im Syntax einzusparen.

Siehe auch perlsub

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
And here’s a reimplementation of the Perl "grep" operator:

           sub mygrep (&@) {
               my $code = shift;
               my @result;
               foreach $_ (@_) {
                   push(@result, $_) if &$code;
               }
               @result;
           }


kann auch sein das man die zu decorierende Sub besser als Typeglob übergibt ,sollte alles im HoP stehen...
Ronnie
 2008-10-08 17:47
#115282 #115282
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Hallo Rolf,
LanX-+2008-10-08 15:34:56--
Termin:
ich wollte einfach für nächsten Donnerstag einladen, Probleme?

Wahrscheinlich treffe ich Alech heut abend und kann ihn auch fragen.

Ein anderer Wochentag wäre mir lieber, wenn möglich. Ansonsten geht auch DO.

Gruß,
Ronnie
LanX-
 2008-10-08 17:57
#115284 #115284
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
PM:
Wegen der Möglichkeit verlängerter WEs würd ich gerne Mittwoch vorschlagen!
Deine Preferenz war Montag, oder?

Ich mail heut abend auf der Liste, nachdem ich den letzten Bericht im Wiki eintrage.

Thema:
eventuell könnte man es sogar mit Attribuite Handlern basteln
http://perldoc.perl.org/Attribute/Handlers.html#EX...

ist alles natürlich alles etwas komplexer als in Py.
Ronnie
 2008-10-08 18:17
#115300 #115300
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Hallo Rolf,
LanX-+2008-10-08 15:57:22--
Wegen der Möglichkeit verlängerter WEs würd ich gerne Mittwoch vorschlagen!
Deine Preferenz war Montag, oder?

MO wäre gut. Eben gesehen das MI leider gar nicht geht, wegen Familienfeier. Zur Not also doch DO.
LanX-+2008-10-08 15:57:22--
Thema:
eventuell könnte man es sogar mit Attribuite Handlern basteln
http://perldoc.perl.org/Attribute/Handlers.html#EX...

Ich schaue es mir nochmal im Detail an. Es wäre jedenfalls syntaktisch am elegantesten.

Gruß,
Ronnie
LanX-
 2008-10-08 18:30
#115303 #115303
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Hi Ronnie
Ronnie+2008-10-08 16:17:44--
Ich schaue es mir nochmal im Detail an. Es wäre jedenfalls syntaktisch am elegantesten.


ähm also ich persönlich finde so ne Lösung
Code (perl): (dl )
DECORATE { wrappercode } *func ;


oder ähnlich lesbarer als mit Attributen. Ich denke du bist es halt von Py so gewöhnt.

was ich gerne mit ATTR hätte wären hingegen Docstrings, Conway hat mal sowas gebastelt aber AFAIR mit Codefilter ...

Ronnie+2008-10-08 16:17:44--
MO wäre gut. Eben gesehen das MI leider gar nicht geht, wegen Familienfeier. Zur Not also doch DO.


Jeden MI Familienfeier ? ;-)

Ich versuch für diesen MO einzuladen und dann bequatschen wirs am besten dort, Renee und Alech haben beide IMHO schon signalisiert das ihnen alles außer DI recht wäre!
<< |< 1 2 >| >> 19 Einträge, 2 Seiten



View all threads created 2008-10-08 16:45.