【问题标题】:How to refer to an object's "Owner" in Ruby?如何在 Ruby 中引用对象的“所有者”?
【发布时间】:2017-09-17 22:03:26
【问题描述】:

“所有者”可能不是正确的术语,但我不知道它是什么,所以它使搜索变得非常困难。

我在做一个纸牌游戏,每个玩家可以多手牌。

我有一个“Player”、“Hand”和“Card”类。

player1 = Player.new 
hand1 = Hand.new # => A new hand of two random cards

player1.hands.push(hand1)

#Now player1 has one hand with two cards in it.

我可以在 hand1 上调用一个属性或方法来引用它的“所有者”player1?

我期待类似的东西

hand1.owner

=> #<Player:0x007fb6ae05b448
# @behavior=:human,
# @hands=[#<Hand:0x007fb6ad8653b0 @cards=[{:A,:spades},{:Q,:hearts}]>],
# @money=800,
# @name="Dougie Jones">

【问题讨论】:

  • 我知道这可能只是一个例子,但是如果您需要查询手牌来确定他们的玩家,我会说您建模错误。
  • 我将不得不同意@MarkThomas 关于这一点。为什么Hand 需要知道它的Player?假设我们正在玩“Go Fish”……你会在他们的Hand 中询问Player 关于Card 而不是询问Hand 关于PlayerHand 应该只知道Cards,Player 应该知道Hand,通过Hand 知道Cards
  • 这是一个二十一点游戏,有时您需要将一手牌分成两只手,最多四手。我发现让每只手“玩”自己并让所有玩家和 AI 决策都在 Hand 类中进行更容易。直到我意识到加倍和分裂需要这手牌知道它的玩家是否有足够的钱,我才遇到麻烦。我现在可能会改变它的结构,特别是因为无论如何我在 Player 类中仍然有很多游戏方法......

标签: ruby object inheritance attributes hierarchy


【解决方案1】:

不,没有办法。一个对象不知道你把它放在哪里。您可以将它保存在许多不同的地方,那么谁将成为所有者?您需要手动设置关系或考虑更改设计。

考虑一下:

class Player
  attr_accessor :hands

  def initialize
    @hands = []
  end

  def add_hand(hand)
    hand.player = self
    @hands << hand
  end
end

class Hand
  attr_accessor :player
end

player = Player.new
hand = Hand.new
player.add_hand(hand)
puts hand.player #=> #<Player:0x000000017b2978>

【讨论】:

  • 是的!谢谢!将 .player 属性添加到 Player 类的 new_hand 方法比我找到的解决方法简单得多,即将玩家的唯一标识符作为附加参数传递给 new_hand 方法,然后将其转换为 Hand 中的属性类的初始化器。谢谢!
【解决方案2】:

您可以交叉引用具有属性的对象。 (每个Hand 对象都可以引用特定的Player 对象)

例如,您可以向Hand 模型添加属性:

class Hand
  attr_accessor :player
end

然后当你创建一个新的Hand,你可以设置player

player1 = Player.new
hand1 = Hand.new
hand1.player = player1

这基本上就是ActiveRecord associations 的工作方式。

【讨论】:

  • 一年后,我正在查看我的帖子历史记录并查看您的评论。伙计,那时我完全没有准备好听到有关 ActiveRecord 的东西。我现在肯定会以不同的方式处理这个问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
相关资源
最近更新 更多