关于python:Ruby版本的to String方法

Ruby version of to String method

这个问题是关于格式化ruby的字符串。

在Python中,内置数据结构具有内置的to-string方法,因此在打印变量时,可以方便地格式化字符串以反映所使用的数据结构。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>>$ 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]

请注意,当我打印a时,值是[1, 2, 3, 4]

但是,在ruby中,当我尝试执行相同的操作时,会得到以下结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>>$ 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>

如您所见,to_s方法没有格式化。此外,如果我在[1,2,3,4]和[1,23,4]和[1234]上调用to_s,则存在唯一性问题,因为to_s将所有元素都聚集在一起,因此它们最终都是" 1234"。我知道我可以尝试通过覆盖to_s方法(" [" + a.join(",")+"]"#仅用于数组)来为每种本机数据结构模拟python内置的to-string方法,但是我想知道是否还有更好的选择,因为黑客入侵似乎破坏了传统的配置约定概念。

那么,有没有与python内置的to-string方法等效的ruby?


在Ruby中,通常有四种方法可用于获取对象的字符串表示形式。

  • #to_str:这是Ruby的标准类型转换协议的一部分(类似于to_intto_aryto_float,)。当且仅当对象实际上确实是一个字符串但由于任何原因不是String类的实例时,才使用它。这是非常不寻常的。实际上,在整个核心库中,String类本身只有no-op实现。
  • #to_s:这也是Ruby的标准类型转换协议的一部分(类似于to_ito_ato_f,)。如果对象具有某种合理的字符串表示形式,则使用它。实际上,它不一定是字符串。几乎所有对象都应对此做出响应。
  • Kernel#String(obj):这也是Ruby的标准类型转换协议的一部分(类似于Kernel#Integer(obj)Kernel#Array(obj)Kernel#Float(obj),)。与obj.to_s相同。
  • #inspect:应该出于调试目的返回对象的人类可读描述。换句话说:它用于检查对象(duh)。
  • 有三种打印对象的方法:

  • Kernel#print(obj, ...):打印以$,分隔并以$\\终止的所有obj。如果obj不是String,则print将首先调用obj.to_s
  • Kernel#puts(obj, ...):基本上等同于$stdout.puts(obj, ...)。它还打印obj,但是通常用换行符将它们分开。但是,它也有一些特殊情况的行为,特别是它通过在新行上打印每个项目来专门处理数组。
  • Kernel#p(obj, ...):类似于puts,但在所有obj上调用#inspect
  • 除了这些之外,标准库中还有一个pp(精美打印)库,它添加了一个Kernel#pp(obj, ...)方法。

    然后是awesome_print库和hirb


    1
    2
    [1,23,4].inspect #=>"[1, 23, 4]"
    p [1,23,4] # Same as  puts [1,23,4].inspect


    使用检查

    1
    2
    3
    4
    5
    6
    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>