What does print call internally?

irb(main):001:0> puts nil
nil
=> nil
irb(main):002:0> print nil
nil=> nil
irb(main):003:0> class NilClass
irb(main):004:1> def inspect
irb(main):005:2> “foo”
irb(main):006:2> end
irb(main):007:1> end
=> foo
irb(main):008:0> puts nil
nil
=> foo
irb(main):009:0> nil.to_s
=> “”
irb(main):010:0> $_
=> foo

$ ruby -v
ruby 1.8.5 (2006-12-25 patchlevel 12) [x86_64-linux]

martin

On Oct 10, 2007, at 15:31 , Martin DeMello wrote:

=> foo
it calls #to_s.

Eric H. wrote:

irb(main):006:2> end
irb(main):007:1> end
=> foo

it calls #to_s.

Hm. What’s going on here then:

$ ruby -e ‘p nil.to_s’
“”
$ ruby -e ‘print nil’
nil

7stud – wrote:

class Dog
def to_s
print “dog”
end
end

d = Dog.new

print d
puts

puts d

–output:–
dog#Dog:0x25634
dog#Dog:0x25634

I guess that should be:

class Dog
def to_s
“dog”
end
end

d = Dog.new

print d
puts

puts d

–output:–
dog
dog

I don’t understand the output of my first example: print returns nil, so
print ‘dog’ should return nil, which means to_s returns nil, and so
print d should be equivalent to print nil.

Quoth Joel VanderWerf:

irb(main):005:2> “foo”
$ ruby -e ‘print nil’
nil


vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Irb calls NilClass#inspect, as the OP demonstrated.

irb(main):001:0> class NilClass; def inspect() “foo” end; end # => foo
irb(main):002:0> nil # => foo
irb(main):003:0> puts nil # => foo
nil

I’m guessing puts/print treat nil as a special case, but I may be wrong.

Eric H. wrote:

On Oct 10, 2007, at 15:31 , Martin DeMello wrote:

=> foo
it calls #to_s.

class Dog
def to_s
print “dog”
end
end

d = Dog.new

print d
puts

puts d

–output:–
dog#Dog:0x25634
dog#Dog:0x25634

On Oct 10, 9:25 pm, 7stud – [email protected] wrote:

I don’t understand the output of my first example: print returns nil, so
print ‘dog’ should return nil, which means to_s returns nil, and so
print d should be equivalent to print nil.

If to_s returns something other than a string, Ruby shakes a naughty
finger at you and ignores you, and falls back on the result of
Kernel#inspect instead.

irb(main):001:0> class Foo; def to_s; 42; end; end
=> nil
irb(main):002:0> puts Foo.new
#Foo:0x359224
=> nil
irb(main):003:0> class Foo; def to_s; “42”; end; end
=> nil
irb(main):004:0> puts Foo.new
42

On 10/10/07, Konrad M. [email protected] wrote:

I’m guessing puts/print treat nil as a special case, but I may be wrong.

That’s quite counterintuitive, though. If true, the question becomes
“why?” - I can’t see any useful purpose it’d serve, save maybe
debugging.

martin

On 10/10/07, Eric H. [email protected] wrote:

irb(main):006:2> end
irb(main):007:1> end
=> foo

it calls #to_s.

How does print nil print “nil” then?

martin

On Oct 10, 2007, at 19:58 , 7stud – wrote:

end
dog#Dog:0x25634
In IO#write, if #to_s returns nil, rb_any_to_s() gets called, which
returns “#<#{self.class}:0x#{object_id.to_s 16}>”, which gets printed
instead of your broken #to_s.

On Oct 10, 2007, at 19:52 , Joel VanderWerf wrote:

irb(main):006:2> end
irb(main):007:1> end
=> foo
it calls #to_s.

Hm. What’s going on here then:

$ ruby -e ‘p nil.to_s’
“”
$ ruby -e ‘print nil’
nil

     switch (TYPE(argv[i])) {
       case T_NIL:
         rb_io_write(out, rb_str_new2("nil"));
         break;
       default:
         rb_io_write(out, argv[i]);
         break;
     }

Martin DeMello wrote:

On 10/10/07, Konrad M. [email protected] wrote:

I’m guessing puts/print treat nil as a special case, but I may be wrong.

That’s quite counterintuitive, though. If true, the question becomes
“why?” - I can’t see any useful purpose it’d serve, save maybe
debugging.

martin

pickaxe2, p. 131:

"With a couple of exceptions, every object you pass to puts and print is
converted to a string by calling that object’s to_s method. If for some
reason the to_s method doesn’t return a valid string, a string is
created containing the object’s class name and ID…

The exceptions are simple, too. The nil object will print as the string
‘nil’, and an array passed to puts will be written as if each of its
elements in turn were passed separately to puts."

Eric H. wrote:

On Oct 10, 2007, at 19:58 , 7stud – wrote:

end
dog#Dog:0x25634
In IO#write, if #to_s returns nil, rb_any_to_s() gets called, which
returns “#<#{self.class}:0x#{object_id.to_s 16}>”, which gets printed
instead of your broken #to_s.

How do you get from puts/print to IO.write?

Hi,

On Thu, 2007-10-11 at 15:26 +0900, Martin DeMello wrote:

That’s quite counterintuitive, though. If true, the question becomes
“why?” - I can’t see any useful purpose it’d serve, save maybe
debugging.

Debugging is right. Otherwise, you print nothing (or “” – who knows?).
It’s probably better to see ‘nil’ and have to toss up between print nil
and print “nil” (or print [“nil”], or whatever!), rather than never
seeing a thing and constantly guessing if you’re perhaps seeing print
nil, “”, [""], etc…

  • Arlen

On Oct 11, 2007, at 05:03 , 7stud – wrote:

Eric H. wrote:

On Oct 10, 2007, at 19:58 , 7stud – wrote:

end
dog#Dog:0x25634
In IO#write, if #to_s returns nil, rb_any_to_s() gets called, which
returns “#<#{self.class}:0x#{object_id.to_s 16}>”, which gets printed
instead of your broken #to_s.

How do you get from puts/print to IO.write?

Follow the calls in rb_f_print() (Kernel#print).