思考的猪

猪一思考,屠夫就发笑

smilewaterID:smilewater
2424次访问,排名2万外好友0人,关注者0
smilewater的文章
原创 6 篇
翻译 0 篇
转载 0 篇
评论 1 篇
最近评论
erway:廖老师,您提到的这项功能很适用啊,有没有一种让大家能够很方便地在线写作然后又很方便地将最后的内容插入到word中的方法呢?
文章分类
    收藏
      相册
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 Ruby Object 类详细分析(1)收藏

      新一篇: Ruby Object 类详细分析(2)  | 旧一篇: 用Ruby的OLE 自动化把文本文件内容插入到Word中

      RubyObject是所有类的父对象,因此它的所有方法在所有对象中都是可用的(如果没有被覆盖的话)。因此它的重要性那是不言而喻的。

      Object到底实现哪些功能,下面一一道来:

      1.       对象比较

      Ruby定义了若干对象比较的方法,有=====eql?equal?,是不是很头大,不过还没完,还有一个=~ 。下面我们对这些比较方式做一个说明。

      首先是==,只有两个对象相同时,该方法的返回值为true。但是子类一般都会对这个方法进行过载,来表示语义上的相等。比如字符串对象和数值对象都对==方法进行了过载。与之相对照的是,equal?方法不应该被子类过载,只有在两个对象表示同一个对象的情况下才会返回true值(注意,是不应该,而不是不能。没有人可以阻止你在Ruby的世界里干这样的坏事,不过你愤怒的老板会给你一张黄牌)。

      首先看一个简单的例子:

      class MyClass
         attr_reader :str
         def initialize(s)
               @str = s
         end
      end

      obj1 = MyClass.new("hello")
      obj2 = MyClass.new("hello")

      puts obj1 == obj2          #false
      puts obj1.equal?(obj2)     #false

      可以看出,在一般情况下,==equal?的行为是一样的,不过我们通常用比较有意义的方式来过载==方法:

      class MyClass
         attr_reader :str
         def initialize(s)
               @str = s
         end
        
         def ==(o)
               str == o.str
         end
        
      #
      你不应该这样做!
      #  def equal?(o)
      #        str == o.str
      #  end
      end

      obj1 = MyClass.new("hello")
      obj2 = MyClass.new("hello")

      puts obj1 == obj2          #true
      puts obj1.equal?(obj2)     #false

      可以看出,我们重新定义的==方法使得比较成功了,再仔细看看,我们是使用了String对象的==方法来实现我们自己定义的==方法的,你应该看得出来,String类已经重载了==方法(否则我们的相等操作无法返回true),如果还没有看出来,下面的这段代码可以帮助你:

      s1 = "hello"
      s2 = "hello"

      puts s1 == s2              #true
      puts s1.equal?(s2)         #false

      s3 = s1

      puts s1 == s3              #true
      puts s1.equal?(s3)         #true

      应该很清楚了,在定义自己的新类的时候,你通常应该为它定义一个比较有意义的==方法,但是你不应该为它重新定义一个equal?方法。

      那么,eql?的作用是什么?如果两个对象的值相等的话,那么eql?方法的返回值为trueeql?方法有一个特殊的作用,它被Hash对象用来测试键值是否相等(注意,还需要有hash方法来配合使用,这个方法在后面介绍)。

      class MyClass
        attr_reader :str
        def initialize(s)
          @str = s
        end
       
        def eql?(o)
          str.eql?(o.str)
        end
       
        def hash
          str.hash
        end
      end

      obj1 = MyClass.new("hello")
      obj2 = MyClass.new("hello")

      puts obj1 == obj2       #false
      puts obj1.eql?(obj2)    #true

      hash = {}

      hash[obj1] = 1
      puts hash[obj2]         #1

      hash[obj2] = 2
      puts hash[obj1]         #2

      Object类中,==eql?的行为是一致的,一般说来,在定义具体类时,也应该保持这样的方式。不过在系统定义的类中有一些特例,比如在Numeric类型的类中,==要在类型和值都相同时才会返回真值,而eql?方法则只要值相等就可以:

         1 == 1.0     #=> true

         1.eql? 1.0   #=> false

       

      ===Ruby的文档中称作“case equality”,它的主要用途是在case语句中,用来判断case语句中when子句的匹配状况。当然你也可以直接在语句中使用它,比如判断一个对象是否在一个范围内就可以使用===来判断:

      puts (1..10) === 2         #=>true
      puts (1..10) === 11        #=>false

      值得注意的是是Range类重载了===方法,因此Range对象实例必须在左侧,下面的结果你应该不会感到意外:

      puts 2 === (1..10)         #=>false
      puts (1..10) === 11        #=>false

      下面我们用一个故意设计的类(其实可以直接用Range的)来演示一下在自己定义的类中过载===方法,我们定义一个ScoreRange的类来对分数进行判断:

      class ScoreRange
         def initialize(min, max)
               @min = min
               @max = max
         end
        
         def ===(score)
               (@min..@max) === score
         end
      end

      PASSED = ScoreRange.new(60, 100)
      FAILED = ScoreRange.new(0, 59)
      GOOD = ScoreRange.new(80, 100)

      score = 68

      case score
         when GOOD
               puts "Good!"
         when PASSED
               puts "Passed!"
         when FAILED
               puts "Failed!"
      end

      最后的输出结果回事“Passed!”,当然,这个程序还存在瑕疵,比如对59.5这样的成绩没有理会,也没有无效分数的判断,它只是用来演示===方法的过载。

      最后一个=~方法是用于正则表达式的模式匹配的,Object的子类应该用比较有意义的方式来过载它,在Object类中,该方法总是返回false。它的具体使用方式可以参见正则表达式的部分,这里不做详细剖析。

       

      发表于 @ 2007年07月17日 11:06:00|评论(loading...)|编辑

      新一篇: Ruby Object 类详细分析(2)  | 旧一篇: 用Ruby的OLE 自动化把文本文件内容插入到Word中

      评论:没有评论。

      发表评论  


      当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
      Csdn Blog version 3.1a
      Copyright © smilewater