在Ruby中,我们定义类成员函数,如
class Dog
def bark
puts "woof"
end
end
我想知道并且在google搜索中彻底失败的是,在Ruby中如何以及在何处定义处理对象数组的方法?
我希望能够做到这样的事情:
dogs = [Dog.new, Dog.new, Dog.new]
dogs.some_function
我如何以及在何处定义some_function
?
注意:我不是在解决特定问题之后,更多的是如何定义这样一个函数的步骤。
答案 0 :(得分:5)
为了让你的所有狗都吠叫,你应该在阵列上使用each
:
dogs.each(&:bark)
相当于
dogs.each { |dog| dog.bark }
很少需要在数组上定义方法,在这种情况下,它将在所有数组上都可用,包含任何内容。要做到这一点,你需要在<{1}}类中声明它,再次声明它:
Array
然后你可以跑:
class Array
def some_function
# do something...
end
end
以及
dogs = [Dog.new, Dog.new, Dog.new]
dogs.some_function
答案 1 :(得分:1)
您还可以创建一个继承自Array
的类,例如
class DogWalker < Array
def some_function
self.each(&:bark)
end
end
class Dog
def bark
puts "woof"
end
end
d = DogWalker.new([Dog.new,Dog.new,Dog.new])
d.some_function
#woof
#woof
#woof
#=> [#<Dog:0x2a5a2e8>, #<Dog:0x2a5a2d0>, #<Dog:0x2a5a2b8>]
这意味着您只能在DogWalker
的实例(以及Array
可用的所有方法)上调用此方法,但不会更改Array
本身。让您更好地控制其中包含的对象。 e.g。
class DogWalker < Array
def initialize(args)
raise ArgumentError.new("Must be an Array of Dogs") unless args.is_a?(Array) && args.all?{|e| e.is_a?(Dog)}
super
end
end
d = DogWalker.new([Dog.new,Dog.new,Dog.new])
#=>[#<Dog:0x2a5a2e8>, #<Dog:0x2a5a2d0>, #<Dog:0x2a5a2b8>]
d = DogWaler.new([Dog.new,12])
#=>ArgumentError: Must be an Array of Dogs
Array.new([1,2,3])
#=>[1,2,3]
正如@UriAgassi指出的那样,您很少需要更改基类,尤其是在设计不需要/不能跨对象类型应用的扩展功能时。这是一个例子:
class Array
def some_function
self.map(&:bark)
end
end
class Dog
def bark
"woof"
end
end
d = [Dog.new,Dog.new]
d.some_function
#=> ["woof","woof"]
d = [1,2,3,4]
d.some_function
#=>NoMethodError: undefined method `bark' for 1:Fixnum
由于Array
可以接受任何对象类型,Array
很好,但some_function
方法需要一个responds_to
bark
的对象,该对象将在事件中引发对象无法执行请求的任务。
答案 2 :(得分:0)
在您的示例中,“狗”是Array class的实例。 如果要扩展Array类,可以像这样添加方法:
class Array
def some_function
end
end