I’m working through a few exercises to teach myself Ruby. One of them
is the creation of a deck of cards along with all the usual
operations one performs upon them.
I override the Object#inspect method to pretty-print my card values,
but it doesn’t always get called. Whether or not it gets called
depends on the absence of a line in #print_playing_deck. Here is
my code stripped down to the basics.
class Card < Object
attr_reader :suit, :value
protected
attr_writer :suit, :value
public
def initialize(suit = “Joker”, value = 15)
@suit = suit
@value = value
end
def inspect
puts “#{self.value} of #{self.suit}s”
end
end
class CardDeck < Card
attr_reader :size
SUITSIZE = 13
def initialize(size = 52)
@size = size
@playing_deck = Array.new(@size) do |index|
case index
when *(0..12)
Card.new("Heart", index + 1)
end
end
@number_remaining = @playing_deck.length
end
def print_playing_deck
@playing_deck.each do |card|
puts card
end
# WEIRD!! If I have any code after this loop, my Card#inspect is
not called.
# In this case I have a “puts” but it could even be arithmetic
expressions preventing
# the #inspect from working
#puts “#{@playing_deck.length} cards in deck”
end
end
And here is the output:
irb(main):001:0> load ‘ex.rb’
=> true
irb(main):002:0> d=CardDeck.new(5)
of s
=>
irb(main):003:0> d.print_playing_deck
#Card:0x65b4
#Card:0x63e8
#Card:0x62a8
#Card:0x61cc
#Card:0x6168
5 cards in deck
=> nil
######## comment out the “puts” in #print_playing_deck and reload
irb(main):004:0> load ‘ex.rb’
./ex.rb:22: warning: already initialized constant SUITSIZE
=> true
irb(main):005:0> d.print_playing_deck
#Card:0x65b4
#Card:0x63e8
#Card:0x62a8
#Card:0x61cc
#Card:0x6168
1 of Hearts
2 of Hearts
3 of Hearts
4 of Hearts
5 of Hearts
=> [, , , , ]
I don’t understand why my Card#inspect method doesn’t print anything
to stdout when there is code after the loop. Is this just a weird
artifact of irb?
BTW, running on OSX with darwinports Ruby 1.8.4.