为什么我的ruby方法总是返回true?

时间:2012-12-18 16:03:41

标签: ruby class collections boolean

从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**即使从未作为集合的一部分插入。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

return true if game == game

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

总是如此。

你可能想要这样的东西:

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

答案 1 :(得分:1)

这里有一些错误:

  1. 您应该使用self.XXXX来创建实例变量 使用@XXXX,它直接访问值,使用self实际执行 另一个方法调用,请参阅此处了解更多详细信息:Instance variable: self vs @

  2. 正如提到的其他人game == game将始终返回true,答案就是答案 已发布但不允许将多个游戏传递到has_game?

  3. 以下是我的更改正常工作:

    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