静的にタイプされた言語がRubyのmethod_missingのようなものを持つことを防ぐものは何ですか?
-
05-10-2019 - |
質問
静的にタイプされた言語の経験はあまりありません(現在はScalaを学び、それを愛しています!)が、私が気づいたことの1つは、RubyのMethod_MissingやColdFusionのOnmissingMethodのようなものがないように見えることです。これを防止または困難にする、静的にタイプされた言語に固有の制限がありますか?
解決
他のヒント
SCALAバージョン2.9は、この機能を介して紹介します Dynamic
特性(スカラドック)。拡張するクラス Dynamic
魔法の方法を取得します applyDynamic(methodName, args)
, 、これはRubyのものに類似しています method_missing
. 。 Scala 2.9の時点で、 -Xexperimental
オプションを使用することを有効にする必要があります Dynamic
.
静的にタイプされた言語では、メンバー関数が直接呼び出されます。コンパイラが呼び出すメンバー関数を把握できない場合、プログラムはコンパイルされません。メソッドの呼び出しは、この意味で、静的です。
動的にタイプされた言語では、メンバー関数は直接呼び出されません。むしろ、コードを呼び出すと、メッセージがオブジェクトに送信され、言語ランタイムはそのメッセージをどうするかを把握します。たとえば、ランタイムは同じ名前のメソッドのオブジェクトをスキャンし、名前のメソッドのオブジェクトをスキャンします method_missing
. 。メソッドの呼び出しは、この意味で、動的です。
C#4は、静的タイピングと動的タイピングを組み合わせます。変数には、コンパイル時間タイプがある場合があります dynamic
. 。この変数でのメソッドの呼び出しは、動的に型付けされた言語のように処理されます。静的タイプを持つ変数に関する任意のメソッドの呼び出しは、静的にタイプされた言語のように処理されます。
# static invocation, bound at compile time by the compiler
var s = 6;
s.ToString();
# dynamic invocation, handled at runtime by the CLR
dynamic d = 6;
d.ToString();
ランドールの投稿をさらに進めるために、それは可能ですが、それが静的なパラダイムに反する理由は、それが「動的な派遣」を超えているからです。 Dynamic Dispatchは、既知の静的コードに動的に結合した関数に喜んで発送できます。 IEコンパイラは、その観点から、実行時に決定論的に実行されるディスパッチをセットアップします。
何 method_missing
コールは、本質的に「すべてをキャッチ」することです。ここで、スイッチステートメントを使用してメソッド名に基づいて何をすべきかを決定します。したがって、コンパイラはここで何が起こるかわからない。コンパイラが次のようなことをしたとしましょう。
if (function is known at compile time)
{
provide static call or dynamic call to "some" derivation
}
else
{
bind the function call to obj.method_missing(...) and pass in the "details"
}
その後、提供する必要があります method_missing
このような:
def method_missing(intendedFunctionName, arguments)
{
if (intendedFunctionName is "X")
{
X may not need arguments, so just do something
}
else if (intendedFunctionName is "Y")
{
Y expects 5 arguments of varying types
Throw exception if there isn't the right number or types
}
... etc ...
}
コンパイラに「任意の」(つまり、コンパイル時に知られていない)任意のタイプの引数を送信するように依頼します。 intendedFunctionName
あなたが説明していないかもしれないこと...まあ、それはあまり安全ではなく、Scalaは静的に安全な言語であることを意図しています。
はい、それは実行可能ですが、静的言語の精神ではありません。あなたが本当にそのタイプの柔軟性を望むなら、ポリグロットプログラミングはおそらくあなたの友達です。
注:Objective-Cは厳密に静的に型付けされていません。コードが実行されるランタイムエンジンがあり、動的タイピングシステムでは、コードをC/C ++のように削除したりインラインしたりすることができません。
Objective-Cには「method_missing」があります(具体的には、 ForwardInvocation と MethodsignatureForselector)そして、それは間違いなく静的にタイプされています。これは、C ++の仮想メソッドのようなものよりもはるかにランタイムで発生するため、コンパイル時にエラーではなく、静的タイプエラーを警告として扱うため、これは機能します(そして、これが「Method_Missing」を持つことができる理由です)。