我正在阅读Ruby 教程,并了解到代码
puts 'start'
puts
puts 'end'
将输出三行,但下面的代码
puts 'start'
puts []
puts 'end'
只会输出两个。所述的原因是 []不是一个对象(编辑:“不指向任何东西”),所以puts
不能用它做任何事情,但为什么在第一种情况下也不是这样?
我试图找到一个官方页面puts
来解决这个问题,这个没有帮助。
陈述的原因是 [] 不是对象
哪里说的?
puts
对数组有特殊处理。当您将数组传递给它时,它会在新行上打印每个元素。您将一个包含零元素的数组传递给它,它会打印零行。
puts
使用数组将每个元素打印一行。没有元素,没有线条。
编辑:我刚才所说的记录在您的链接中:
如果使用数组参数调用,则将每个元素写入新行。
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
您共享的链接指出:
如果使用数组参数调用,则将每个元素写入新行。
puts []
意味着,您正在puts
使用空数组调用。即没有要打印的元素。这就是发生的事情。
不带参数的 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]