Ruby 符号#到_使用自定义方法处理
我喜欢在Ruby中使用Ruby 符号#到_使用自定义方法处理,ruby,Ruby,我喜欢在Ruby中使用Symbol#to_proc将方法作为块传递: [1.0, 2.0, 3.0].map(&:to_i) #=> [1, 2, 3] 我还可以定义自己的lambda,times\u two,并将其作为块传递: times_two = ->(x) {x * 2} [1, 2, 3].map(×_two) #=> [2, 4, 6] 虽然我似乎无法将时间作为符号传递: [1, 2, 3].map(&:times_two)
Symbol#to_proc
将方法作为块传递:
[1.0, 2.0, 3.0].map(&:to_i)
#=> [1, 2, 3]
我还可以定义自己的lambda,times\u two
,并将其作为块传递:
times_two = ->(x) {x * 2}
[1, 2, 3].map(×_two)
#=> [2, 4, 6]
虽然我似乎无法将时间作为符号传递:
[1, 2, 3].map(&:times_two)
#=> ArgumentError: wrong number of arguments (0 for 1)
但是,当我尝试对某个方法执行相同操作时,会出现一个错误:
def times_three(x)
x * 3
end
[1, 2, 3].map(×_three)
#=> ArgumentError: wrong number of arguments (0 for 1)
[1, 2, 3].map(&:times_three)
#=> ArgumentError: wrong number of arguments (0 for 1)
我猜我不能这样做,因为times\u three
是一种方法,而不是过程
那么,您如何定义自定义方法,以便它们可以像上面第一个示例中的to\u i
那样在Symbol#to_proc
时尚中使用呢
例如,我如何才能做到这一点
[1, 2, 3].map(&:times_three)
#=> [3, 6, 9]
编辑:
我看了下面发布的视频,显然你可以使用方法
方法接近Symbol#to_proc:
def times_three(x)
x * 3
end
t_three = method(:times_three)
[1, 2, 3].map(&t_three)
#=> [3, 6, 9]
然而,这并不完全是符号到过程:
您必须在
整数
或数值
上定义三次
程序符号由Peter Cooper解释:
现在,因为times_three现在是Integer类的一个方法,所以您可以使用符号来处理
[1, 2, 3].map(&:times_three)
如果要访问不属于对象类但作用于对象的方法,则需要将该对象作为参数传递给该方法
def times_three(x)
x * 3
end
[1, 2, 3].map{|i| times_three(i) }
要处理的符号
需要将对象用作接收器
[1, 2, 3].map(&:some_action)
相当于
[1, 2, 3].map{|i| i.some_action}
不要链接到随机引用,你应该在这里写下简短的解释/复制它,并将链接作为你的anwser的来源。谢谢你的视频。但是,它没有说明为什么我必须在
整数
或数值
上定义乘以三次
。它显示了在Ruby采用Symbol#to#proc之前,如何在类上实现to#u proc
,尽管视频没有显示如何以这种方式定义自己的方法。@GarytheGat:它确实显示了Symbol#to#u proc
是如何实现的,即在块的第一个参数上调用该方法,将块的其他参数作为方法调用的参数传递。在您的例子中,块的第一个参数是1
(在第一次迭代中),并且没有其他参数,因此Symbol#to_proc
调用1。times_three
,ergo,times_three
需要在1
的一个类中定义,即Fixnum
,Integer
,Numeric
,对象
,内核
或基本对象
。不幸的是,…也没有什么帮助。谢天谢地,鲁宾尼乌斯从不让人失望,资料更具可读性,事实上,它的内容基本上只有一行:。非常感谢你的清晰解释,史蒂夫。现在我知道了如何做到这一点,使用这样的方法对核心类进行monkey patch以清除复杂或重复的块是可以接受的做法吗?好的,是的,只要目的明确并且有好处,monkey patch绝对可以。本周我有一个rails应用程序,其中强制输入字段的标签中有一个星号,例如“First Name*”
和“City*”
,企业突然希望所有星号都是红色字体。我本可以编写一个像red\u asterisk('First Name*')
这样的助手方法,但是用猴子补丁字符串类'First Name*'更容易。red\u asterisk
然后只需在*'
上进行全局查找/替换,它就变成了*'。red<但是,代码>自我
是。我假设self
对于像*
,%
这样的方法必须是显式的,这些方法包含语法上的糖分。你或其他人知道这是不是真的吗?@CarySwoveland我认为是的,因为我认为语法糖不是由解析器使用的,只是由我们这些简单的程序员使用的。:)在我的概念模型中,*
很可能被解释为self.*(arg)
或者更可能是self.send(:*,arg)
,所以您需要def*;结果=0;arg.times{result+=self};结果;结束
如果输出取决于接收器(3*5与7*5不同),则需要使用self
。如果你想让输出无条件,比如说,3*5=>“我不知道”;7*5=>“我不知道”
然后跳过self
。任何新手读到这篇文章,不要在家里尝试!不适合猴子补丁*
,%
,+
等。
[1, 2, 3].map(&:some_action)
[1, 2, 3].map{|i| i.some_action}