Techioz Blog

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 はモジュールよりも空に少し近づけるのに役立つかもしれません)。

それを望んでいるのであれば、これらのどれも、安全に中に入ることができる刑務所を提供しません。