1

从 codeschool 的 ruby​​-bits 课程中,我试图了解这些类是如何工作的——我有一个Game类和一个集合类,称为Library存储游戏集合。

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)

当我尝试查找某个游戏是否正在myCollection使用该has_game?方法时,我总是得到true

puts myCollection.has_game?(contra) #=> returns **true**即使这从未作为集合的一部分插入。

我究竟做错了什么?

4

2 回答 2

2
return true if game == game

我认为这种说法可能会引起问题。

它总是正确的。

你可能想要这样的东西:

def has_game?(wanted)
  for game in self.games
    return true if game == wanted
  end
  false
end
于 2012-12-18T16:07:11.587 回答
1

这里有几件事是错误的:

  1. 而不是使用self.XXXX创建实例变量你应该使用@XXXX,它直接访问值,使用 self 实际上执行另一个方法调用,请参阅此处了解更多详细信息:实例变量: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
于 2012-12-18T16:47:58.367 回答