Rubyで新しい空のバインディングを作成する方法はありますか?
概要
eval で使用する完全に空の Binding オブジェクトを作成する方法はありますか?
ドキュメントによると、新しいバインディングを作成できるのは Kernel#binding メソッドのみです。私は次のようなことを試しました:
empty = binding
しかし、その後、そのバインディングは、コードの後半で割り当てられる同じスコープ内の他のローカル変数とともに、そのローカル変数内でそれ自体を空にします。
定数 TOPLEVEL_BINDING は空のバインディングであり、当面の目的には十分であることがわかりました。ただし、常にそうとは限りません。
新しい、完全に空のバインディングを作成する方法はありますか?
解決策
簡単な方法は、バインディングのみを呼び出すメソッドを作成することです。
def empty_binding
binding
end
それから:
b = empty_binding
b.local_variables
# [ ]
そのバインディングには引き続き self があり、その self が利用できるインスタンス変数にアクセスできます。いくつかの策略を使ってそれを制限することもできます。
module Empty
def self.binding
super
end
end
b = Empty.binding
b.eval('puts local_variables.inspect')
# [ ]
b.eval('puts instance_variables.inspect')
# [ ]
b.eval('puts self.inspect')
# Empty
何が機能するかは、目標が何であるかによって異なります。ローカル変数を持たないバインディングは非常に簡単ですが、何も持たないバインディングはおそらく Ruby 自体をハックしない限り不可能です (ただし、BasicObject はモジュールよりも空に少し近づけるのに役立つかもしれません)。
それを望んでいるのであれば、これらのどれも、安全に中に入ることができる刑務所を提供しません。