Reputation: 63
This question is about formatting ruby's strings.
In Python, built-in data structures have a built-in to-string method, and so when a variable is printed, the string is conveniently formatted to be reflective of the data structure used. For example:
>>>$ python
Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
$>>> a = [1,2,3,4]
$>>> str(a)
'[1, 2, 3, 4]'
$>>> print a
[1, 2, 3, 4]
$>>> d = { "a":"a", "b":"b", 1:5 }
$>>> str(d)
"{'a': 'a', 1: 5, 'b': 'b'}"
$>>> print d
{'a': 'a', 1: 5, 'b': 'b'}
$>>> x = [1, 23, 4]
$>>> print x
[1, 23, 4]
notice that when i print a, the value is [1, 2, 3, 4]
However, in ruby, when i try to do the same things, i get this result:
>>>$ irb
irb(main):001:0> x = [1,23,4]
=> [1, 23, 4]
irb(main):002:0> x.to_s
=> "1234"
irb(main):003:0> puts x
1
23
4
=> nil
irb(main):004:0> print x
1234=> nil
irb(main):005:0> h = { "a" => "a", 1 => 5, 'b'=>'b' }
=> {"a"=>"a", "b"=>"b", 1=>5}
irb(main):006:0> print h
aabb15=> nil
irb(main):007:0> h.to_s
=> "aabb15"
irb(main):008:0> puts h
aabb15
=> nil
irb(main):009:0>
As you can see, there is no formatting with the to_s method. Furthermore, there's a uniqueness problem if i call to_s on [1,2,3,4] and [1,23,4] and [1234] because the to_s clumps all elements together so they all end up being "1234". I know that i can try to emulate the python built-in to-string methods for every native data structure by overriding the to_s method ( "[" + a.join(",") + "]" #just for arrays), but i was wondering if there is a better alternative since hacking it would seem to break the convention-over-configuration concept.
So is there a ruby equivalent of python's built-in to-string method?
Upvotes: 5
Views: 6834
Reputation: 369536
In Ruby, there are four methods that are typically available for getting a string representation of an object.
#to_str
: this is part of Ruby's standard type conversion protocols (similar to to_int
, to_ary
, to_float
, …). It is used if and only if the object really actually is a string but for whatever reason is not an instance of the String
class. It is extremely unusual. In fact, in the entire core library, there is only the no-op implementation in the String
class itself.#to_s
: this is also part of Ruby's standard type conversion protocols (similar to to_i
, to_a
, to_f
, …). It is used if the object has some sort of sensible string representation. It does not actually need to be a string. Almost all objects should respond to this.Kernel#String(obj)
: this is also part of Ruby's standard type conversion protocols (similar to Kernel#Integer(obj)
, Kernel#Array(obj)
, Kernel#Float(obj)
, …). It is the same as obj.to_s
.#inspect
: it is supposed to return a human-readable description of the object for debugging purposes. In other words: it is for inspecting an object (duh).There are three methods for printing objects:
Kernel#print(obj, ...)
: prints all obj
s separated by $,
and terminated by $\
. If an obj
is not a String
, print
will call obj.to_s
first.Kernel#puts(obj, ...)
: is basically equivalent to $stdout.puts(obj, ...)
. It also prints the obj
s, but it typically separates them with newlines. However, it also has some special case behavior, in particular it treats arrays specially by printing each item on a new line.Kernel#p(obj, ...)
: similar to puts
but calls #inspect
on all obj
s.In addition to those, there is also the pp
(pretty print) library in the standard library which adds a Kernel#pp(obj, ...)
method.
Then, there's the awesome_print
library and hirb
.
Upvotes: 9
Reputation: 49114
Use inspect
irb(main):001:0> h = { "a" => "a", 1 => 5, 'b'=>'b' }
=> {"a"=>"a", "b"=>"b", 1=>5}
irb(main):003:0> puts h.inspect
{"a"=>"a", "b"=>"b", 1=>5}
=> nil
irb(main):004:0>
Upvotes: 0
Reputation: 370357
[1,23,4].inspect #=> "[1, 23, 4]"
p [1,23,4] # Same as puts [1,23,4].inspect
Upvotes: 9