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.
문제
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.
해결책
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.
다른 팁
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]