評估繫結內部

Ruby 通過一個名為 binding 的物件跟蹤區域性變數和 self 變數。我們可以通過呼叫 Kernel#binding 來繫結範圍,並通過 Binding#eval 來評估繫結中的字串。

b = proc do
  local_variable = :local
  binding
end.call

b.eval "local_variable" #=> :local
def fake_class_eval klass, source = nil, &block
  class_binding = klass.send :eval, "binding"

  if block
    class_binding.local_variable_set :_fake_class_eval_block, block
    class_binding.eval "_fake_class_eval_block.call"
  else
    class_binding.eval source
  end
end

class Example
end

fake_class_eval Example, <<-BLOCK
  def self.foo
    :foo
  end
BLOCK

fake_class_eval Example do
  def bar
    :bar
  end
end

Example.foo #=> :foo
Example.new.bar #=> :bar