Cameron
Cameron

Reputation: 135

Best practices for accessing ruby instance variables

David Black’s “Well-Grounded Rubyist” provided an example to illustrate the use of the cycle method:

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

deck = PlayingCard::Deck.new

I wanted to access the instance variable @cards defined inside a sub-class. What is the best method to access this array?

My understanding is that I would have to add an instance method in Deck. Is there a better technique?

What would be the best way to assign hands of cards?

Upvotes: 0

Views: 546

Answers (1)

AmitA
AmitA

Reputation: 3245

You can already access it now, because your script calls attr_reader :cards:

my_deck = PlayingCard::Deck.new(10)
my_deck.cards

attr_reader is a "class macro" (as Paolo Perrotta referred to this pattern in his "Metaprogramming Ruby" book) that simply defines a getter to an ivar with the same name:

# this line...
attr_reader :cards

# ... is equivalent to 
def cards
  @cards
end

Now, if you really wanted, you could pierce the object's veil and access directly its instance variables with instance_variable_get:

my_deck.instance_variable_get(:@cards)

But try to avoid this if possible to keep your objects well encapsulated.

Upvotes: 3

Related Questions