类的 Ruby 未定义方法“每个”
Posted
技术标签:
【中文标题】类的 Ruby 未定义方法“每个”【英文标题】:Ruby undefined method 'each' for class 【发布时间】:2013-04-28 14:38:24 【问题描述】:我在创建一个 Stats 类和另一个容器类时遇到错误。错误是
test.rb:43:in `<main>' undefined method `each' for #<Boyfriends:0x2803db8 @boyfriends=[, , , ]> (NoMethodError)
这是绝对有道理的,因为该类确实不包含该方法,但是 ruby 是否应该在父类和祖父母类中搜索该方法?该脚本显示所需的输出;它只是像这样在输出中嵌入错误
test.rb:43:in `<main>'I love Rikuo because he is 8 years old and has a 13 inch nose
I love dolar because he is 12 years old and has a 18 inch nose
I love ghot because he is 53 years old and has a 0 inch nose
I love GRATS because he is unknown years old and has a 9999 inch nose
: undefined method `each' for #<Boyfriends:0x2803db8 @boyfriends=[, , , ]> (NoMethodError)
这里是代码
class Boyfriends
def initialize
@boyfriends = Array.new
end
def append(aBoyfriend)
@boyfriends.push(aBoyfriend)
self
end
def deleteFirst
@boyfriends.shift
end
def deleteLast
@boyfriends.pop
end
def [](key)
return @boyfriends[key] if key.kind_of?(Integer)
return @boyfriends.find |aBoyfriend| aBoyfriend.name
end
end
class BoyfriendStats
def initialize(name, age, nose_size)
@name = name
@age = age
@nose_size = nose_size
end
def to_s
puts "I love #@name because he is #@age years old and has a #@nose_size inch nose"
end
attr_reader :name, :age, :nose_size
attr_writer :name, :age, :nose_size
end
list = Boyfriends.new
list.append(BoyfriendStats.new("Rikuo", 8, 13)).append(BoyfriendStats.new("dolar", 12, 18)).append(BoyfriendStats.new("ghot", 53, 0)).append(BoyfriendStats.new("GRATS", "unknown", 9999))
list.each |boyfriend| boyfriend.to_s
【问题讨论】:
我建议清理问题的语言/内容,否则会被删除。 【参考方案1】:这绝对有道理,因为该类确实不包含该方法,但正如我一直在阅读的那样,ruby 是否应该在类的父母和祖父母中搜索该方法?
没错,但是您没有声明任何超类,因此超类将是Object
。它也没有each
方法。
如果你想要一个可枚举的方法,你必须自己定义它——你可能想要遍历数组。
在这种情况下,您可以定义一个自己的 each 方法,将传递的块向下传递给数组 each
方法:
class Boyfriends
def each(&block)
@boyfriends.each(&block)
end
end
这里的&block
让您按名称捕获传递的块。如果您是 ruby 新手,这可能对您来说意义不大,解释它是如何工作的有点超出了这个问题的范围。 this Question 中接受的答案很好地解释了块和 yield
的工作原理。
获得 each 方法后,您还可以拉入 Enumerable 以获取一些方便的方法:
class Boyfriends
include Enumerable
end
另外,to_s
是一个应该返回字符串的方法,所以你应该删除BoyfriendStats#to_s
中的puts
。
【讨论】:
谢谢你。我知道这很容易解决,但由于我刚刚开始使用 ruby,所以我不太明白。我将您的帖子标记为答案,但我有一个问题。&
前缀对 ruby 中的变量有什么作用。我想我还没有读到任何关于它的内容。
我想知道输出来自哪里,在原始示例中。这是问题的有趣部分。
@xaxxon 我最后回答了这个问题。他的BoyfriendStats#to_s
方法中有一个puts
,当Ruby 尝试显示Boyfriends
实例时,这会导致输出。
@randynewfield 用相关问题的链接更新了答案。
感谢&block
的回答。我已经简要阅读了代码块并开始尝试在我自己的代码中使用它们。我想我读过的内容不包括&
前缀。感谢您的回答和进一步的阅读材料。以上是关于类的 Ruby 未定义方法“每个”的主要内容,如果未能解决你的问题,请参考以下文章
nil:NilClass 的未定义方法“每个”,但我使用了实例变量