如何将自定义方法添加到Ruby中的现有Enumerable模块?我正在运行Ruby 2.0。
答案 0 :(得分:3)
将方法添加到每个其他模块的方法相同。
如果您要将带有参数bar
和baz
的方法quux
添加到模块Foo
,请编写
module Foo
def bar(baz, quux)
# code code code
end
end
因此,如果要将方法histogram
添加到模块Enumerable
,请编写
module Enumerable
# Counts the number of occurrences of each unique object in `self`.
#
# @return [Hash<E, Integer>] a `Hash` of objects mapped to number of occurrences in `self`.
def histogram
group_by(&:itself).map {|k, v| [k, v.size] }.to_hash
end
end
答案 1 :(得分:2)
在Ruby中,您可以使用monkey-patching
,其中包含open classes
的概念。这意味着Ruby中的类可以随时修改。例如,您可以在数字类中创建一个double方法。
class Integer < Numeric
def self.double
self * 2
end
end
现在你可以在数字上调用双重方法
4.double
=> 8
希望这有帮助
答案 2 :(得分:0)
Enumerable
模块中定义的所有方法都要求接收者是枚举数或具有方法each
。假设我们希望创建一个类似于Enumerable#to_a的可枚举方法my_to_a
,除了它只返回接收者元素的第一个n
(或者,如果它是一个枚举器,则返回第一个{{1} }元素),n
是n
的参数。
my_to_a
行
module Enumerable
def my_to_a(n)
enum = is_a?(Enumerator) ? self : each
n.times.with_object([]) { |o,a| a << enum.next }
end
end
[0,1,2,3,4].my_to_a(3)
#=> [0, 1, 2]
(0..4).my_to_a(3)
#=> [0, 1, 2]
{ a:1, b:2, c:3, d:4, e:5 }.my_to_a(3)
#=> [[:a, 1], [:b, 2], [:c, 3]]
'0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).my_to_a(3)
#=> ["0", "1", "2"]
require 'prime'; Prime.my_to_a(4)
#=> [2, 3, 5, 7]
[0,1,2,3,4].my_to_a(6)
#=> StopIteration (iteration reached an end)
'0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).my_to_a(6)
#=> StopIteration (iteration reached an end)
如果enum = is_a?(Enumerator) ? self : each
是枚举器,将enum
设置为self
,否则将其设置为枚举器self
。后一种情况假设self.each
具有方法self
,这意味着类each
具有实例方法self.class
(或方法each
已在{ {1}}的单例课程)。 each
必须返回一个枚举数。在此示例中,self
(等效于each
)仅对于使用String#gsub且有一个参数且没有块的两个示例为is_a?(Enumerator)
。 1 在其他示例中,self.is_a?(Enumerator)
和true
。这些类是self.class.included_modules.includes?(Enumerable) #=> true
,self.class.instance_methods.include?(:each) #=> true
,Array
和Range
。 Hash
是前三个实例方法,Prime
是类方法。
一旦我们有了枚举数each
行
Prime
很简单。参见Integer#times,Enumerator#with_object和Enumerator#next。
1注意enum
,因此任何返回枚举数的方法(实例为n.times.with_object([]) { |o,a| a << enum.next }
)都会对Enumerator.included_modules #=> [Enumerable, Kernel]
方法作出响应。也就是说,方法的类(例如String)无需包含Enumerator
或具有方法Enumerable
。