Ruby和元编程之万物皆为对象

2019-09-25 09:47:50王冬梅

>> puts "hello #{self}"
>> end
>> m = self
=> main
>> a.hello_self
hello obj

对象的复制

前文说对象的存在包括两部分,一是状态/实例变量,另一个是行为,本回专注讲了单例方法和影子类。
Ruby中对象的复制也有两种模式,一个是只复制当前的状态/实例变量 dup。另外一种是连同影子类和引用的对象一起复制,从而把单例方法也复制一份。

>> a = "obj"
>> def a.hello_self
>> puts "hello #{self}"
>> end
>> b = a.dup
=> "obj"
>> b.hello_self
NoMethodError: undefined method `hello_self' for "obj":String
    from (irb):90
>> b = a.clone
=> "obj"
>> b.hello_self
hello obj

其实有本回上述的这些功能,即便是没有class,Ruby也可以作为一种Prototype(类似JavaScript)的面向对象语言了。

你可以建立一个对象,生成默认的实例变量,把行为作为单例方法定以在这个对象的影子类上,然后用clone生成千千万万个实例。当然这样比较麻烦,但却是可行的途径之一。

其他Object API

对象还有很多其他的功能,比如可以freeze,另外dup跟clone也有一些其他的引用上面的区别,dup只复制引用,clone会吧引用的对象也复制。

这些都可以在Object类(Ruby所有对象的父类)API上找到,可以查看apidock.com的文档

例如关于dup

.dup() produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. dup copies the tainted state of obj. See also the discussion under Object#clone. In general, clone and dup may have different semantics in descendant classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendant object to create the new instance.

本回完

本回讲了些对象相关的东西,有的很基础,有的是Ruby自身的一些特性。

其中Ruby对象模型中最具特色的两个特性就是影子类/单例方法和self,最好能深入理解这两个概念。

且听下回分解

下回注重一些关于类的故事。