ruby 未定义的方法......用于类(NoMethodError)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9487568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:50:16  来源:igfitidea点击:

undefined method ... for class (NoMethodError)

ruby

提问by DarkSun

I'm just startin to learn ruby and I'm writing a simple program, but I've got an error undefined method 'send_for_beer' for Person:Class (NoMethodError)Here is a code:

我刚刚开始学习 ruby​​,我正在编写一个简单的程序,但是我遇到了一个错误undefined method 'send_for_beer' for Person:Class (NoMethodError)这是一个代码:

class Person
    @iq = 0
    @speed = 0
    @power = 0
    @beauty = 0
    def initialize (iq, speed, power, beauty)
        @iq = iq
        @speed = speed
        @power = power
    end

    def send_for_beer
        result @iq * 2 + @speed * 10 + @power * 5 + @beauty
        return result
    end
end

number_of_people = 3
person_array = Array.new(number_of_people, Person)
n = 0
beer_person = 0
beer_cof = 0
number_of_people.times do 

    ............
    person_array.push(Person.new(iq, speed, power, beauty))

    if person_array[n].send_for_beer > beer_cof     <-----here is an error
        beer_cof = person_array[n].send_for_beer
        beer_person = n
    end
    n = n+1
end

回答by Alex Wayne

Here's your problem:

这是你的问题:

person_array = Array.new(number_of_people, Person)

In short, don't make array like this. Use the []literal syntax. What this returns is:

总之,不要像这样制作数组。使用[]文字语法。这返回的是:

[Person, Person, Person]

That is 3 references to the Personclass, not instances. Then later you do:

那是对Person类的3 个引用,而不是实例。然后你做:

person_array.push(Person.new(iq, speed, power, beauty))

And you end up with:

你最终得到:

[Person, Person, Person, person_instance]

So when you iterate through and call send_for_beeron that first item, it does have that method because send_for_beeris an instance method that you are calling erroneously on a class object.

因此,当您迭代并调用send_for_beer第一项时,它确实具有该方法,因为send_for_beer您在类对象上错误地调用了一个实例方法。

The fix here is to simply assign person_arrayto an empty array literal, and then push things to it.

这里的解决方法是简单地分配person_array给一个空数组文字,然后将内容推送给它。

person_array = []


And a minor style note: <<is usually preferred to Array#push, making the filling of the array look more like this.

还有一个小风格说明:<<通常比 更Array#push受欢迎,使数组的填充看起来更像这样。

person_array << Person.new(iq, speed, power, beauty)


Ruby also support implicit return of the last expression in a method. So you do not need to return result. Instead, simply calulate the return value as the only line in the method.

Ruby 还支持隐式返回方法中的最后一个表达式。所以你不需要return result。相反,只需将返回值计算为方法中的唯一行。

def send_for_beer
  @iq * 2 + @speed * 10 + @power * 5 + @beauty
end


Instance variables don't quite work like that either. When you have @namein the class body directly, you are not initializing instance variables for each instance. You are actually setting instance variable on the class object (which is weird, I know). What you actually need to do is set them from any instance method, typically initialize, which you are doing here. So you can totally remove the instance variable setting at the class level here.

实例变量也不太像那样工作。当您@name直接在类体中时,您不会为每个实例初始化实例变量。您实际上是在类对象上设置实例变量(这很奇怪,我知道)。您实际需要做的是从任何实例方法中设置它们,通常initialize是您在这里所做的。所以你可以在这里完全删除类级别的实例变量设置。

回答by Baldrick

I think you've a syntax error in the method send_for_beer, the =sign is missing in the affectation of the variable result.

我觉得你的方法已经有语法错误send_for_beer时,=符号在变量的做作失踪result

By the way, the method can be written

顺便说一下,方法可以写成

def send_for_beer
    @iq * 2 + @speed * 10 + @power * 5 + @beauty
end

回答by Jonathan

If you have an array of fixed length, you can supply a block to create a new Person object for each element. You could rewrite your person_array line as follows:

如果你有一个固定长度的数组,你可以提供一个块来为每个元素创建一个新的 Person 对象。您可以按如下方式重写您的 person_array 行:

person_array = Array.new(number_of_people) { Person.new(0, 0, 0, 0) }

Add the following line to the top of your class.

将以下行添加到类的顶部。

attr_writer(:iq, :speed, :power, :beauty)

This snipped of code could then modify the objects in your array.

这段代码片段可以修改数组中的对象。

person_array.each do |p|
    p.iq, p.speed, p.power, p.beauty = rand(20) + 1, rand(5) + 1, 1
    p.beauty = 10 if (rand(2) == 0)
end