Project1
标题: 【Ruby】block的模板实现问题 [打印本页]
作者: 寒冷魔王 时间: 2015-10-16 11:20
标题: 【Ruby】block的模板实现问题
本帖最后由 寒冷魔王 于 2015-10-16 13:38 编辑
我有两个用法相同的函数:
def range1(n)
n.times { |i| yield(i) }
end
def range2(n)
n.times { |i| yield(n-i-1) }
end
def range1(n)
n.times { |i| yield(i) }
end
def range2(n)
n.times { |i| yield(n-i-1) }
end
这两个函数都可以通过
rangeN(n) { |i| print(i) }
来调用,具有一致性。
我想通过使用一个函数does,实现上述模板。
比如这种方式
does({range1(10)}) # 此为理想状态,不正确
does({range2(10)}) # 此为理想状态,不正确
如下我做了一番尝试:
def do1(proc)
proc.call { |i| print(i) }
end
def do2(&block)
block.call.call { |i| print(i) }
end
def do3(*args)
print(*args)
end
def do4(sym)
#eval(sym + "{ |i| print(i) }") # ! Error!
end
n = 10
range1(n) { |i| print(i) }
puts
puts("1.1:")
do1( ->(&block) { range1(n) { |i| block.call(i) } } )
puts
puts("1.2:")
do1( Proc.new { |&block| range1(n) { |i| block.call(i) } } )
puts
puts("2:")
do2 { ->(&block) { range1(n) { |i| block.call(i) } } }
puts
puts("3:")
range1(n) { |*args| do3(*args) }
puts
puts("4:")
do4("range1(n)") # ! Error!
def do1(proc)
proc.call { |i| print(i) }
end
def do2(&block)
block.call.call { |i| print(i) }
end
def do3(*args)
print(*args)
end
def do4(sym)
#eval(sym + "{ |i| print(i) }") # ! Error!
end
n = 10
range1(n) { |i| print(i) }
puts
puts("1.1:")
do1( ->(&block) { range1(n) { |i| block.call(i) } } )
puts
puts("1.2:")
do1( Proc.new { |&block| range1(n) { |i| block.call(i) } } )
puts
puts("2:")
do2 { ->(&block) { range1(n) { |i| block.call(i) } } }
puts
puts("3:")
range1(n) { |*args| do3(*args) }
puts
puts("4:")
do4("range1(n)") # ! Error!
有没有更为简便的写法呢?
===============
感谢@喵呜喵5 大触的答案,已经成功实现does:
def does(method_name,*args)
send(method_name,*args) { |i| print(i) }
end
does(:range1,10)
puts
does(:range2,10)
puts
def does(method_name,*args)
send(method_name,*args) { |i| print(i) }
end
does(:range1,10)
puts
does(:range2,10)
puts
作者: 墨凌羽 时间: 2015-10-16 12:10
你这是在干吗QAQ
稀奇古怪的写法。。。
总觉得是思路问题
作者: 喵呜喵5 时间: 2015-10-16 13:16
- def my_method(param1,param2)
- p param1
- p param2
- yield "!"
- end
- def call_method(method,*args)
- proc = Proc.new do |args|
- p args
- end
- send(method,*args,&proc)
- end
- call_method("my_method","Hello","World")
复制代码
作者: taroxd 时间: 2015-10-16 15:12
本帖最后由 taroxd 于 2015-10-16 15:33 编辑
问题在于,ruby 的方法不是对象。所以,你这个东西用正常的 ruby 写会比较难看。
用这种风格写会漂亮一些
# range1[10][:display]
# range2[10][:display]
# range1[10][method :print]
# range2[10][-> n { print n / 2 }]
range1 = -> n { -> f { n.times &f } }
range2 = -> n { -> f { n.times.reverse_each &f }}
does = -> range { range[:display] }
does[range1[10]]
puts
does[range2[10]]
puts
# range1[10][:display]
# range2[10][:display]
# range1[10][method :print]
# range2[10][-> n { print n / 2 }]
range1 = -> n { -> f { n.times &f } }
range2 = -> n { -> f { n.times.reverse_each &f }}
does = -> range { range[:display] }
does[range1[10]]
puts
does[range2[10]]
puts
保持原有 range1 定义的话,可以这样
def range1(n, &f)
n.times &f
end
def does(callable, *args)
callable.call(*args, &:display)
end
does method(:range1), 10
puts
def range1(n, &f)
n.times &f
end
def does(callable, *args)
callable.call(*args, &:display)
end
does method(:range1), 10
puts
总之,这种不方便也就是调用函数可以不打括号的代价。非常需要函数作为对象的时候,就用 method 方法转换吧。或者有时干脆用 lambda 其实也是很方便的。
作者: 英顺的马甲 时间: 2015-10-16 21:11
do4会出错是因为eval时n不存在
作者: 羽世 时间: 2015-10-17 22:20
_(:зゝ∠)_幸好看不懂
作者: 羽世 时间: 2015-10-17 22:36
羽世 发表于 2015-10-17 22:20
_(:зゝ∠)_幸好看不懂
_(:зゝ∠)_好久不见
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |