Reputation: 23
I am new to ruby and I can't understand why I after running this code I get an extra empty line as a result as a part of the output. I am using Ruby 2.5.3
class Card
attr_accessor :rank, :suit
def initialize(rank,suit)
@rank = rank
@suit = suit
end
def output_card
puts "#{self.rank} of #{self.suit}"
end
def self.random_card
suit = ["hearts", "spades", "clubs", "diamonds"]
Card.new(rand(1..13), suit.sample)
end
end
class Deck
def initialize
d = 0
@cards =[]
while d < 13
@cards << Card.random_card
d += 1
end
end
def shuffle
@cards.shuffle!
end
def output
@cards.each do |card|
card.output_card
end
end
def deal
self.shuffle
dealing = @cards.shift
puts "#{dealing.output_card}"
end
end
deck = Deck.new
deck.deal
The above will give me this result:
[ENV]:/vagrant/OOP $ ruby card.rb
6 of clubs
[ENV]:/vagrant/OOP $
As you can see there is an extra line, and I don't understand why.
Upvotes: 0
Views: 39
Reputation: 10054
From the docs of puts
:
Writes a newline after any that do not already end with a newline sequence.
In Deck.deal
you have puts "#{dealing.output_card}"
. Card#output_card
is defined as:
def output_card
puts "#{self.rank} of #{self.suit}"
end
I.e., Card#output_card
is already printing with a new line at the end. The return value of this method, which is the return value of puts
, which in turn per the docs is nil
, is then printed in Deck.deal
, resulting in an empty line being printed.
In short, you're printing twice, where the second puts
results in the additional line.
I suggest you remove puts
from Card
as it should not have a notion of printing itself. That's the job of Deck
. I would change Card#output_card
to be Card#to_s
and just return the string you're constructing rather than puts
ing it. Then you can rely on the fact that puts
will call #to_s
on the object being printed.
class Card
# ...
def to_s
"#{self.rank} of #{self.suit}"
end
# ...
end
class Deck
# ...
def output
@cards.each do |card|
puts card
end
end
def deal
self.shuffle
puts @cards.shift
end
end
Upvotes: 0