`
run_xiao
  • 浏览: 193010 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

比较对象

    博客分类:
  • Ruby
阅读更多
之前对Ruby中如何比较对象模棱两可,老想拿Java中的操作去套,发现很多时候行不通,今天花了点时间总算搞得比较清楚了

首先看看所有对象的父类Object包含的比较方法:     
===:类似于instanceof
=~:用于比较正则表达式,这两个都比较简单
而另外三个方法变化就比较多
==  eql?   equal? 三个方法原本在Object中定义的作用是一样的,都用来判断是否为同一对象,看看Object的C代码(object.c)
    rb_define_method(rb_mKernel, "==", rb_obj_equal, 1);
    rb_define_method(rb_mKernel, "equal?", rb_obj_equal, 1);
    rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);

定义的三个方法调用了同一个c方法。

然而在RDoc中还有这样的解释:
引用

Unlike ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b).

==方法可以子类中重载以提供同该class相符合的意义,而equal?不应该(should never)重载,以保证其本身的比较object_id的意义

这就解释了如下代码:
a = “a”
b = “a”
a == b 			#true
a.eql? b			#true
a.equal? b		#false


查看String的C代码(string.c)
    rb_define_method(rb_cString, "==", rb_str_equal, 1);
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);


String有重载 == 和eql?方法,但未重载equal?,另外== 和eql?方法重写规则也不太一样,大概看了下C代码,最终一个调用rb_memcmp方法比较,一个调用memcmp,未仔细研究其差别。不过按Rdoc中所述,eql?应该和==同意,数字类型除外(Numeric),在Has中会调用该方法。
一直没搞懂ruby为什么要搞得这么复杂,自定义类时要遵从这些约定?不如Java来的简单明了。

另外,Ruby中还有个Comparable Module,它主要是根据<=>的结果(1,0或-1)提供<   <=   ==   >   >=   between?等方法的比较结果(true,false),所以在自定义的类中必须定义<=>方法,否则调用Comparable提供的方法时会报错
分享到:
评论
1 楼 不是流氓 2007-08-06  
顶一个,看明白了

相关推荐

Global site tag (gtag.js) - Google Analytics