2016-08-26 1 views
0

Ich habe eine Klasse mit einer unbekannt Reihe von Funktionen:Scala: execute Funktionen nacheinander und Parameter zwischen ihnen vorbei

class processors { 
    def p1(s: String): String = { 
    //code 
    } 
    def p2(s: String): String = { 
    //code 
    } 
    def p3(s: String): String = { 
    //code 
    } 
    ... 
} 

Ich möchte die ganze Funktion einer nach dem anderen ausgeführt werden können, Reihenfolge werden sie geschrieben (p1 -> p2 -> p3 -> ...). Außerdem möchte ich die anfängliche Zeichenfolge an p1 übergeben, die das Ergebnis als Argument für p2 weitergeben und weitermachen wird. Gibt es einen einfachen Weg, das zu tun?

EDIT:

Was ich bisher haben:

Im Moment habe ich eine hartcodierte Sequenz:

val processors = Seq(p1 _, p2 _, p3 _).reduce(_ andThen _) 
processors(some_string) 

Ich möchte die Hartcodierung vermeiden , grundsätzlich ..

+1

Steuern Sie die Klasse? Weißt du, wie viele Methoden es hat? Wenn Sie nicht (wie Sie in Ihrer Frage * unbekannt * sagen) wissen, wie genau rufen Sie sie jetzt an? –

+0

Wenn Sie keinen Prozessor in jeder Funktion zurückgeben, bezweifle ich, dass Sie die Funktion aufrufen können, ist dies warten p1 -> p2 -> p3. Sie sollten die aktuelle Frage besser erklären. Sie können wahrscheinlich Folgendes definieren: def p1 (s: String): Prozessor = {} def p2 (s: Prozessor): Prozessor {} def p3 (s: Prozessor): Prozessor {} Sie können einen Wert entsprechend der aktuellen hinzufügen String-Wert Bei jeder Änderung des Prozessors kann der correctValue geändert werden. – ypriverol

+0

'Def run (s: String): String = p3 (p2 (p1 (s))) // Witze über dich:)' Wenn Sie nicht wissen, die Anzahl der Schritte verwenden Sie einfach reflection API, um alle Methoden zu erhalten, werfen sie in eine Liste und rufen nacheinander den String als Akkumulator auf. – sebszyller

Antwort

2

Reflexion kann hier helfen. Dieses Beispiel bezieht sich auf ein einzelnes Argument mit Ganzzahl, aber es kann auf mehrere Argumente erweitert werden, aber es wird etwas schwierig, mit Typen umzugehen. Argumenttypen können von der Klasse abgefragt werden.

class A { 
    def f(x: Int): Int = 2 * x 
    def g(x: Int): Int = x * x 
} 

val clazz = classOf[A] 

clazz.getDeclaredMethods.filter(! _.getName.contains("$")) 
.map(x => {a: Integer => x.invoke(new A(), a: Integer).asInstanceOf[Integer] }) 
.reduce(_ andThen _)(new Integer(1)) 

Für Ihren Fall ersetzen Sie einfach Int mit String

Um die Reihenfolge der Ausführung der Funktionen in der Klasse

try zu halten Nummer im Funktionsnamen zu setzen und sie dann bestellen durch Parsen von String erhalten von getName Methode

+0

Das ist genau das, was ich sagte, ich möchte nicht – shakedzy

+0

@shakedzy tun. Bearbeitete die Antwort. hoffe das hilft dir. – pamu

+0

Hier drei Möglichkeiten: 1) fester Code 2) Java oder Scala Reflexion 3) Makro Annotation: '@procontainer Klasse Prozessoren'. siehe user1303559