From: "matz (Yukihiro Matsumoto)" <matz@...> Date: 2012-07-14T16:44:52+09:00 Subject: [ruby-core:46434] [ruby-trunk - Bug #6087] How should inherited methods deal with return values of their own subclass? Issue #6087 has been updated by matz (Yukihiro Matsumoto). Target version changed from 2.0.0 to 3.0 Array methods should return consistent values. But we keep the behavior for now to maintain compatibility. We will fix this (to consistently return Arrays) in 3.0. Matz. ---------------------------------------- Bug #6087: How should inherited methods deal with return values of their own subclass? https://bugs.ruby-lang.org/issues/6087#change-28054 Author: marcandre (Marc-Andre Lafortune) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: 3.0 ruby -v: trunk Just noticed that we still don't have a consistent way to handle return values: class A < Array end a = A.new a.flatten.class # => A a.rotate.class # => Array (a * 2).class # => A (a + a).class # => Array Some methods are even inconsistent depending on their arguments: a.slice!(0, 1).class # => A a.slice!(0..0).class # => A a.slice!(0, 0).class # => Array a.slice!(1, 0).class # => Array a.slice!(1..0).class # => Array Finally, there is currently no constructor nor hook called when making these new copies, so they are never properly constructed. Imagine this simplified class that relies on `@foo` holding a hash: class A < Array def initialize(*args) super @foo = {} end def initialize_copy(orig) super @foo = @foo.dup end end a = A.new.flatten a.class # => A a.instance_variable_get(:@foo) # => nil, should never happen I feel this violates object orientation. One solution is to always return the base class (Array/String/...). Another solution is to return the current subclass. To be object oriented, I feel we must do an actual `dup` of the object, including copying the instance variables, if any, and calling `initialize_copy`. Exceptions to this would be (1) explicit documentation, e.g. Array#to_a, or (2) methods inherited from a module (like Enumerable methods for Array). I'll be glad to fix these once there is a decision made on which way to go. -- http://bugs.ruby-lang.org/