2013-11-20 130 views
0

的方面,我有以下代码评估和演示在另一类

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

这可以实现吗?

+0

你不希望MyClass作为测试器的子类..对吗?或者您准备好同意更改您的代码的任何建议? –

+0

是的,'MyClass'是一个独立的实体,与'Tester'无关。基本上我想知道我是否可以让一个类使用另一个类的上下文进行评估。 – MxyL

+0

你的问题没有意义。 'printer'是一个实例方法。它不能在“MyClass”上下文中评估 - 只能在“MyClass”的_instance_上下文中进行评估。针对您的问题有各种可能的解决方案,但它们都涉及代码结构的根本性改变,而且我不清楚您实际需要什么。 这听起来像你想调用另一个类的实例方法而不创建该类的实例,但这没有任何意义。 – Max

回答

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" 
+0

我想我可以像@tlewin建议的那样实例化MyClass的一个实例并将其发送给它。另一方面,如果我要实例化一个,我可以实例化一次,将它作为一个类变量存储,然后用它来代替。 – MxyL

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方法可以执行任意代码。如果你不控制字符串的内容,这将是非常危险的选择。

+0

您对'instance_eval'的使用完全与该问题相切。在'Tester'的实例上使用它并不会让调用'MyClass'的实例方法变得更容易。 – Max

+0

@Max你完全正确。这就是我在'instance_eval'代码块中包含'MyClass.new'的原因。 –