Ruby ruby 中的方法不是一级对象? 谁能给讲讲?

zztczcx · 2013年06月12日 · 最后由 luikore 回复于 2013年06月12日 · 3222 次阅读

今天看到一句话 为理解 python 的 self,不妨对比一下 ruby 和 javascript。ruby 的方式是方法不是一级对象,所以绕过了这个问题(python 的类方法为什么要写一个 self 参数)。

关于一级对象 http://en.wikipedia.org/wiki/First-class_object

我看 ruby 好像可以在运行时,创建方法。到底是不满足哪一条,才不能称作一级对象。 初学 ruby,对一些概念还不很理解。谁能解释一下吗? 谢谢。

or assigned into a variable 这条就不满足,ruby 只能得到 Object,不能得到 function,对比下 js

#1 楼 @jjym 嗯, ruby 中 方法好像不是对象。

只是取出来的写法不同而已: a.method :f

python / js 的 a.f() 其实是两个操作: 取方法对象, 然后 apply

ruby 的 a.f() 是一个操作: 发消息

#3 楼 @luikore ruby 中 一个对象的方法存在于对象自身的类中。 那 python /js 中呢, 这个取对象方法,是在自身取还是去类中取? 或者说,python 实例化对象的时候,方法是存在实例中的吗?

#4 楼 @zztczcx

ruby 是有 eigen class 就从自身取, 取不到就从 class 取, 再取不到就搜 super class / module ... js 是从自身取, 取不到就从 prototype 取, 再取不到就到 prototype 的 prototype 取...

实例的方法对象, 都是 class / prototype 上的 "函数指针" + 实例 (self) 的组合, 函数体都只存一份的, 但方法对象都有绑定的实例.

#3 楼 @luikore 我感觉这样的说法只是自欺欺人而已,无论是两个操作还是一个操作,最后解释器都是两个步骤,1)找到对应方法,2)然后调用方法。 Ruby 这样设计的一个很显然原因是早期吸收了 Perl 的语法糟粕,调用方法可以省略括号,导致从语法解析上就不可能把方法直接作为对象取出来,而必须经过另一个统一接口返回。

#6 楼 @ekim_sgra 其实解释器怎么做你是管不了的... rubinius 里某些方法调用就不用经过 1)

你可以按这两步理解 js/python, 但是不能这么理解 ruby, 它们是不同的

各人喜好吧. 我就讨厌写括号

#6 楼 @ekim_sgra 我觉得不是因为你说的原因,而是 ruby 太强调面向对象才导致函数不是第一公民,不知道这点是不是跟 smalltalk 学的? 表示就算不小心写了括号都要删掉。。

#6 楼 @ekim_sgra 再提一点不同

就算强制括号, a.f 取方法对象在 ruby 中也是行不通的. 因为 ruby 实现了元对象协议的动态分派 (dynamic dispatch) -- 调用的时候可能方法根本就还没定义, 但这个 dispatch 还是有可能跑到 method_missing 中并成功返回的. 用先取后调的语义去理解 a.f() 还是不合逻辑.

有得必有失, 在我看来 a.method :f 的能用的地方没有动态分派用在 DSL 的地方多...

#9 楼 @luikore 那凭啥 Python 可以

#10 楼 @bhuztez python 是实现了 "attr_missing", 和动态分派略有区别吧

需要 登陆 后方可回复, 如果你还没有账号请 注册新账号