From: ruby-core@...
Date: 2015-06-02T19:38:21+00:00
Subject: [ruby-core:69449] [Ruby trunk - Bug #10845] Subclassing String

Issue #10845 has been updated by Marc-Andre Lafortune.

Assignee set to Yukihiro Matsumoto

It's clear to me that there's no rationale behind the current behavior.

The question is broader than that.

First, it's not only for `String`:

    class MyArray < Array; end
    x = MyArray.new([1,2,3])
    x.first(2).class == x[0..1].class # => false
    (x+x).class == (x * 2).class # => false

etc...

Also troubling is the fact that no constructor is called at all... Take this somewhat absurd example where `@other` is normally guaranteed to be a Hash (and `to_s` assumes that):

    class MyArray < Array
      def initialize(size = 0, default = nil, **other)
        @other = other
        super(size, default)
      end

       def initialize_clone(x)
        raise "This is never called"
      end

      def initialize_dup(x)
        raise "This is never called"
      end

      def initialize_copy(x)
        raise "This is never called"
      end

     def to_s
        super + @other.keys.to_s
      end
    end

    MyArray.new(2, :foo, bar: 42).*(2).to_s
    # => undefined method `keys' for nil:NilClass (NoMethodError)

The newly created `MyArray` has no `@other` because no constructor is called.


----------------------------------------
Bug #10845: Subclassing String
https://bugs.ruby-lang.org/issues/10845#change-52720

* Author: Tsuyoshi Sawada
* Status: Open
* Priority: Normal
* Assignee: Yukihiro Matsumoto
* ruby -v: 2.2
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
If I make a subclass of `String`, the method `*` returns an instance of that class.

~~~ruby
class MyString < String
end

MyString.new("foo").*(2).class #=> MyString
~~~

This is different from other similar operations like `+` and `%`, which return a `String` instance.

~~~ruby
MyString.new("foo").+("bar").class #=> String
MyString.new("%{foo}").+(foo: "bar").class #=> String
~~~

I don't see clear reason why `*` is to be different from `+` and `%`, and thought that perhaps either the behaviour with `*` is a bug, or the behaviour with `+` and `%` is a bug.

Or, is a reason why they are different?



-- 
https://bugs.ruby-lang.org/