The stated reason is that [] isn't an object
Stated where?
puts
has a special handling for arrays. When you pass it an array, it prints each element on a new line. You pass it an array with zero elements, it prints zero lines.
Frage
I'm going through a Ruby tutorial, and learned that the code
puts 'start'
puts
puts 'end'
will output three lines, but the following code
puts 'start'
puts []
puts 'end'
will only output two. The stated reason is that [] isn't an object (edit: "doesn't point to anything"), so puts
can't do anything with it, but why is that not also true in the first case?
I tried to find an official page about puts
to figure this out, and this one was no help.
Lösung
The stated reason is that [] isn't an object
Stated where?
puts
has a special handling for arrays. When you pass it an array, it prints each element on a new line. You pass it an array with zero elements, it prints zero lines.
Andere Tipps
puts
with an array will print one line per element. No element, no lines.
EDIT: What I just said is documented in your link:
If called with an array argument, writes each element on a new line.
The link your shared, states:
If called with an array argument, writes each element on a new line.
puts []
means, you are calling puts
with empty array. i.e. no elements to print. and that's what happened.
puts arr
is like
arr.each { |e| puts e }
You can do something like this by yourself:
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 with no arguments has special behaviour - i.e. print new line. In all other cases, it treats all arguments as an array, and maps these arguments to strings using #to_s, and outputs each string on a new line. That's why you get no output when calling puts []
. If you want to have a new line in the output, you can either call puts
with no arguments (it's obvjous), or use splat operator with empty array, like this: puts *[]
.
You can write your own implementation of puts
in order to understand things better.
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]