2009-07-13 27 views
2

私は学校向けのRubyプロジェクトで作業していますが、悲しいかなか私の文献でこの質問に対する答えを見つけることができませんでした。Ruby - 配列内のオブジェクトへのメソッド呼び出し

キャンプ用ロットの配列があり、それぞれにゲストが含まれています。私はこのような多くを初期化します。私はGuestオブジェクトを作成し、それを初期化し、そして今、私は私のLotGuestを追加したいダウン

lots = Array.new 

for i in (1..36) 
    lots[i] = Lot.new(i) 
end 

さらなる。クラスLotのメソッドは次のようになります。LotArrayであるように私は、メソッドを呼び出したいとき

def AddGuest(guest) 
    @guest = guest 
end 

問題が来ます。

lots[lotnumber].AddGuest(guest) 

この呼び出しは私にエラーを与える:私が使用している

undefined method `[email protected]' for #<Guest:0x2c1ff14> (NoMethodError) 

が必要なので、クラスがお互いのことを知っています。私はRubyを理解するのに苦労しましたが、ArrayクラスのAddGuestメソッドにアクセスしようとするとエラーが発生する可能性がありますか?私はC++でこれを行うのに慣れています。

以下は完全なソースです(少なくとも関連する部分)。

全体Lotクラス:main.rb

#includes 
require 'guest' 
require 'lot' 

#initiate comparison variables 
userInput = "0" 
numberOfGuests = 0 
foundLot = false 
guests = Array.new 
lots = Array.new 

#initialize lot list 
for i in (1..36) 
    lots[i] = Lot.new(i) 
end 

プレーヤー入力の

class Lot 

    def initialize(number) 
    @gauge = rand(2000) + 2000 
    @number = number 
    @guest = false 
    end 

    def Occupied() 
    return @guest 
    end 

    def AddGuest(guest) 
    @guest = guest 
    end 

    def RemoveGuest() 
    @guest = false 
    end 

end 

部品は、一般的にRubyのメソッド名は大文字ではありません

#make sure lot is not taken 
while foundLot == false do 
    lotnumber = rand(35)+1 
    if lots[lotnumber].Occupied() == false then 
    foundLot = "true" 
    end 
end 
foundLot = false 

guest = Guest.new(firstName, lastName, adress, phone, arrival, lotnumber) 
guests.insert(numberOfGuests, guest) 
numberOfGuests++ 

lots[lotnumber].AddGuest(guest) #this is where error hits 

end 

end 

end 
+5

あなたは完全なソースを投稿することができますか?クラスのスコープで定義されているAddGuestメソッドですか? –

+0

誤ってAddGuestをプライベートにしたり、保護したりする可能性はありますか? – Ori

+0

ちょうど参考にして、ロットをより簡単に 'lots =(1..36).collect {| n | Lot.new n} 'を選択します。 Rubyは、明示的に多くのループを排除します。 – Chuck

答えて

6

エラーは++演算子の使用に関連しているように見えますが、これはC++では非常に自然にサポートされていますが、Rubyではサポートされていません。

同等です:

numberOfGuests += 1 
+1

それはそれを解決しました!すばらしい迅速な回答に感謝します。さて、もし私がちょうど私の行の最後にセミコロンを追加することを止めることができたら... :) – Tobbe

0

を省略しました。規約は単純に:ClassName、CONSTANT、method_nameです。あなたはロットオブジェクトの配列を持っているので

、以下が真でなければなりません:

lots.class # => Array 
lots[1].class # => Lot 

と呼ばれる方法は、ロットのために定義する必要があります。

+0

申し訳ありませんが不明な場合は、呼び出されたメソッドがLotに対して定義されています。私がArrayクラスについて話していたとき、私は組み込みクラスを意味していましたが、私は自分で作成していません。 – Tobbe

+0

貼り付けたコードサンプルに対処する異なる応答を投稿したばかりです。私はそれが助けて欲しい – tadman

1

カップル少しヒント...

[1]

Aこれを書くために少しより多くの慣用的な方法...

for i in (1..36) 
    lots[i] = Lot.new(i) 
end 

は...

(1..36).each { |i| lots[i] << Lot.new(i) } 

[2]

をロットからのユーザーレビューを削除するには、nilではなくfalseに設定することをお勧めします。

>> lot = Lot.new(2) 
=> #<Lot:0x1300920 @number=2, @gauge=3444> 
>> lot.occupied 
=> false 
>> lot.add_guest('A guest') 
=> "A guest" 
>> lot.occupied? 
=> true 
>> lot.remove_guest 
=> nil 
>> lot.occupied? 
=> false 

は、それはあなたのクラス定義でattr_accessorメソッドを使用する従来のです2 ...

を取る:これは、使用の私の提案...

class Lot 

    def initialize(number) 
    @gauge = rand(2000) + 2000 
    @number = number 
    # Don't need to set @guest -- it's nil by default. 
    end 

    # In Ruby, methods that return a boolean often have a "?". 
    # Makes it "read better" when you call the method. (See 
    # usage sample.) 
    def occupied? 
    ! @guest.nil? 
    end 

    # There's a more commonplace way to do this. See below... 
    def add_guest(guest) 
    @guest = guest 
    end 

    def remove_guest() 
    @guest = nil 
    end 

end 

例だろう。彼らはあなたのクラスに自動的にgetterメソッドとsetterメソッドを追加します。あなたは...代わりにadd_guestremove_guestのあなたは一般的なRubyのパターンに従うことを望んでいた場合、その

class Lot 

    attr_accessor :number, :gauge, :guest 

    def initialize(number) 
    @gauge = rand(2000) + 2000 
    @number = number 
    end 

    def occupied? 
    ! @guest.nil? 
    end 

end 

使い方...ロット(add_guestのような)のユーザーレビューを設定し

irb(main):017:0> lot = Lot.new(3) 
=> #<Lot:0xb7f7fca8 @gauge=3186, @number=3> 

を行うことができます。 ..

irb(main):019:0> lot.guest = 'A guest' 
=> "A guest" 
irb(main):020:0> lot.occupied? 
=> true 

は...ロットのためのユーザーレビューを見る

irb(main):025:0> lot.guest 
=> "A guest" 

ユーザーレビューを削除...

irb(main):021:0> lot.guest = nil 
=> nil 
irb(main):023:0> lot.occupied? 
=> false 
+0

実際には、あなたのために汚い仕事をするためにArray#collectを使うことがさらに良いでしょう。 (1..36).collect {| i | Lot.new(i)}。これは例のように0でインデックス付けされ、1でインデックス化されません。 – tadman

+0

または 'Array.new(36){| i | Lot.new(i)} – rampion

+0

"lots [i] << Lot.new(i)"では、 "<<"ではなく "="を使用しますか? –

関連する問題