Is # {} always equivalent to_s?

In “ What does it mean to use the class name to interpolate strings? ” Candide suggested that #{}inside the string implicitly calls to_s, So, for example:

my_array = [1, 2, 3, 4]
p my_array.to_s # => "[1, 2, 3, 4]"
p "#{my_array}" # => "[1, 2, 3, 4]"

However, if to_sArray is overridden as shown below, I get different results:

class Array
  def to_s
    self.map { |elem| elem.to_s }
  end
end

p my_array.to_s # => ["1", "2", "3", "4"]
p "#{my_array}" # => "#<Array:0x007f74924c2bc0>"

I suppose this happens anytime and is to_soverridden anyway .

What should I do to keep the equality between to_sand the expression #{}in the string, if possible?

I ran into this problem in the RubyMonk Lesson : what, according to lesson # {ogres}, should return, in my experience something else.

+4
3

, Object#to_s. , to_s a String. , . Array#to_s , String. [ , to_X to_XYZ: raise a Exception .]

to_s String. Array, to_s. , . , raise a TypeError, Ruby String, ( ) .

RubySpec, () , no Exception is raise d , String: , Object#to_s String, Object#inspect.

language/string_spec.rb#L197-L208:

it "uses an internal representation when #to_s doesn't return a String" do
  obj = mock('to_s')
  obj.stub!(:to_s).and_return(42)

  # See rubyspec commit 787c132d by yugui. There is value in
  # ensuring that this behavior works. So rather than removing
  # this spec completely, the only thing that can be asserted
  # is that if you interpolate an object that fails to return
  # a String, you will still get a String and not raise an
  # exception.
  "#{obj}".should be_an_instance_of(String)
end

, , , , Exception, String, , String .

+4

, Ruby:

"#{my_array}" # => "#<Array:0x007f74924c2bc0>"

, Ruby , to_s, , Ruby, , Array.to_s.

- :

'[%s]' % self.map { |elem| elem.to_s }.join(', ')

, , .

:

[].class # => Array
[].to_s.class # => String

class Array
  def to_s
    self.map { |elem| elem.to_s }
  end
end

[].to_s.class # => Array

class Array
  def to_s
    '[%s]' % self.map { |elem| elem.to_s }.join(', ')
  end
end

[].to_s.class # => String

my_array = [1, 2, 3, 4]
"#{my_array}" # => "[1, 2, 3, 4]"

STD-Lib 'to_s, , . to_s, , . , , inspect.

+2

Array#to_s , to_s . . , Ruby , ​​ "#{my_array}". p my_array.to_s, my_array.to_s - , p Array#inspect, .

+1

Source: https://habr.com/ru/post/1607839/


All Articles