Kit Ho
Kit Ho

Reputation: 26968

Ruby: Why symbols change to strings when using puts instead of print?

I don't understand the behavior of print and puts? I know print would not make a new line but puts can. but why the output of print will change from symbol to string when using puts instead of print?

`$ ruby -e 'print Kernel.private_instance_methods(false)'

[:initialize_copy, :remove_instance_variable, :sprintf, :format, :Integer, :Float, :String, :Array, :warn, :raise, :fail, :global_variables, :__method__, :__callee__, :eval, :local_variables, :iterator?, :block_given?, :catch, :throw, :loop, :caller, :trace_var`

$ ruby -e 'puts Kernel.private_instance_methods(false)'

initialize_copy
remove_instance_variable
sprintf
format
Integer
Float
String
Array
warn
raise
fail
global_variables
__method__
__callee__
eval
local_variables

Upvotes: 0

Views: 873

Answers (2)

xzgyb
xzgyb

Reputation: 452

The print function will call array's to_s function, the array's to_s function is the alias of inspect function.

This can be found in ruby's array.c code.

rb_define_alias(rb_cArray,  "to_s", "inspect");

Therefore:

array = Kernel.private_instance_methods(false)
$stout.write(array.to_s)

will also output the same result.

Upvotes: 0

Michael Kohl
Michael Kohl

Reputation: 66837

When you call puts, what really gets called is the rb_io_puts C function, which basically works like this:

  • If there is no argument, output a newline.
  • For each argument check if it's of type string (T_STRING in Ruby C lingo) and if yes, call rb_io_write with it. Also, if the string was of length zero or didn't finish in a newline, add a \n.
  • If the argument is an array, recursively call io_puts_ary on it.
  • In any other case, call rb_obj_as_string on the argument, which basically is the low-level equivalent of to_s.

So when you puts [:a, :b, :c], you'll hit the third case and io_puts_ary will take over. Long story short this will do something similar as what I described above, and will call rb_obj_as_string on each element and output it followed by a newline.

Upvotes: 3

Related Questions