什么原因导致游戏对象出现NameError?

问题描述 投票:0回答:1

我正在使用 Ruby 学习 OOP。我有 2 个课程 - 游戏和玩家。 将为井字游戏创建玩家和计算机。我的想法是使用 Player 类来创建游戏的玩家和计算机。

我相信 Player 类可以与 Game 类交互,因此 Game 类用

@player
初始化。游戏类应该能够打印出
player_name
,但是,它并没有按照我的计划发生。

class Game
    attr_accessor :player, :computer

    @@board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

    def initialize(player, computer)
        @player = player
        @computer = computer

        puts "#{player.name} vs #{computer.name}"
    end

    def self.player_name
        puts "#{player.name}" # line 14
    end

    def self.computer_name
        puts "#{computer.name}"
    end

    def self.status
        puts "#{@@board}"
    end
end
class Player
    attr_reader :name

    def initialize(name)
        @name = name

        puts "#{name} is online."
    end
end

我执行以下代码:

p1 = Player.new('John')
p2 = Player.new('Computer')
Game.new(p1, p2)
Game.player_name # line 39
Game.computer_name

收到以下错误消息。错误来自第 39 行和第 14 行。

John is online.
Computer is online.
John vs Computer
test.rb:14:in `player_name': undefined local variable or method `player' for Game:Class (NameError)

        puts "#{player.name}"
                ^^^^^^
Did you mean?  player_name
        from test.rb:39:in `<main>'

我真的很困惑我的错误在哪里。

ruby
1个回答
7
投票

我真的很困惑我的错误在哪里。

您将实例变量/方法与类变量/方法混合在一起。

attr_accessor :player
定义由实例变量
@player
支持的属性。在
initialize
中,您设置该实例变量。但是,使用
def self.player_name
,您定义了 class 方法,并且该类不知道
player
(只有实例知道)。

要解决此问题,请将类方法转换为实例方法:(删除

self.

class Game
  attr_accessor :player, :computer

  def initialize(player, computer)
    @player = player
    @computer = computer
  end

  def player_name
    puts "#{player.name}"
  end

  def computer_name
    puts "#{computer.name}"
  end
end

并将您的游戏实例分配给一个变量,就像您对

p1
p2
所做的那样,这样您就可以调用这些实例方法:

game = Game.new(p1, p2)
game.player_name    # prints: John
game.computer_name  # prints: Computer

我省略了

@@board
以保持上面的示例较小。一般来说,您应该避免类变量,因为它们的行为不寻常。 (参见为什么在 Ruby 中使用类变量被认为是“代码味道”?

我只是将它分配给另一个实例变量:

class Game
  attr_accessor :player, :computer

  def initialize(player, computer)
    @board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

    # ...
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.