Issue #13358 has been updated by Eregon (Benoit Daloze).


I agree making OpenStruct.allocate an alias of Class#new is not a great idea and easily problematic.
We had a problem due to this in TruffleRuby (now fixed by renaming all our internal allocate methods).

The fix we came up with seems cleaner and let YAML deserialize OpenStruct (the original reason why this alias was introduced)
by making respond_to? work on a OpenStruct.allocate instance.
It only needs an extra "&" in
https://github.com/ruby/ruby/blob/d77214e8a37efecfa835ce56ce5f11e4125effd4/lib/ostruct.rb#L198
therefore becoming:
https://github.com/graalvm/truffleruby/blob/8338f62a711e2a1d816dd8393b9402c6d3238e8c/lib/patches/ostruct.rb#L10

----------------------------------------
Bug #13358: OpenStruct overriding allocate
https://bugs.ruby-lang.org/issues/13358#change-63764

* Author: sitter (Harald Sitter)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
In https://github.com/ruby/ruby/commit/15960b37e82ba60455c480b1c23e1567255d3e05 OpenStruct gained

~~~
  class << self # :nodoc:
    alias allocate new
  end
~~~

Which is rather severely conflicting with expected behavior as Class.allocate is meant to [not call initialize](http://ruby-doc.org/core-2.4.0/Class.html#method-i-allocate). So, in fact, the change made allocate of OpenStruct do what allocate is asserting not to do :-/

For OpenStruct itself that isn't that big a deal, for classes inheriting from OpenStruct it breaks allocate though.

Example:

~~~
require 'ostruct'

class A < OpenStruct
  def initialize(x, y = {})
    super(y)
  end
end

A.allocate
~~~

As `allocate` is alias'd to `new` in `OpenStruct` this will attempt to initialize `A` which will raise an `ArgumentError` because `A` cannot be initialized without arguments.

~~~
$ ruby x.rb
x.rb:4:in `initialize': wrong number of arguments (given 0, expected 1..2) (ArgumentError)
        from x.rb:9:in `new'
        from x.rb:9:in `<main>'
~~~

OpenStruct at the very least should document the fact that its allocate is behaving differently.
Ideally, OpenStruct should not alias allocate at all.



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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>