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:
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
Best Answer
Here's your problem:
In short, don't make array like this. Use the
[]
literal syntax. What this returns is:That is 3 references to the
Person
class, not instances. Then later you do:And you end up with:
So when you iterate through and call
send_for_beer
on that first item, it does have that method becausesend_for_beer
is an instance method that you are calling erroneously on a class object.The fix here is to simply assign
person_array
to an empty array literal, and then push things to it.And a minor style note:
<<
is usually preferred toArray#push
, making the filling of the array look more like this.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.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. 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, typicallyinitialize
, which you are doing here. So you can totally remove the instance variable setting at the class level here.