2

我正在阅读Ruby 教程,并了解到代码

puts 'start'
puts
puts 'end'

将输出三行,但下面的代码

puts 'start'
puts []
puts 'end'

只会输出两个。所述的原因是 []不是一个对象(编辑:“不指向任何东西”),所以puts不能用它做任何事情,但为什么在第一种情况下也不是这样?

我试图找到一个官方页面puts来解决这个问题,这个没有帮助。

4

5 回答 5

8

陈述的原因是 [] 不是对象

哪里说的?

puts对数组有特殊处理。当您将数组传递给它时,它会在新行上打印每个元素。您将一个包含零元素的数组传递给它,它会打印零行。

于 2012-12-11T06:36:05.623 回答
2

puts使用数组将每个元素打印一行。没有元素,没有线条。

编辑:我刚才所说的记录在您的链接中:

如果使用数组参数调用,则将每个元素写入新行。

于 2012-12-11T06:35:30.420 回答
2
puts arr

就好像

arr.each { |e| puts e }

你可以自己做这样的事情:

def p(s)
  if s.respond_to? 'each'
    s.each { |e| p e }
  else
    puts s
  end
end

p 'hello' # prints line with 'hello'
p [] # prints nothing
p [1, 2] # prints 2 lines with 1 and 2
于 2012-12-11T06:37:27.233 回答
2

您共享的链接指出:

如果使用数组参数调用,则将每个元素写入新行。

puts []

意味着,您正在puts使用空数组调用。即没有要打印的元素。这就是发生的事情。

于 2012-12-11T06:38:27.337 回答
2

不带参数的 Put 具有特殊行为 - 即打印新行。在所有其他情况下,它将所有参数视为一个数组,并使用 #to_s 将这些参数映射到字符串,并在新行上输出每个字符串。这就是为什么调用时没有输出的原因puts []。如果你想在输出中有一个新行,你可以不puts带参数调用(它是 obvjous),或者使用带有空数组的 splat 运算符,如下所示puts *[]

您可以编写自己的实现puts以更好地理解事物。

  def my_puts(*args)
    STDOUT.write("args is #{args.inspect}\n")
    if args.empty?
      STDOUT.write("\n")
    else
      args.each { |arg| STDOUT.write("#{arg.to_s}\n") }
    end
  end


1.9.3p194 :039 > my_puts
args is []

 => 1 
1.9.3p194 :040 > my_puts []
args is [[]]
[]
 => [[]] 
1.9.3p194 :041 > my_puts *[]
args is []

 => 1 
1.9.3p194 :042 > my_puts 1,2,3
args is [1, 2, 3]
1
2
3
 => [1, 2, 3] 
1.9.3p194 :043 > my_puts [1,2,3]
args is [[1, 2, 3]]
[1, 2, 3]
 => [[1, 2, 3]] 
1.9.3p194 :044 > my_puts *[1,2,3]
args is [1, 2, 3]
1
2
3
 => [1, 2, 3] 
于 2012-12-11T07:32:13.683 回答