2009-09-07 133 views
2

在这个例子中,从Ruby编程语言(第270页),我很困惑,为什么上示例代码的最后一行instance_eval方法定义了类方法称为String.empty需要与反思例如帮助从“Ruby编程语言”

当您要定义实例方法时,是否使用class_eval来定义类方法,instance_eval

o.instance_eval("@x") # Return the value of o's instance variable @x 

# Define an instance method len of String to return string length 
String.class_eval("def len; size; end") 

# Here's another way to do that 
# The quoted code behaves just as if it was inside "class String" and "end" 
String.class_eval("alias len size") 

# Use instance_eval to define class method String.empty 
# Note that quotes within quotes get a little tricky... 
String.instance_eval("def empty; ''; end") 

回答

7

你不使用class_eval定义 类的方法,当 要定义一个实例方法instance_eval

不幸的是,它并不那么简单。

首先仔细看看class_eval正在做什么的例子。 class_eval是一种来自Ruby的module class的方法,因此可以在任何类或模块上调用。当您使用String.class_eval时,您正在评估课程背景下的给定代码。即当你编写String.class_eval("def len; size; end")时,就好像你重新打开了类并输入了传递给class_eval例如

class String 
    def len 
    size 
    end 
end 

因此增加使用class_eval你会写String.class_eval("def self.empty; ''; end")具有相同的效果类方法:

class String 
    def self.empty 
    '' 
    end 
end 

instance_eval在Ruby的Object class定义所以可用任何Ruby对象。在一般情况下,它可用于将方法添加到特定实例。例如如果我们有一个字符串str,并说:

str.instance_eval("def special; size; end") 

,那么这将别名任何其他String对象specialsize只是str但不是:

irb(main):019:0> "other".special 
NoMethodError: undefined method `special' for "other":String 
     from (irb):19 

为了理解正在发生的事情与字符串。 instance_eval记住类String本身就是一个对象(类Class的一个实例),并且每个类定义了一个单例实例对象。当您使用String.instance_eval时,您正在评估String实例对象上下文中的给定代码。即等同于重新打开字符串的元类并键入传递的代码

class String 
    class << self 
    def empty 
     '' 
    end 
    end 
end 
1

这是总的主题:

使用ClassName.instance_eval定义 单方法。

使用ClassName.class_eval来定义 实例方法。

post有一个非常整洁的解释,给它一个镜头...