ruby中数字与数字字符串相加的原理

阅读更多
在ruby的世界中,很多东西不怕你做不到,就怕你想不到。正所谓,思想有多远,你就可以走多远。思想不一定非得是自己的,借鉴他人的也很好(不过,做人要厚道,如果是别人的idea,要把思想来源说明白、讲清楚)。ruby世界是个开放的世界,能在这样的世界里生活,那是件很爽的事情。扯了一下淡。。。。

    言归正传。。。


    刚看ruby时,看到 1+“23”这样的表达式,觉得很N(orth)B,数字跟字符居然可以这样运算。时间越久,就越想知道为什么可以这样做,具体的过程是什么样的,在rubinius之前,这个探索是痛苦的。因为ruby是用c语言实现的,而那个C语言的代码我看着实在是不习惯。比如下面的代码,直到现在也木有弄明白。哪位知道的可以给我指导一下。


static inline void
rb_ary_modify_check(ary)
    VALUE ary;
{
    if (OBJ_FROZEN(ary)) rb_error_frozen("array");
    if (FL_TEST(ary, ARY_TMPLOCK))
	rb_raise(rb_eRuntimeError, "can't modify array during iteration");
    if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
	rb_raise(rb_eSecurityError, "Insecure: can't modify array");
}




   
     自从有了rubinius,又多了一条探索ruby世界奥秘的路,重要的是,这是条我比较习惯的路。好吧,还是回到1+“23”这个问题上来。
     rubinius的实现中,主要用到了3个方法:   :+, :redo_coerce,:math_coerce

具体如下:
def +(o)
  Ruby.primitive :fixnum_add
  redo_coerce :+,o
end


def redo_coerce(math,right)
    b,a = math_coerce(right)
    a.__send__ meth,b
end


def math_coerce(other,error = :coerce_error)
    begin
         values = other.coerce(self)#[other,self]
    rescue
         send error,other
    end

    unless values.__kind_of__(Array)&&values.length==2 do
          raise TypeError,"coerce must return [x,y]"  
    end
    values[1],values[0]
end

 




    整个实现就差不多了,但是没完!!!注意到math_coerce这个方法的参数之一是other,而other又调用了coerce这个方法。。。。。从中看出点什么东西来没????我猜你想到了,要使1+“23”能工作,也就是说能得到24,那么应该为String类实现coerce(貌似强制的意思)这个方法。



class String
  def coerce(n)
    if self['.']
      values =  [n, Float(self)]
      print "self is ",self,"\n"
      [n, Float(self)]
    else
      [n, Integer(self)]
    end
  end
end





这样就大功告成了。理解了这个,也就可以为其他很多的类实现运算,进而可以得到你想要的结果了。North B



你可能感兴趣的:(Ruby,C,C++,C#,生活)