设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 3414|回复: 2
打印 上一主题 下一主题

[原创发布] 【初阶】构建更智能的方法 - Ruby方法相关

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1195
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

跳转到指定楼层
1
发表于 2010-7-21 01:37:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 DeathKing 于 2010-7-21 08:43 编辑

这个东西估计你看了也没用,很少人的工程中能用上这些东西。不过你必须承认,有了这些东西,可以使方法更具有弹性,更加灵活。

另外,欢迎大家丢砖指正。测试环境是Ruby1.8.1(RGSS),RGSS2也完全可以,甚至于Ruby1.9.6也能成功运行本次范例。

一、迭代
迭代允许我们执行由我们传递的一个语句块,当然,使用关键字yield。
  1. def a_yield_method
  2.     yield
  3. end
复制代码
调用a_yield_method {p "hi! I am a yield-method."},由花括号扩住的正是我们所谓的“语句块”。事实上,你可以把一对{}替换为do~end,这似乎只关乎美观和“结合能力”的问题。
  1. a_yield_method {p "hi! I am a yield-method."}
  2. #=> "hi! I am a yield-method."
复制代码
这样做有个严重的问题,当我们没有传递块的时候,会触发LocalJumpError。Kernel模块提供了一个完美的解决办法,block_given?返回true或flase来标识是否传递了一个块。于是我对上一个方法稍作修改:
  1. def a_yield_method
  2.   if block_given?
  3.     yield                        # 如果传递了块就迭代
  4.   else
  5.     p "Miss"                        # 没传递就显示丢失
  6.   end
  7. end
复制代码
这样就可以确保万无一失,同时yield关键字可以让我们对原方法随时扩容,这是否又是得益于Ruby的强动态性呢?

二、块参数


在参数前加一个&,让他变成块参数,使得他可以接受Proc对象。值得一提的是,这里的&可不是C语言里面的取址运算符。
  1. def a_proc_method( &proc )
  2.   p proc.class
  3.   yield if block_given?
  4.   proc.call if block_given?
  5. end

  6. a_proc_method
  7. #=> NilClass

  8. a_proc_method { p "Double Kill" }
  9. #=> Proc
  10. #=> "Double Kill"
  11. #=> "Double Kill"
复制代码
这个例子很容易理解,我们利用反射机制检测着proc参数,并且如果传递了块就迭代并调用proc的call方法(由Proc类提供)。

三、参数列表

参数前加(一元)星号,是他称为参数列表(可变参数)。可变参数是一个数组对象,应该在定义方法时置于最后,并且没有默认值。可以用for关键字或者each(Array类提供)等方法遍历参数。

展望:Ruby 2.0以上的版本中,将添加**二元星号(作用貌似是可变参数,但是一个Hash对象?)。
  1. def multiple_arg_method( *args )
  2.   args.each do |e|
  3.     p e
  4.   end
  5. end

  6. multiple_arg_method(1,"2",3.0,[4,5],{6=>7},Proc.new{p "hi"})
  7. #=> 1
  8. #=> "2"
  9. #=> 3.0
  10. #=> [4,5]
  11. #=> {6=>7}
  12. #=> #<Proc>
复制代码
方法内部,我采取的策略是使用each方法迭代每一个元素,并用p给输出出来。可以想象,我们利用可变参数做一个简单的加法方法:
  1. def sum( *args )
  2.   result = 0
  3.   args.each do |e|
  4.     result += e
  5.   end
  6.   return result
  7. end

  8. p sum(1,2,3,4,5,6,7,8,9)
  9. #=> 45
复制代码
四、活用反射机制

众所周知,向量可以于一个数量相乘,亦可以于一个向量相乘,因此,我们可以利用反射机制定义一个智能的方法,辨识传递的参数,并作出智能的部署:

在本例中,假设向量是由Vector类管理,数量是由Numeric类管理。我们在Vector类里重载*运算符,向量的x,y坐标以@x,@y这两个实变量的形式存储。
  1. def *( opt )
  2.   if opt.is_a? Numeric                # 是数量
  3.     self.x *= opt
  4.     self.y *= opt
  5.     return self
  6.   elsif opt.is_a? Verctor        # 是向量
  7.     return self.x * opt.x + self.y * opt.y
  8.   end
  9. end
复制代码
很明显,我们利用is_a?方法,判定传递过来的参数是那个类的实例,从而决定改如何操作,这的确让方法变得灵活。当然也可以用.kind_of?或者.class.ancestors.include?方法来确定。

五、参数默认值

我们可以给参数制定默认值,当没有传递参数时,这使得Ruby不会发生ArgumentError。
  1. class Human
  2.   attr_reader :age
  3.   def initialize( age = 0)
  4.     @age = age
  5.   end
  6. end

  7. guest = Human.new
  8. p guest.age #=> 0
复制代码
没有传递参数,也可以正常使用?真是莫大的方便




为什么有此文?晚上睡不着觉起来蛋疼……

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
2
发表于 2010-7-21 01:55:59 | 只看该作者
呵呵,支持下~
动态参数列表在传参的时候也有应用,在数组对象前面加上 * 就表示展开数组,按先后顺序传递每个元素给方法~
multiple_arg_method(*[1, 2, 3, 4, 5])

向量相乘也分点积和叉积,这里写的应该是点积吧,后面一个运算符打错了:return self.x * opt.x + self.y * opt.y

关于 Ruby 2.0 的新运算符是在哪里看到的,求链接……Matz 好像在 RubyConf 上说过 2.0 会是一个 1.9 的增强版,不会有什么革命性的改变 ><

点评

很好的补充与勘误。 关于Ruby 2.0的消息来自于ChinaRails,具体链接已忘记(仔细找还是有的):[url]http://chinaonrails.com/[/url]  发表于 2010-7-21 08:40
回复 支持 反对

使用道具 举报

Lv1.梦旅人

辉瑞中国首席研究员<

梦石
0
星屑
50
在线时间
142 小时
注册时间
2008-1-18
帖子
2129
3
发表于 2010-7-21 10:34:18 | 只看该作者
好吧 在下的感觉是 总觉得这篇文章不痛不痒
就像是把参考手册照搬了一遍 内涵和难点都没讲

本来就知道的不需要看 不知道应该是一头雾水

LZ可以54在下,只是个人感觉而已

点评

除非你真的想去探究他的内部,不然表面(用法)是很好理解的。  发表于 2010-7-21 12:29
呵呵 里面所涉及的东西简单么  发表于 2010-7-21 12:01
这个本来就很简单,而且rgss里面也用不上。所以这个完全可以被54  发表于 2010-7-21 11:41
来6r就是等某位仁兄的巨坑

褴褛着身行无端,囊中羞涩空心酸。
平生几无得意事,倒塔泡面宅寝室。
惟羡隔壁高帅富,雨露春风月夜声。
青丝无处觅其踪,只有硬盘苍井空。
莫云男儿空悲愁,鸿鹄岂不天际游。
坐断天下执鹿首,千百金帛万兜鍪。
夜深忽梦某年月,再见女神欲语迟。
吊丝终有逆袭日,木耳再无回粉时。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-12-23 22:57

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表