为什么我会得到一个额外的尾随 space 以及如何摆脱它?

Why do I get an extra trailing space and how to get rid of it?

我是 ruby 的新手,我不明白为什么在 运行 这段代码之后我得到一个额外的空行作为输出的一部分。我正在使用 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 $

如您所见,多了一行,我不明白为什么。

来自 puts 的文档:

Writes a newline after any that do not already end with a newline sequence.

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

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

即,Card#output_card 已经在末尾换行打印。此方法的 return 值,即 puts 的 return 值,根据文档又是 nil,然后打印在 Deck.deal 中,导致打印空行。

简而言之,您打印了两次,其中第二次 puts 产生了附加行。

我建议您从 Card 中删除 puts,因为它不应该有打印本身的概念。那是 Deck 的工作。我会将 Card#output_card 更改为 Card#to_s 并且只是 return 您正在构造的字符串而不是 putsing 它。然后你可以相信 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