评估绑定内部

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