【问题标题】:Understanding attr_reader instance variable accessibility outside it's originating subclass了解 attr_reader 实例变量在其原始子类之外的可访问性
【发布时间】:2017-02-13 14:05:48
【问题描述】:

我正在学习 The Well Grounded Rubyist,但我无法理解如何访问存储在子类 Deck 的实例 var @cards 中的数组。

class PlayingCard
  SUITS = %w{ clubs diamonds hearts spades }
  RANKS = %w{ 2 3 4 5 6 7 8 9 10 J Q K A }
  class Deck
    attr_reader :cards
    def initialize(n=1)
      @cards = []
      SUITS.cycle(n) do |s|
        RANKS.cycle(1) do |r|
          @cards << "#{r} of #{s}"
        end
      end
    end
  end
end

two_decks = PlayingCard::Deck.new(2)
puts two_decks
# => #<PlayingCard::Deck:0x007fb5c2961e80>

这是有道理的,它从 PlayingCard::Deck 返回 two_decks 的对象 id。为了使它更有用,我想出的访问存储在@cards 中的数组的唯一方法是添加另一个方法 Deck#show。现在我可以在@cards 上调用其他方法,就像我开始做的那样。这个简单的例子允许获取@cards的计数:

class PlayingCard
  SUITS = %w{ clubs diamonds hearts spades }
  RANKS = %w{ 2 3 4 5 6 7 8 9 10 J Q K A }
  class Deck
    attr_reader :cards
    def initialize(n=1)
      @cards = []
      SUITS.cycle(n) do |s|
        RANKS.cycle(1) do |r|
          @cards << "#{r} of #{s}"
        end
      end
    end
    def show
      @cards
    end
  end
end

two_decks = PlayingCard::Deck.new(2).show
p two_decks.count
# => 104

我很困惑,因为我认为 attr_reader 允许在课堂外看到 @cards 实例变量。 Cards#show 方法是否增加了变量的范围?我错过了更好的方法吗?我是否应该从@cards 收集操作/信息?谢谢!

【问题讨论】:

  • @cards 是一个实例变量,attr_reader 所做的是允许您访问(读取其值)此实例变量,您已在 show 方法中成功完成。
  • 你还在迷茫吗?你明白安德烈的评论吗?
  • 非常感谢。起初我以为它可以在 PlayingCard 类之外使用。
  • 我是否有更合适的方式来访问@cards 表示的数组?除了在 PlayingCard::Deck.new 实例上创建/调用 show 方法之外?

标签: ruby


【解决方案1】:

这就是我想要的。我认为我的困惑是没有意识到 attr_* 属性可以像方法一样被调用。感谢您的帮助!

class PlayingCard
  SUITS = %w{ clubs diamonds hearts spades }
  RANKS = %w{ 2 3 4 5 6 7 8 9 10 J Q K A }
  class Deck
    attr_reader :cards
    def initialize(n=1)
      @cards = []
      SUITS.cycle(n) do |s|
        RANKS.cycle(1) do |r|
          @cards << "#{r} of #{s}"
        end
      end
    end
  end
end

two_decks = PlayingCard::Deck.new(2)
p two_decks.cards.count

【讨论】:

    【解决方案2】:

    在 Ruby 中,您通常无法更改变量的范围以在其类之外查看它。公开变量的正确方法是将它包装在一个方法中,就像你使用的那样

    def show
      @cards
    end
    

    attr_reader 方法是一种方便的方法,它会自动为您创建方法。因此,添加 attr_reader :cards 会将此方法隐式添加到您的类中:

    def cards
      @cards
    end
    

    这意味着您现在可以使用two_decks.cards 访问@cards,而您根本不需要show 方法。

    值得一提的是,你也可以使用attr_writer :cards来添加这个方法:

    def cards= value
      @cards = value
    end
    

    可以这样调用:two_cards.cards = some_value

    您可以使用attr_accessor :cards 自动添加读取和写入方法。

    【讨论】:

      猜你喜欢
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      相关资源
      最近更新 更多