如何通过&:语法为is_a?方法传递Integer参数?
如何给Ruby的
is_a?方法用&:语法传递参数 你猜的完全没错![1,2,3].all?(&:is_a?(Integer))报错的核心原因就是:Ruby的&:语法糖只能跟单纯的方法名符号,不能直接带参数调用方法。
先搞懂&:的本质
&:method_name其实是Symbol#to_proc的简写,它会生成一个这样的proc:
proc { |obj| obj.method_name }
这个proc只能接收一个对象参数,然后调用该对象的对应方法——没有额外参数的位置,所以你直接给:is_a?加(Integer)肯定会触发语法错误。
解决方法:用柯里化(Currying)实现带参数的方法绑定
如果一定要用&语法来传递参数,可以借助Ruby的方法柯里化特性,把需要的参数提前绑定到is_a?方法上:
[1,2,3].all?(&method(:is_a?).curry[Integer])
拆解一下这个写法的逻辑:
method(:is_a?):获取当前上下文中的is_a?方法对象(is_a?是Object的实例方法,这里借助Kernel模块的方法引用能力);.curry:把这个方法转成柯里化方法,允许我们分步传递参数;[Integer]:给柯里化后的方法传入第一个参数Integer;&:把绑定好参数的柯里化方法转成proc,传给all?方法。
当然,也可以换更直观的写法
其实你最初的块写法[1,2,3].all? {|x| x.is_a?(Integer)}已经非常清晰易读了,如果你不是特别执着于&:语法,保留这种写法反而更友好,团队协作时也更容易被理解。
内容的提问来源于stack exchange,提问作者Balocre
相关产品推荐
相关产品推荐

