2012-12-18 208 views
1

從codechool的ruby-bits課程,我試圖瞭解這些類是如何工作的 - 我有一個Game類和一個名爲Library的集合類,用於存儲一系列遊戲。爲什麼我的ruby方法總是返回true?

class Game 
    attr_accessor :name, :year, :system 
    attr_reader :created_at 

    def initialize(name, options={}) 
    self.name = name 
    self.year = options[:year] 
    self.system = options[:system] 
    @created_at = Time.now 
    end 


    def ==(game) 
    name == game.name && 
    system == game.system && 
    year == game.year 
    end 
end 

圖書館類:

class Library 
    attr_accessor :games 

    def initialize(*games) 
    self.games = games 
    end 

    def has_game?(*games) 
    for game in self.games 
     return true if game == game 
    end 
    false 
    end 
end 

現在我創造一些遊戲:

contra = Game.new('Contra', { 
    year: 1994, 
    system: 'nintendo' 
}) 

mario = Game.new('Mario', { 
    year: 1996, 
    system: 'SNES' 
}) 

sonic = Game.new('Sonic', { 
    year: 1993, 
    system: 'SEGA' 
}) 

和實例化一個新的集合:

myCollection = Library.new(mario, sonic) 

當我試圖找到,如果某些遊戲在使用has_game?方法210,我總是儘管這從未被插入作爲集合的一部分true

puts myCollection.has_game?(contra) #=> returns **true**

我在做什麼錯?

+3

因爲'遊戲==遊戲「總是如此。 – melpomene

+0

那麼Game類中的==(遊戲)'實例方法就是這個問題?我該如何解決?我需要檢查遊戲是否爲集合的一部分 –

+2

不,問題在於您將「遊戲」與自己進行比較。 – melpomene

回答

1

有一對夫婦的事情,錯在這裏是:

  1. 而不是使用self.XXXX創建實例變量,你應該 使用@XXXX,它直接訪問值,使用自己實際執行 另一種方法調用,請參閱此處瞭解更多詳細信息:Instance variable: self vs @

  2. 當別人提到game == game將始終返回true,即 已經發布不允許超過單場比賽傳球更has_game?

這裏是我的變化是正常工作了答案:

class Game 
    attr_accessor :name, :year, :system 
    attr_reader :created_at 

    def initialize(name, options={}) 
    @name  = name 
    @year  = options[:year] 
    @system  = options[:system] 
    @created_at = Time.now 
    end 


    def ==(game) 
    @name == game.name && 
    @system == game.system && 
    @year == game.year 
    end 
end 

class Library 
    attr_accessor :games 

    def initialize(*games) 
    @games = games 
    end 

    # only returns true if this Library 
    # has ALL of the games passed to has_game? 
    def has_game?(*_games) 
    _games.each do |game| 
     return false if not @games.include?(game) 
    end 

    return true 
    end 
end 

contra = Game.new('Contra', { 
    year: 1994, 
    system: 'nintendo' 
}) 

mario = Game.new('Mario', { 
    year: 1996, 
    system: 'SNES' 
}) 

sonic = Game.new('Sonic', { 
    year: 1993, 
    system: 'SEGA' 
}) 

myCollection = Library.new(mario, sonic) 
puts "Collection has Contra? #{myCollection.has_game?(contra)}" 
puts "Collection has Sonic and Mario #{myCollection.has_game?(sonic, mario)}" 

輸出:

Collection has Contra? false 
Collection has Sonic and Mario true 
+0

真棒!這正是我正在尋找的 –

+0

你的「has_game?()」方法只返回最後一個遊戲是否包含在@games中......它可能會更容易與一個數組相交,或者你可以這樣迭代:def has_game? (* _games); _ games.map {|game|@games.include(遊戲)}。all?; end – Pavling

+0

@Pavling你是對的,我忘了在發生錯誤時突然出現。 –

2
return true if game == game 

我覺得這個說法可能會導致問題。

它總是如此。

你可能想是這樣的:

def has_game?(wanted) 
    for game in self.games 
    return true if game == wanted 
    end 
    false 
end 
+0

那麼我該如何解決這個問題? –

相關問題