免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6349 | 回复: 2

[原创]ruby几个高级特性的理解 [复制链接]

论坛徽章:
0
发表于 2008-09-28 22:46 |显示全部楼层
面向对象的思想在ruby中表现的淋漓尽致,几个特性也是比较难以理解的,这里做个小总结:

1. super

先看例子吧:

  1. class Father
  2.     def hello
  3.         p 'hello, i am dad'
  4.     end
  5. end

  6. class Child < Father
  7.     def hello
  8.         p 'hello, i am son'
  9.         super

  10.     end

  11. end

  12. Father.new.hello
  13. #hello, i am dad
  14. Child.new.hello
  15. #hello, i am dad
  16. #hello, i am son
复制代码


ruby类中方法查找路径为:类实例先查找本类中是否定义了该方法, 然后查找该类中是否include了其他module,该mudule中是否包含了改方法, 然后查找该类的父类中是否有改方法, 然后是父类中是否include了其他module,改mudole中是否包含了其他方法。
在查找的整个过程中如果查找到将会立刻执行并停止向上一级的查找


super可以理解为,按照上面的查找路径再向上一级进行查找, 如果有,就在该处(调用super的逻辑片段中)再执行一遍改匹配该方法名的方法,如果整个查找过程都没有匹配到,将会抛出异常NoMethodError,所以上面的例子就不难理解了, 要注意的是super不是只查找自己父类中的同名方法, 包括module的


另外super也接受参数:
super, 及没有加任何参数时(裸词), 是默认自动向前传递所有该方法所获得的参数
super(), 不向上一级传递任何参数
super(a,b,c), 传递指定的参数

2. <<

<<用来批量定义类或者模块的方法(注意不是实例方法)

下面两段代码的效果是一样
  1. class As
  2.     def As.hello
  3.         #do something

  4.     end
  5. end

  6. class As
  7.     class << self
  8.         def hello
  9.              #do something
  10.         end
  11.     end
  12. end
复制代码


同理下面两段代码的效果是一样的

  1. module TimeFormat
  2.     def self.show_time
  3.         #do something
  4.     end
  5. end

  6. module TimeFormat
  7.     class << self
  8.         def show_time
  9.             #do something
  10.         end
  11.     end
  12. end
复制代码


3. yield和block

block在ruby是独有的特性, 其中yeild的使用更是灵活

下面是内置类File :pen的源码

  1. def File.open(name, mode = "r")
  2.     f = os_file_open(name, mode)
  3.     if block_given?
  4.         begin
  5.             yield f
  6.         ensure
  7.             f.close
  8.         end
  9.         return nil
  10.     else
  11.         return f
  12.     end
  13. end
复制代码


这个方法非常简洁明了,block_given?判断是否传递了代码块,有的话就把文件句柄传给代码块进行操作,这个地方就是

  1. yield f
复制代码


我觉得可以这样理解yield的行为:把yield后面的参数传递给后面的代码块作为参数。
yield的作用可以这样理解:拿学生举个例子,每个学生交的学费是一样的,所以处理交学费的流程就放在方法中,但是每个学生的要花费的生活费不一样,要考虑很多的因素,所以把特殊的因素放在代码块中操作,这样就可以即统一又有区别的计算出总的花费。

另一个例子


  1. def  c(v, &block)
  2.     return v unless v.is_a? Array
  3.     v.each &block if block_given?

  4. end
  5. c([1,2,3]) { |x| p x + 1 }    #2, 3, 4

  6. def c(v)
  7.     return v unless v.is_a? Array
  8.     v.each { |x| yield x } if block_given?
  9. end
  10. c([1,2,3]) { |x| p x + 1 }    #2, 3, 4
复制代码

论坛徽章:
0
发表于 2011-02-23 10:10 |显示全部楼层
你好 c(v, &block)
&起什么作用? 地址指针? 新手,请指教。

论坛徽章:
0
发表于 2011-08-02 23:04 |显示全部楼层
是灵活
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP