在从String继承的Ruby类中,如何使用explicit.to_s获取“{my_String}”

在从String继承的Ruby类中,如何使用explicit.to_s获取“{my_String}”,ruby,Ruby,简而言之,我希望这个测试程序的最后一行中的所有三个{}都会产生相同的字符串,但它们不会。如果我的类从对象继承,它就可以工作 > ./test.rb A string foobar, and MyString: , MyString.to_s: foobar > cat test.rb #!/usr/bin/env ruby class MyString < String def initialize s @s= s.to_s

简而言之,我希望这个测试程序的最后一行中的所有三个{}都会产生相同的字符串,但它们不会。如果我的类从对象继承,它就可以工作

> ./test.rb 
A string foobar, and MyString: , MyString.to_s: foobar

> cat test.rb 

    #!/usr/bin/env ruby

    class MyString < String
      def initialize s
        @s= s.to_s
        @simple = s.index(?+)
      end
      def to_s() @s end
    end

x='foobar'

puts "A string #{x}, and MyString: #{
        MyString.new(x)}, MyString.to_s: #{MyString.new(x).to_s}"

字符串插值似乎以不同的方式处理字符串类型的对象:

irb(main):011:0> class MyString < String
irb(main):012:1>   def initialize(str)
irb(main):013:2>     @str = str
irb(main):014:2>   end
irb(main):015:1>   def to_s
irb(main):016:2>     puts "to_s called!"
irb(main):017:2>     @str
irb(main):018:2>   end
irb(main):019:1> end
=> nil
irb(main):020:0> "#{MyString.new('foo')}"
=> ""
如你所见,to_s甚至不被称为。原因是str.to_s==str不变,其中str.is_a?一串您破坏了该不变量,从而混淆了库代码


结论:如果要对字符串进行子类化,请不要覆盖到\u s。无论如何,这没有多大意义。

字符串插值处理字符串类型对象的方式似乎有所不同:

irb(main):011:0> class MyString < String
irb(main):012:1>   def initialize(str)
irb(main):013:2>     @str = str
irb(main):014:2>   end
irb(main):015:1>   def to_s
irb(main):016:2>     puts "to_s called!"
irb(main):017:2>     @str
irb(main):018:2>   end
irb(main):019:1> end
=> nil
irb(main):020:0> "#{MyString.new('foo')}"
=> ""
如你所见,to_s甚至不被称为。原因是str.to_s==str不变,其中str.is_a?一串您破坏了该不变量,从而混淆了库代码

结论:如果要对字符串进行子类化,请不要覆盖到。无论如何,这没有多大意义。

因为,字符串插值不会对字符串对象调用。参数的默认值为,因此子类的实例实际上都是空字符串

实现此功能的一种方法是在子类中调用initialize方法中的super,并传递字符串值:

class MyString < String
  def initialize s
    super s.to_s    # this line added
    @s= s.to_s
    @simple = s.index(?+)
  end
  def to_s() @s end
end

puts "#{MyString.new("foo")}"  # => produces "foo"
同样,字符串插值不会调用字符串对象上的_。参数的默认值为,因此子类的实例实际上都是空字符串

实现此功能的一种方法是在子类中调用initialize方法中的super,并传递字符串值:

class MyString < String
  def initialize s
    super s.to_s    # this line added
    @s= s.to_s
    @simple = s.index(?+)
  end
  def to_s() @s end
end

puts "#{MyString.new("foo")}"  # => produces "foo"

谢谢,这很有道理。我差点就想明白了。我认为“自我”并没有真正得到价值,这就是为什么。谢谢,这是有道理的。我差点就想明白了。我认为“自我”并没有真正得到价值,这就是为什么。这个问题有点复杂。新方法也需要一些调整。多亏了那些回答的人。问题有点复杂。新方法也需要一些调整。感谢回答的人。我确实遇到过需要字符串对象而不是MyString对象的情况。我是在一个地方以{self}的身份那样做的。但现在我认为这只是self.to_,语法上更简单。我确实遇到过需要String对象而不是MyString对象的情况。我是在一个地方以{self}的身份那样做的。但现在我认为这只是self.to_,语法上更简单。