2009-08-07 70 views
21

我有几个关于Ruby的方法,过程和块的问题让我觉得很奇怪。它们与语法或功能没有太大关系,而是作为决策背后的逻辑。Ruby方法,Proc和块混淆

问题1:

为什么该块可以被传递到方法(例如每个),但它们不能被分配给一个变量?

我知道你可以在程序中传递它们,即p = Proc.new {...}(使用&p访问),但是让程序员通过这些方法是没有什么意义的。

问题2:

为什么有方法和程序之间的区别?

举例来说,我可以完成以下两种方式定义一个函数,并调用该函数的任务:

def square(x) 
    x**2 
end 

square(3) 
=> 9 

square = lambda {|x| x**2} 
square.call(3) 
=> 9 

为什么分化?例如在Python中,以标准方式定义一个函数,并由square = lambda x: x**2完成创建函数并将其分配给square的相同任务。

回答

20

问题1:块不是对象,它们是句法结构;这就是为什么他们不能被分配给一个变量。这是为对象保留的特权。

问题2:方法不是对象,所以它们不能接收消息。相反,procs和lambdas是对象,因此它们不能像方法那样被调用,但必须接收一条消息,告诉它们根据消息传递的参数返回一个值。

Procs和Lambdas是对象,因此它们可以接收call消息并分配给名称。总而言之,它是一个使特效和lambda表现出奇怪的行为的对象。方法和块不是对象,不共享该行为。

+5

红宝石声称一切都是对象。块应该是对象,以便与之匹配,并且它们可以作为参数传递,所以它们在某些方面明确地扮演着对象的角色。 – rpjohnst 2009-08-07 17:58:18

+6

可以通过创建一个对象来表示块,proc或lambda,使块可以像对象一样工作。没有这个设备,它们只是语法结构。 – Pinochle 2009-08-07 18:03:33

+0

有块对象 - 这就是lambda {whatever}的目的。 – Chuck 2009-08-07 18:04:16

4

方法是方法 - 也就是说,它们是对象可以响应消息而采取的操作。他们不是功能。

块关闭 - 它们是关闭封闭范围的函数。它们在概念上不属于“属于”给定的对象。

在某些语言中,方法仅仅是一个对象成员的函数,但Ruby不会以这种方式查看它们。从自己的对象中分离出一种方法更像是手术而不是简单的分配。 Ruby从现代OO的granddaddy Smalltalk中获得了面向对象的模型。

5

在一定程度上至少,方法对象:

class ABC 
    def some_method 
    end 
end 
ABC.instance_method(:some_method) #=> #<UnboundMethod: ABC#some_method> 

进一步说,有一个内置类:方法,如记录here

也是这个参见:http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

随意<bseg>,它确实相当似乎证明了一切都是一个对象的事情。在这个特殊情况下,它似乎需要多一点挖掘才能看到。

(我必须作出努力,以更好地理解这种:我开始认为这是获得一个更深入的了解至关重要。)

+0

方法似乎把它们的对象当作'Proc'的实例。在'Method'的'ri'文档中,'method'这个词在解释中没有使用,但'proc'是。这两个类接收相同的消息,但不同之处在于它们是如何被调用的以及事实上方法是在另一个对象的名称空间内定义的,其中proc需要接收要调用和存在的调用方法(persist,as我之前说过)独立于其他物体。 – Pinochle 2009-08-07 18:48:25

+0

啊,另一个区别是......'方法'没有收到'新'消息,其中'Proc'做。如果方法是对象,它们不是完全意义上的对象('完整'意思是我们习惯在对象中看到的所有特征)。 – Pinochle 2009-08-07 18:51:28

+0

这个wikibooks链接很有帮助。谢谢。 – David 2009-08-07 18:54:40