Displaying something is one thing; having the result of a function available in memory for further use, such as transport over a network connection or storage, is something else. In ruby everything is an object, so you should operate on and with objects. This is what ruby was made for.
Edited to address looping multiple times and readability.
My original was decried as unreadable, and then someone came up with a monadic solution using a lambda literal and monkey patching. Even a seasoned programmer will be challenged to follow its logic, and the stack manipulation involved in the interpreter throws scalability out the window anyway. A procedural block in a single loop addresses all of that without being pedantic. "Readable" also implies "understandable."
Freezing the string literals should not be necessary in ruby >= 2.4; they should be automatically frozen, but since the single-loop solution is to address scalability (imagine calling it a million times), one should not overlook this optimization. Also, I have reduced it to a single conditional statement within the block, which means greater scalability.
print 'How many items do you want to see: '.freeze
list = (1..gets.to_i).collect do |i|
div_by_3 = (i % 3).zero?
div_by_5 = (i % 5).zero?
case
when div_by_3 && div_by_5
:foobar
when div_by_3
:foo
when div_by_5
:bar
else
i
end
end
puts list.to_s
Output:
How many items do you want to see: 50
[1, 2, :foo, 4, :bar, :foo, 7, 8, :foo, :bar, 11, :foo, 13, 14, :foobar, 16, 17, :foo, 19, :bar, :foo, 22, 23, :foo, :bar, 26, :foo, 28, 29, :foobar, 31, 32, :foo, 34, :bar, :foo, 37, 38, :foo, :bar, 41, :foo, 43, 44, :foobar, 46, 47, :foo, 49, :bar]