简体   繁体   English

Ruby方法,Proc和块混淆

[英]Ruby method, Proc, and block confusion

I have a couple questions about Ruby's methods, procedures, and blocks that strike me as rather odd. 我有几个关于Ruby的方法,程序和块的问题让我觉得奇怪。 They're not so much about syntax or function as the logic behind the decisions made. 它们与语法或功能的关系不如决策背后的逻辑。

Question 1: 问题1:

Why is it that blocks can be passed to methods (eg each) but they cannot be assigned to a variable? 为什么块可以传递给方法(例如每个)但是它们不能分配给变量?

I know you can pass them around in procedures, ie p = Proc.new {...} (accessed with &p ), but it doesn't make much sense to make the programmer go through these means. 我知道你可以在程序中传递它们,即p = Proc.new {...} (用&p访问),但让程序员通过这些方法没有多大意义。

Question 2: 问题2:

Why is there a differentiation between methods and procedures? 为什么方法和程序之间存在差异?

For instance, I can accomplish the task of defining a function and calling that function in the following two ways: 例如,我可以通过以下两种方式完成定义函数和调用该函数的任务:

def square(x)
    x**2
end

square(3)
=> 9

or 要么

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

Why the differentiation? 为什么要分化? In Python for example both defining a function in the standard way and by square = lambda x: x**2 accomplish the same task of creating the function and assigning it to square . 例如,在Python中,以标准方式和square = lambda x: x**2定义函数,完成了创建函数并将其赋值为square的相同任务。

Question 1: Blocks are not objects, they are syntactic structures; 问题1:块不是对象,它们是句法结构; this is why they cannot be assigned to a variable. 这就是他们无法分配给变量的原因。 This is a privilege reserved for objects. 这是为对象保留的权限。

Question 2: Methods are not objects, so they cannot receive messages. 问题2:方法不是对象,因此无法接收消息。 Inversely, procs and lambdas are objects, so they cannot be invoked like methods, but must receive a message that tells them to return a value on the basis of the parameters passed with the message. 相反,procs和lambdas是对象,因此它们不能像方法一样调用,但必须接收一条消息,告诉它们根据随消息传递的参数返回一个值。

Procs and Lambdas are objects, so they can receive the call message and be assigned to names. Procs和Lambdas是对象,因此它们可以接收call消息并分配给名称。 To summarize, it is being an object that makes procs and lambdas behave in ways you find odd. 总而言之,它是一个使procs和lambdas以你发现奇怪的方式表现的对象。 Methods and blocks are not objects and don't share that behavior. 方法和块不是对象,也不共享该行为。

To some extent at least, methods are objects: 至少在某种程度上,方法对象:

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

Further to that, there is a built-in class: Method, as documented here . 除此之外,还有一个内置类:Method,如此处所述

See also this: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls 另见: http//en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

Haphazardly <bseg> , it does rather seem to bear out the everything-is-an-object thing. <bseg> ,它确实似乎证实了一切都是对象的东西。 In this particular case, it just appears to take a little more digging to see. 在这种特殊情况下,它似乎需要更多的挖掘才能看到。

(I really must make an effort to understand this better: I'm starting to think it's fundamental to getting a deeper understanding.) (我真的必须努力更好地理解这一点:我开始认为这是获得更深入理解的基础。)

Methods are methods — that is, they're actions that an object can take in response to messages. 方法是方法 - 也就是说,它们是对象可以响应消息的动作。 They are not functions. 它们不是功能。

Blocks are closures — they're functions that close over the enclosing scope. 块是闭包 - 它们是封闭范围内的函数。 They don't conceptually "belong to" a given object. 它们在概念上不属于“属于”给定对象。

In some languages, methods are merely functions that are members of an object, but Ruby does not view them this way. 在某些语言中,方法只是作为对象成员的函数,但Ruby不会以这种方式查看它们。 Separating a method from its owning object is more akin to surgery than simple assignment. 将方法与其拥有的对象分开更类似于手术而不是简单的分配。 Ruby takes its object-orientation model from Smalltalk , the granddaddy of modern OO. Ruby采用现代OO的祖父Smalltalk的面向对象模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM