what does print call internally?

M

Martin DeMello

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
 
E

Eric Hodel

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

it calls #to_s.
 
7

7stud --

7stud said:
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.
 
K

Konrad Meyer

--nextPart1742221.jO4t3LgaTi
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Quoth Joel VanderWerf:
=20
Hm. What's going on here then:
=20
$ ruby -e 'p nil.to_s'
""
$ ruby -e 'print nil'
nil
=20
--=20
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 # =3D> foo
irb(main):002:0> nil # =3D> foo
irb(main):003:0> puts nil # =3D> foo
nil

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

=2D-=20
Konrad Meyer <[email protected]> http://konrad.sobertillnoon.com/

--nextPart1742221.jO4t3LgaTi
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQBHDZekCHB0oCiR2cwRAoIiAJ4zDtSb9Vkz1s0O4fASSQ7cDQnyHACgznWs
oVfN+75m30PrtFH2tlbGIHo=
=5nKb
-----END PGP SIGNATURE-----

--nextPart1742221.jO4t3LgaTi--
 
P

Phrogz

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
 
M

Martin DeMello

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
 
E

Eric Hodel

Hm. What's going on here then:

$ ruby -e 'p nil.to_s'
""
$ ruby -e 'print nil'
nil

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

Eric Hodel

class Dog
def to_s
print "dog"
end
end

d = Dog.new

print d
puts

puts d

--output:--
dog#<Dog:0x25634>
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.
 
7

7stud --

Martin said:
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 said:
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?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top