Eval() は、少なくとも Ruby では、単一のステートメント (代入など) から関連するプログラムを完了するまで、何でも実行できます。多くの小さなスニペットを実行するには、可能な他のほとんどの実行形式よりもかなりの時間がかかります。
問題を詳しく見てみると、eval が使用される可能性のあるさまざまなスキームのベースにあった、少なくとも 3 つの異なる関数があります。Dart は、これらのうち少なくとも 2 つを最小限の方法で処理します。
Dart は、「一般的な」スクリプトの実行をサポートする予定はありません。
ただし、NoSuchMethod メソッドを使用すると、変数の動的な「注入」をローカル クラス環境に効果的に実装できます。eval() を次のような文字列に置き換えます: eval( "String text = 'your first name here';" );
Dart がすぐにサポートできるようになった 2 つ目の関数は、次のようなメソッドの呼び出しです。 eval( "Map map = SomeClass.some_method()" );
これをいじった後、最終的に、単一の単純なクラスを使用して、クラスのメソッドを呼び出すために必要な情報を、一般的なユーティリティがあると思われる文字列として格納できることに気付きました。一連のメソッドを呼び出すために必要になる可能性のある大きなメンテナンスの多い switch ステートメントを置き換えることができます。Ruby ではこれはほとんど些細なことでしたが、Dart では直感的とは言えない呼び出しがいくつかあるため、この「トリック」を 1 か所にまとめたいと思いました。
class.methodName() をキーだけで (文字列として) 呼び出すことができるように、リフレクションを使用して多くのクラス (ライブラリ全体?) をマップに「蓄積」するコードを次に示します。
注: Map & List 関数を実行するためにいくつかの「ヘルパー メソッド」を使用しました。おそらくそれらを単純な Dart に置き換えたいと思うでしょう。ただし、このコードは関数のみを使用して使用およびテストされています。
コードは次のとおりです。
//The used "Helpers" here..
MAP_add(var map, var key, var value){ if(key != null){map[key] = value;}return(map);}
Object MAP_fetch(var map, var key, [var dflt = null]) {var value = map[key];if (value==null) {value = dflt;}return( value );}
class ClassMethodMapper {
Map _helperMirrorsMap, _methodMap;
void accum_class_map(Object myClass){
InstanceMirror helperMirror = reflect(myClass);
List methodsAr = helperMirror.type.methods.values;
String classNm = myClass.toString().split("'")[1]; ///#FRAGILE
MAP_add(_helperMirrorsMap, classNm, helperMirror);
methodsAr.forEach(( method) {
String key = method.simpleName;
if (key.charCodeAt(0) != 95) { //Ignore private methods
MAP_add(_methodMap, "${classNm}.${key}()", method);
}
});
}
Map invoker( String methodNm ) {
var method = MAP_fetch(_methodMap, methodNm, null);
if (method != null) {
String classNm = methodNm.split('.')[0];
InstanceMirror helperMirror = MAP_fetch(_helperMirrorsMap, classNm);
helperMirror.invoke(method.simpleName, []);
}
}
ClassMethodMapper() {
_methodMap = {};
_helperMirrorsMap = {};
}
}//END_OF_CLASS( ClassMethodMapper );
============
main() {
ClassMethodMapper cMM = new ClassMethodMapper();
cMM.accum_class_map(MyFirstExampleClass);
cMM.accum_class_map(MySecondExampleClass);
//Now you're ready to execute any method (not private as per a special line of code above)
//by simply doing this:
cMM.invoker( MyFirstExampleClass.my_example_method() );
}