简体   繁体   English

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

[英]undefined method … for class (NoMethodError)

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

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 Person class, not instances. 这是对Person类的3个引用,而不是实例。 Then later you do: 然后你会做:

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_beer on that first item, it does have that method because send_for_beer is 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_array to 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. Ruby还支持隐式返回方法中的最后一个表达式。 So you do not need to return result . 所以你不需要return result Instead, simply calulate the return value as the only line in the method. 相反,只需将返回值计算为方法中的唯一行。

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

Instance variables don't quite work like that either. 实例变量也不像那样工作。 When you have @name in the class body directly, you are not initializing instance variables for each instance. 如果直接在类主体中使用@name ,则不会为每个实例初始化实例变量。 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. 你真正需要做的是从任何实例方法设置它们,通常是initialize ,你在这里做。 So you can totally remove the instance variable setting at the class level here. 因此,您可以在此处完全删除类级别的实例变量设置。

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

If you have an array of fixed length, you can supply a block to create a new Person object for each element. 如果您有一个固定长度的数组,则可以提供一个块来为每个元素创建一个新的Person对象。 You could rewrite your person_array line as follows: 您可以按如下方式重写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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM