2012-02-28 20 views
2

私はルビーを学ぶためにちょうどSTARTINだと私は簡単なプログラムを書いているが、私はここでエラーundefined method 'send_for_beer' for Person:Class (NoMethodError) を持っているコードです:未定義のメソッド...(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 

答えて

8

ここにあなたの問題だ書き込むことができます。 []リテラル構文を使用します。これは返すことです:Personクラスに3つの参照、ないのインスタンスである

[Person, Person, Person] 

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

そして、あなたがで終わる:その後、後であなたが

[Person, Person, Person, person_instance] 

あなたはを反復処理し、その最初の項目にsend_for_beerを呼び出すときsend_for_beerがインスタンスメソッドであるため、だから、それはその方法を持っていないことあなたはクラスオブジェクトで誤って呼び出しています。

空の配列リテラルにを代入して、それに物事をプッシュするだけです。

person_array = [] 

とマイナースタイルノート

<<は、通常、アレイの充填がより次のようになりながら、 Array#pushに好ましいです。

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

Rubyは、メソッドの最後の式の暗黙の復帰をサポートしています。だからあなたはreturn resultする必要はありません。代わりに、メソッドの唯一の行として戻り値を単純に較正します。

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

インスタンス変数は、かなりのいずれかのそのように動作しません。クラス本体に@nameが直接存在する場合は、インスタンスごとにインスタンス変数を初期化していません。実際にはクラスオブジェクトにインスタンス変数を設定しています(これは不思議ですが、私は知っています)。実際に行う必要があるのは、インスタンスメソッド(通常はinitialize)から設定することです。したがって、ここでクラスレベルでインスタンス変数設定を完全に削除することができます。

1

私はあなたがsend_for_beerメソッドで構文エラーを起こしたと思いますが、変数resultの影響で=記号が欠落しています。このような配列をしない、要するに

person_array = Array.new(number_of_people, Person) 

:ところで

は、方法は

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

固定長の配列を持っている場合は、各要素の新しいPersonオブジェクトを作成するブロックを指定できます。

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

があなたのクラスの先頭に次の行を追加します。次のようにあなたのPERSON_ARRAY行を書き換えることができます。

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

これで、コードが切り取られ、配列内のオブジェクトが変更される可能性があります。

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 
関連する問題