Eval在另一个类的上下文中

时间:2013-11-20 19:02:15

标签: ruby

我有以下代码

class Tester

  def eval_something(string)
    eval(string)  # How to change?
  end

  def printer
    p "Not what I want"
  end
end

class MyClass

  def printer
    p "Hello World"
  end
end

t = Tester.new
t.eval_something("printer")

我希望Tester实例的eval_something来评估MyClass上下文中的代码。例如,我希望此脚本打印出Hello World而不是Not what I want

这可以实现吗?

2 个答案:

答案 0 :(得分:0)

不太确定这是否适用于您的目的,但您可以尝试:

class Tester
  def eval_something(string)
    MyClass.send(string.to_sym)  # Send will evaluate the symbol passed to it.  Equivalent of calling MyClass.printer in this case
  end

  def printer
    p "Not what I want"
  end
end

class MyClass
  def self.printer   # This needs to be a class method since MyClass does not inherit from Tester in this example
    p "Hello World"
  end
end

t = Tester.new
t.eval_something("printer")

=> "Hello World"

答案 1 :(得分:0)

在您的示例中,您可以使用instance_eval方法并传递MyClass引用:

t = Tester.new
t.instance_eval do
  MyClass.new.printer
end

这将返回“Hello World”。

instance_eval运行您在对象上下文中传递的代码块。在这种情况下,您可以访问任何实例变量。例如:

class Test
  def initialize any
    @any = any
  end
end

t = Test.new('abc')
t.instance_eval {puts @any}

它将打印'abc'。

建议使用instance_evalclass_eval方法,因为它可以让您更好地控制它将执行的内容。这是一个更安全的选择。

eval方法可以执行任意代码。如果你不控制字符串的内容,那将是非常冒险的选择。