了解它之外的attr_reader实例变量可访问性的原始子类

时间:2017-02-13 14:05:49

标签: ruby

我正在学习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实例var。 Cards#show方法是否增加了变量的范围?有没有更好的方法让我失踪?关于@cards的操作/信息收集应该在哪里发生?谢谢!

2 个答案:

答案 0 :(得分:0)

在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自动添加读取和写入方法。

答案 1 :(得分:0)

这就是我想要的。我认为我的困惑并没有意识到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