2012-12-18 52 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

那么我该如何解决这个问题? –

相关问题