为什么我会有一个多余的尾随空间,以及如何摆脱它?

时间:2019-04-21 20:44:17

标签: ruby oop class-level

我是红宝石的新手,我不明白为什么我在运行这段代码后会在输出中得到额外的空行。我正在使用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

上面将给我这个结果:

[ENV]:/vagrant/OOP $ ruby card.rb
6 of clubs

[ENV]:/vagrant/OOP $

如您所见,还有多余的一行,我不明白为什么。

1 个答案:

答案 0 :(得分:0)

摘自puts的文档:

  

在所有未以换行符结尾的行之后写入换行符。

Deck.deal中,您有puts "#{dealing.output_card}"Card#output_card定义为:

def output_card
  puts "#{self.rank} of #{self.suit}"
end

也就是说,Card#output_card已经在打印,并在最后一行添加了新行。然后,此方法的返回值(即puts的返回值,依次是每个文档是nil,然后在Deck.deal中打印,导致打印出空行。

简而言之,您要打印两次,第二个puts会导致额外的一行。

我建议您从puts中删除Card,因为它不应该具有打印本身的概念。这就是Deck的工作。我将Card#output_card更改为Card#to_s,只返回您正在构造的字符串,而不是puts对其进行编码。然后,您可以依靠puts将在要打印的对象上调用#to_s的事实。

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