[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Nuby - why does my #inspect misbehave?

Chuck Remes

3/3/2006 1:31:00 AM

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.


5 Answers

Logan Capaldo

3/3/2006 1:46:00 AM

0


On Mar 2, 2006, at 8:30 PM, cremes.devlist@mac.com wrote:

> 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.
>

As a general rule #inspect is not supposed to print anything it is
supposed to return a string. Likewise in this case I believe your
inspect method is better named "to_s" since it gets you a string
representation of the object, not a peek into the objects internal
state. I don't know what the cause of your bug is though. Irb will
usually print the inspect string of an evaluated expression on its
own though, and puts returns nil. So when irb does the equivalent of
p a_card its going to get back nil which is gonna be converted to the
empty string. This may be part of your problem, but first I would
suggest changing your code to match the usual ruby conventions and
secondly try running the code outside of irb.




dblack

3/3/2006 2:07:00 AM

0

dblack

3/3/2006 2:42:00 AM

0

nope

3/3/2006 2:46:00 AM

0

unknown wrote:
> Hi --
>
> On Fri, 3 Mar 2006, James Britt wrote:
>
>>
>> :(
>
> ?

O-('_' Q)



--
Posted via http://www.ruby-....


james_b

3/3/2006 4:14:00 AM

0

dblack@wobblini.net wrote:
> Hi --
>
> On Fri, 3 Mar 2006, James Britt wrote:
>
>> dblack@wobblini.net wrote:
>>
>>>
>>> One of the great rites of passage for new Rubyists is learning that:
>>>
>>> puts array
>>>
>>> does the iterating for you :-)
>>
>>
>>
>>
>> :(
>
>
> ?


POGSFJ

(I'll refrain from invoking P*LS)



James