Schlüsselwortargumente für FunktionenIch würde es lieben, wenn wir in benutzerdefinierten Funktionen Schlüsselwortargumente in den Aufrufen verwenden könnten, damit ich dies tun kann
Names default to here(1);
f = function({x, y=2, z=3},
show(x, y, z);
);
print("What I'd like to do");
f(1, z=2);
//I want it to be 1, 2, 2
//instead of having to do
f = function({x, kwargs={}},
{DEFAULT LOCAL},
// optional
y = 2;
z = 3;
evallist(kwargs);
show(x, y, z);
);
print("Using List");
f(1, {z=2});
Jemand hat es erwähnt Hier , aber es war vor 8 Jahren, also dachte ich mir, ich würde es wieder aufgreifen.
SkriptingBetreff: Schlüsselwortargumente für Funktionen @ gzmorgan0 Mein größtes Problem mit der kwargs-Liste ist, dass damit alles ausgeführt werden kann. Zum Beispiel, wenn ich alle Einheimischen in einer bestimmten Funktion sehen möchte.
f = function({x, kwargs = {}},
{y = 2, z = 3, a = Expr(y + z)},
evallist(kwargs);
r = x + y + z;
return(r);
);
f(14, {print(namespace("local") << Get Contents)});
Welches ist ein Sicherheitsproblem für mich mit verschlüsseltem Code.
Ich behalte die Dinge tatsächlich in einem assoziativen Array und mache dann einen << Schnittpunkt mit einem assoziativen Standardarray, um zu überprüfen, ob die übergebenen Argumente gültig sind.
Dann analysiere ich einfach die Schlüsselwertpaare in die Funktion, damit ich das Array nicht zum Aufrufen verwenden muss.
Ich habe Hilfefunktionen, um all dies zu tun, aber das bringt seine eigenen Probleme mit sich. Und es ist umständlicher als ich mag.
@ XanGregg , mein Fehler. Zu den meisten dieser Dinge habe ich ein viel engeres Sichtfeld.
Betreff: Schlüsselwortargumente für Funktionen @vince_faller Ich mag immer noch Ihre vorgeschlagene kwargs = {} -Lösung mit einer Modifikation. IMHO Default Local eignet sich gut für einfache Skripte, ist jedoch für komplexe Skripte riskant. Ich empfehle, eine Liste lokaler Variablen zu verwalten. Im Folgenden finden Sie ein Skript, das eine Modifikation Ihrer kwargs-Lösung darstellt, jedoch die Syntax {z, 4} vs. z = 4 als Elemente in Ihrer kwargs-Liste verwendet und einen generischen Codeblock erfordert. Eine Funktion könnte ein lokales assoziatives Array verwenden, um "Schlüsselwort" -Werte zuzuweisen, die den unten angegebenen Codeblock implizieren würden. Dann ist die Syntax der einzelnen Variablen jedoch umständlicher, anstatt a + b wäre es so etwas wie aa1 [a] + aa1 [b], daher verwendet das Beispiel Listen.
Wenn ich eine Funktion mit vielen Variablen hätte, aber für jeden Funktionsaufruf nur wenige ändern wollte, könnte ich diesen Ansatz verwenden. Der Schlüssel hier ist das
- Es wird keine Variable geändert, es sei denn, sie befindet sich in der varList und
- geänderte Werte sind lokal.
Names Default To Here( 1 );
//simple example
g1 = Function({kwargs={}}, {Default Local},
varList = {a,b,c,d,e,f};
valList = {1,2,3,4,5,6};
For(i=1, i<=nitems(kwargs), i++,
//each item must be a list of 2 values.
If(IsList(kwargs[i]),
Try(valList[loc(varList,kwargs[i][1])] = kwargs[i][2])
);
);
Eval( EvalExpr( Expr(varList) = Expr(valList)) ) ;
show(a,b,c,d,e,f);
);
myList = {{a,10},{y,-44},{f,20}};
g1(myList);
// [+] no variable gets changed unless it is in the variable list
// [-] varList and valList need to be defined
// [-] lines 7-13 would need to be added to each function, could be a global expression
// [-] instead of z=4 syntax, {z,4} syntax is required
//------Modification of Vince Faller script
f = function({x, kwargs={}},
{DEFAULT LOCAL},
// optional
varList = {x, y};
valList = {2,3};
For(i=1, i<=nitems(kwargs), i++,
//each item must be a list of 2 values.
If(IsList(kwargs[i]),
Try(valList[loc(varList,kwargs[i][1])] = kwargs[i][2])
);
);
Eval( EvalExpr( Expr(varList) = Expr(valList)) ) ;
print("Before Bad Call");
show(y);
print("Bad Call");
//even though f2 is default local,
//because it's not explicit in the function it writes to here
f2(1, { {b,3}, {y,5}});
print("After Bad Call");
show(y);
);
f2 = function({a, kwargs={}},
{DEFAULT LOCAL},
varList= {b,c};
valList = {2,3};
For(i=1, i<=nitems(kwargs), i++,
//each item must be a list of 2 values.
If(IsList(kwargs[i]),
Try(valList[loc(varList,kwargs[i][1])] = kwargs[i][2])
);
);
Eval( EvalExpr( Expr(varList) = Expr(valList)) ) ;
show(a, b, c);
);
f(1, {z=2});
Betreff: Schlüsselwortargumente für FunktionenRichtig. Ob Sie es glauben oder nicht, wir versuchen, alte JSL-Verhaltensweisen, auch unwahrscheinliche, nicht zu brechen.
Betreff: Schlüsselwortargumente für FunktionenAhh. Wenn also jemand diese Syntax verwendet (aus welchem Grund auch immer), würde sie kaputt gehen, wenn er später az global benötigt. Verstanden.
Betreff: Schlüsselwortargumente für FunktionenDerzeit werden Argumente für Benutzerfunktionen ausgewertet und z = 4 ist ein gültiger Ausdruck
f(1, z=4);
würde z = 4 auswerten, ein globales z erzeugen und ein Ergebnis von 4 haben, und dann das Ergebnis an das y-Argument von f übergeben.
Betreff: Schlüsselwortargumente für FunktionenWarum sollte eine neue Syntax erforderlich sein? Wollen Sie anrufen oder definieren? Ich denke, wir könnten sie genauso definieren.
Wenn eine Funktion bereits keine Schlüsselwortargumente verwendet, werden standardmäßig Positionsargumente verwendet, wie dies derzeit der Fall ist.
Offensichtlich könnten wir vor der Implementierung keine Keyword-Argumente verwenden, daher sehe ich das nicht als fehlerhafte Skripte an.
Die Funktion
f = function({x, y=2, z=3},
show(x, y, z);
);
würde keine anderen Skripte brechen.
und wenn alle vorherigen Skripte sowieso Positionsargumente verwenden, dann denke ich nicht, dass es irgendetwas kaputt machen würde.
Aber wenn ich es Keyword-Argumente gab, die standardmäßig positionell sind, wenn keine Keywords angegeben wurden
f(1, 2, 4);
würde nichts kaputt machen (ich vermute). Aber es würde nur erlauben
f(1, z=4);
Ich verstehe nicht, warum es einen gefälschten Namespace braucht (aber andererseits verstehe ich nicht, wie Funktionen unter der Haube funktionieren).
Betreff: Schlüsselwortargumente für FunktionenDies würde eine neue Syntax erfordern, die vorhandene Skripte nicht ändert. Vielleicht so etwas wie Ihr Beispiel mit einer Liste, die an einen speziellen Empfänger übergeben wird. Oder vielleicht eine neue Syntax für den Aufrufer, z. B. ein gefälschter Namespace: f (1, arg: z = 2).
Betreff: Schlüsselwortargumente für FunktionenVielen Dank. Es hat definitiv ein paar Probleme. Die größte Möglichkeit, Variablen in eine Funktion einzufügen, führt häufig zu einer Kollision von Variablen. Ich bin nicht vorsichtig.
Names default to here(1);
f = function({x, kwargs={}},
{DEFAULT LOCAL},
// optional
y = 2;
z = 3;
evallist(kwargs);
print("Before Bad Call");
show(y);
print("Bad Call");
//even though f2 is default local,
//because it's not explicit in the function it writes to here
f2(1, {b=3, y=5});
print("After Bad Call");
show(y);
);
f2 = function({a, kwargs={}},
{DEFAULT LOCAL},
b=2;
c=3;
evallist(kwargs);
show(a, b, c);
);
f(1, {z=2});
Betreff: Schlüsselwortargumente für FunktionenIhre aktuelle "kwargs" -Listenlösung ist ein netter Zwischentrick.