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

Project1

 找回密码
 注册会员
搜索
查看: 2815|回复: 6

[讨论] 【Ruby】block的模板实现问题

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1024
在线时间
1389 小时
注册时间
2010-8-9
帖子
3471
发表于 2015-10-16 11:20:39 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 寒冷魔王 于 2015-10-16 13:38 编辑

我有两个用法相同的函数:
RUBY 代码复制
  1. def range1(n)
  2.   n.times { |i| yield(i) }
  3. end
  4. def range2(n)
  5.   n.times { |i| yield(n-i-1) }
  6. end


这两个函数都可以通过
rangeN(n) { |i| print(i) }
来调用,具有一致性。

我想通过使用一个函数does,实现上述模板。
比如这种方式
does({range1(10)}) # 此为理想状态,不正确
does({range2(10)}) # 此为理想状态,不正确

如下我做了一番尝试:
RUBY 代码复制
  1. def do1(proc)
  2.   proc.call { |i| print(i) }
  3. end
  4. def do2(&block)
  5.   block.call.call { |i| print(i) }
  6. end
  7. def do3(*args)
  8.   print(*args)
  9. end
  10. def do4(sym)
  11.   #eval(sym + "{ |i| print(i) }")  # ! Error!
  12. end
  13.  
  14. n = 10
  15.  
  16. range1(n) { |i| print(i) }
  17. puts
  18. puts("1.1:")
  19. do1( ->(&block) { range1(n) { |i| block.call(i) } } )
  20. puts
  21. puts("1.2:")
  22. do1( Proc.new { |&block| range1(n) { |i| block.call(i) } } )
  23. puts
  24. puts("2:")
  25. do2 { ->(&block) { range1(n) { |i| block.call(i) } } }
  26. puts
  27. puts("3:")
  28. range1(n) { |*args| do3(*args) }
  29. puts
  30. puts("4:")
  31. do4("range1(n)")  # ! Error!


有没有更为简便的写法呢?


===============
感谢@喵呜喵5  大触的答案,已经成功实现does:
RUBY 代码复制
  1. def does(method_name,*args)
  2.   send(method_name,*args) { |i| print(i) }
  3. end
  4. does(:range1,10)
  5. puts
  6. does(:range2,10)
  7. puts
SRPG on RM 项目研发组 正式成立。目前SRPG·RMVA系统进度88.8%。SMRC Kernel 进度90%
↖(^ω^)↗热烈庆祝~SMRC Ver5.1 SRPG战棋地图移动范围生成脚本正式发布~~
-----------------------------------------------------------------------------------------
SMRC具有高性能、高兼容、定制自由、使用方便的特点。
1.性能,100移动力轻松算出,无压力;
2.兼容,RGSS1-3通吃,效率保证;
3.支持移动形状定制,支持4方位、6方位、正方形或其他任意有移动规律的形状;
4.可以充当高性能寻路来使用。
【链接点此】
-----------------------------------------------------------------------------------------
【2016/01/06更新 | 改版】RM脚本编辑器Gemini
-----------------------------------------------------------------------------------------

Lv5.捕梦者 (暗夜天使)

只有笨蛋才会看到

梦石
1
星屑
20895
在线时间
9331 小时
注册时间
2012-6-19
帖子
7105

开拓者短篇九导演组冠军

发表于 2015-10-16 13:16:36 | 显示全部楼层
  1. def my_method(param1,param2)
  2.   p param1
  3.   p param2
  4.   yield "!"
  5. end

  6. def call_method(method,*args)
  7.   proc = Proc.new do |args|
  8.     p args
  9.   end
  10.   send(method,*args,&proc)
  11. end

  12. call_method("my_method","Hello","World")
复制代码

评分

参与人数 1星屑 +66 收起 理由
寒冷魔王 + 66 +666 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
48
在线时间
784 小时
注册时间
2013-1-4
帖子
1102
发表于 2015-10-16 12:10:46 | 显示全部楼层
你这是在干吗QAQ
稀奇古怪的写法。。。
总觉得是思路问题

评分

参与人数 1星屑 +1 收起 理由
寒冷魔王 + 1 -300 小墨水禁止卖萌

查看全部评分

RM-GUI延期。。。最近被黑心老板压迫T_T
二次元少女的shitake,长着长脸,身高165,蓝色卷双马尾,FCUP,瞳色黑色,病气和御宅属性,是天才少女。
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2207
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

发表于 2015-10-16 15:12:34 | 显示全部楼层
本帖最后由 taroxd 于 2015-10-16 15:33 编辑

问题在于,ruby 的方法不是对象。所以,你这个东西用正常的 ruby 写会比较难看。
用这种风格写会漂亮一些

RUBY 代码复制
  1. # range1[10][:display]
  2. # range2[10][:display]
  3. # range1[10][method :print]
  4. # range2[10][-> n { print n / 2 }]
  5. range1 = -> n { -> f { n.times &f } }
  6. range2 = -> n { -> f { n.times.reverse_each &f }}
  7.  
  8. does = -> range { range[:display] }
  9.  
  10. does[range1[10]]
  11. puts
  12. does[range2[10]]
  13. puts


保持原有 range1 定义的话,可以这样
RUBY 代码复制
  1. def range1(n, &f)
  2.   n.times &f
  3. end
  4.  
  5. def does(callable, *args)
  6.   callable.call(*args, &:display)
  7. end
  8.  
  9. does method(:range1), 10
  10. puts


总之,这种不方便也就是调用函数可以不打括号的代价。非常需要函数作为对象的时候,就用 method 方法转换吧。或者有时干脆用 lambda 其实也是很方便的。

点评

不过上面没写,用 -> a { ... }, ->(a) { ... }, ->a{...},以及把 { ... } 改成 do...end 都可以  发表于 2015-10-16 17:44
谢谢  发表于 2015-10-16 17:43
https://github.com/ruby/ruby/blob/trunk/doc/syntax/literals.rdoc#procs  发表于 2015-10-16 17:41
-> xx { xx } 这种形式有没有具体的资料可以参考?  发表于 2015-10-16 17:11

评分

参与人数 1星屑 +20 收起 理由
寒冷魔王 + 20 多谢~

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

路人党员

梦石
0
星屑
51
在线时间
2276 小时
注册时间
2010-12-30
帖子
3225
发表于 2015-10-16 21:11:37 | 显示全部楼层
do4会出错是因为eval时n不存在
  1. do4("range1(%d)" % n)
复制代码

点评

_(:зゝ∠)_这个n只是举了个简单的例子,实际情况比这个复杂,需要类等等  发表于 2015-10-16 21:16
本人擅长XP,如果有脚本或者Ruby方面的问题欢迎发电邮到[email protected]咨询,本人很少检查电邮所以不一定会及时回复,本人不会直接出手解决问题只会提供一个方向,所以谢绝伸手党
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
105
在线时间
36 小时
注册时间
2014-10-6
帖子
99
发表于 2015-10-17 22:20:21 | 显示全部楼层
_(:зゝ∠)_幸好看不懂

点评

_(:зゝ∠)_好久不见  发表于 2015-10-17 22:33
~
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
105
在线时间
36 小时
注册时间
2014-10-6
帖子
99
发表于 2015-10-17 22:36:28 | 显示全部楼层
羽世 发表于 2015-10-17 22:20
_(:зゝ∠)_幸好看不懂

_(:зゝ∠)_好久不见
~
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-16 15:02

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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