Ruby OOP 类交互:哪种方式更新实例变量?

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

我有 2 个类:游戏类和玩家类。这是一款井字棋游戏。

class Game
    attr_accessor :player_1, :player_2, :numbers, :board

    def initialize(player_1, player_2)
        @player_1 = player_1
        @player_2 = player_2
        @numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    end
end
class Player

    attr_reader :name
    attr_accessor :selection

    def initialize(name)
        @name = name
        @selection = []
    end

    def play(game)
        print "#{name}, please pick a number: "
        number = gets.chomp.to_i
        print "#{name} selected #{number}"
        puts
        
        selection << number
        index = game.numbers.find_index(number)

        if (name == 'player_1')
            game.numbers[index] = 'X'
        else
            game.numbers[index] = 'O'
        end
    end
end

初始化代码

Player
Game

p1 = Player.new('player_1')
p2 = Player.new('player_2')
game = Game.new(p1, p2)

我设置播放器的方式是,每当玩家选择一个数字(例如:使用

p1.play(game)
)时,该数字将存储在
selection
Player
中,并且
numbers
中的
Game
将更新为“ x”/“o”。

完成上述步骤后,我将

:player_1
中的
:player_2
Game
更新为:

game.player_1 = p1
&
game.player_2 = p2

打印出

game.player_1.selection
,结果就是预期的。然而,我错误地跳过了一次
game.player_1 = p1
game.player_2 = p2
并再次打印了
game.player_1.selection
。令我惊讶的是,无论我执行
game.player_1 = p1
&
game.player_2 = p2
,两种方式的结果都是相同的。

作为 OOP 世界的新手,我想得到澄清;对于我的情况,更新

player_1
/
player_2
的正确方法是什么?谢谢。

ruby oop
1个回答
0
投票

变量用于引用对象。您可以通过

=
将对象分配给变量来设置对象,例如:

a = "hello"

您现在可以通过

"hello"
参考
a
,例如

a << " world"

a #=> "hello world"

由于这种用法,您可能会认为您修改了

a
。但这并不完全正确。您实际上修改了
a
所指的对象,即字符串
"hello"
,然后变成了
"hello world"

当您将一个对象分配给多个变量时,这种区别很重要,例如:

a = "hello"
b = a

a << " world"

a #=> "hello world"
b #=> "hello world"

b = a
将使
b
引用与
a
所引用的同一个对象。我认为它是:

variable  object
   a ───────┐
          "hello"
   b ───────┘

当调用

a << "hello"
时,对象被修改,即:

variable  object
   a ───────┐
          "hello world"
   b ───────┘

事后检查

a
b
仅显示该修改。


对于我的情况,更新

player_1
/
player_2
的正确方法是什么?

你不必这样做。在您的代码中,

p1
game.player_1
已经引用同一个对象,即
Player
的实例。因此,您只需更新该播放器实例即可。

设置

game.player_1 = p1
实际上是多余的,因为
game.player_1
已经引用了
p1
。您只是重新分配了同一个对象。

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