Perl Vergleich: Eval aus der Schleife bekommen?

Hallo,
ich habe folgende Situation:
Ich möchte für ein Array eine ganz allgemeine konditionale Auswertungsoperation schreiben, die als „Vergleichsparameter“ irgend etwas bekommen kann.

Mein Code sieht derzeit so aus:

 foreach my $rowValue ($self-\>{dataArray})
 { 
 push(@returnArray,$rowValue) if 
 (eval ("return 1 if $rowValue {$comparisonAction}"));
 }

Das Problem an der Sache ist, dass das ständige Eval in der Schleife eigentlich unnötig ist.
Wie sorge ich dafür, dass ich das ActionPattern nur einmal kompilieren muss und dann vorkompilierten Code in der Schleife nutze?

Danke und Gruss,
Michael

Hallo,

ich habe folgende Situation:
Ich möchte für ein Array eine ganz allgemeine konditionale
Auswertungsoperation schreiben, die als „Vergleichsparameter“
irgend etwas bekommen kann.

Mein Code sieht derzeit so aus:

foreach my $rowValue ($self->{dataArray})
{
push(@returnArray,$rowValue) if
(eval („return 1 if $rowValue {$comparisonAction}“));
}

Das Problem an der Sache ist, dass das ständige Eval in der
Schleife eigentlich unnötig ist.
Wie sorge ich dafür, dass ich das ActionPattern nur einmal
kompilieren muss und dann vorkompilierten Code in der Schleife
nutze?

Du kannst z.B. dynamisch eine Funktion erzeugen, und diese dann immer verwenden:

# Subroutine generieren:
my $comperator = eval 
 'sub { return 1 if ($\_[0] ' . $comparisonAction . ');}';
my @result = grep { &$comperator($\_) } $self-\>{dataArray};

(ungetestet, aber so ähnlich sollte es schon gehen).

Das funktioniert natürlich nur, solange $comparisonAction immer gleich evaluiert (also kein ’

push(@returnArray,$rowValue) if
(eval („return 1 if $rowValue {$comparisonAction}“));

kleine frage am rande: $comparisonAction kommt nicht zufällig als input vom
user, z.b. über den webbrowser? wenn doch, solltest du das ganze noch absichern.

kleine frage am rande: $comparisonAction kommt nicht zufällig
als input vom user, z.b. über den webbrowser? wenn doch, solltest du das ganze noch absichern.

Es geht um ein reines Verwaltungsobjekt, und ich habe einfach keine Lust darauf, so etwas zu basteln:

sub getGreaterResults { if $A > 10 return $A }
sub getInbetweenResults { if $A in (8,9,10) return $A }

da ich etliche Operationen habe, die sich alle lediglich durch die Art des herangezogenen Vergleichs unterscheiden.

Es wird also einzig die übergeordnete Klasse in der Lage sein, das Ding tatsächlich aufzurufen und zu entscheiden wie verglichen wird, aber danke für den Hinweis. Ja, solche Loopholes könnten gefährlich sein :wink:

Gruss,
Michael

Du kannst z.B. dynamisch eine Funktion erzeugen, und diese
dann immer verwenden:

Subroutine generieren:

my $comperator = eval
'sub { return 1 if ($_[0] ’ . $comparisonAction . ‚);}‘;
my @result = grep { &$comperator($_) } $self->{dataArray};

Danke, genau das was ich gesucht habe. Closures. :wink:

Hallo Moritz

Du kannst z.B. dynamisch eine Funktion erzeugen, und diese
dann immer verwenden:

Subroutine generieren:

my $comperator = eval
'sub { return 1 if ($_[0] ’ . $comparisonAction . ‚);}‘;
my @result = grep { &$comperator($_) } $self->{dataArray};

(ungetestet, aber so ähnlich sollte es schon gehen).

Das funktioniert natürlich nur, solange $comparisonAction
immer gleich evaluiert (also kein 'sub getSmallerResults { return $_ 10 }

sub getBetweenResults { return $_ >= 8 && $_ = 8 && $_ (), @dataArray;

print "@result1\n@result2\n@result3\n@result4\n"Grüße

CMБ

Hallo Semjon,

Moritz’ Lösung war schon genau das, was ich gesucht und gebraucht hatte.

Vielleicht habe ich das Problem nicht richtig verstanden (zu lange weg), aber was spräche hier gegen eine Variante aus normalem Perl

Die „gory details“ der Retrieval-Operation werden erst zu Laufzeit bekannt.
D.h. was und womit verglichen wird, kann nicht im Code fest verdrahtet werden.

Ich wollte halt in der Threaderstellung nicht zu tief in das Problem einsteigen, da dann vermutlich erst recht keiner mehr verstehen würde, was ich eigentlich will :wink:

Gruss,
Michael

Hallo Michael,

Moritz’ Lösung war schon genau das, was ich gesucht und
gebraucht hatte.

OK

Die „gory details“ der Retrieval-Operation werden erst zu
Laufzeit bekannt.
D.h. was und womit verglichen wird, kann nicht im Code fest
verdrahtet werden.

Ich wollte halt in der Threaderstellung nicht zu tief in das
Problem einsteigen, da dann vermutlich erst recht keiner mehr
verstehen würde, was ich eigentlich will :wink:

Hört sich interessant an. Ich glaube dennoch
nicht, dass Du ein eval in beschriebener Form
benötigst. Wie sind denn Deine Vergleichsoperatoren
strukturiert? Wie viele verschiedene?

(Falls Du Lust und Zeit hast, darauf einzugehen).

Grüße

CMБ