Feature #2451

BasicObject.initialize with variable number of argument

Added by Marc-Andre Lafortune about 2 years ago. Updated 10 months ago.

[ruby-core:27080]
Status:Closed Start date:12/07/2009
Priority:Normal Due date:
Assignee:Yukihiro Matsumoto % Done:

100%

Category:core
Target version:1.9.2

Description

If one wants to write a class easily extensible (for some kind of library, say), then there is no nice way to have the initialize method be extensible other than through monkeypatching.

This could be made much more flexible if BasicObject.initialize accepted any number of arguments.

Would there be a downsize to have BasicObject.initialize accept many arguments?

Here's a more detailed example:

class NiceClass
  def initialize(arg1, arg2)
    # do some stuff with arg1 and arg2
    super # allow for included modules to initialize
  end
end

# Someone else:
class NiceClass
  module CoolExtension
    def initialize(arg1, arg2)
      # do cool stuff
      super # allow for more extensions
    end
  end

  include CoolExtension
end

This would not work unless BasicObject#initialize accepts any number of arguments. Currently, only super() -- i.e. passing none of the arguments -- can be called, so arg1 & arg2 must be copied to instance variables for included modules to access, or else monkeypatching becomes the only possibility. 

The patch is trivial:

diff --git a/object.c b/object.c
index 10eb983..33cae20 100644
--- a/object.c
+++ b/object.c
@@ -2538,7 +2538,7 @@ Init_Object(void)
 #undef rb_intern
 #define rb_intern(str) rb_intern_const(str)

-    rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, 0);
+    rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, -1);
     rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance);
     rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
     rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);


Notes: 
- There is no documentation for BasicObject#initialize.
- Ironically, the Ruby Draft Specification states that Object#initialize accepts any number of arguments! I'm glad I already have that team agree with me ;-)
- No error is generated by make test-all
- See also http://blog.rubybestpractices.com/posts/rklemme/018-Complete_Class.html where Robert Klemme recommends calling super from constructors but has to use super(), i.e. passing no arguments

Similarly, I also propose that Object#initialize accepts any number of arguments in Ruby 1.8.8

Related issues

related to ruby-trunk - Bug #5542: Ruby 1.9.3-p0 changed arity on default initialization method Rejected 11/02/2011

Associated revisions

Revision 26135
Added by Marc-Andre Lafortune about 2 years ago

* object.c: BasicObject#initialize accepts any number of arguments [ruby-core:27080]

Revision 29638
Added by Marc-Andre Lafortune over 1 year ago

* object.c: Make BasicObject.new accept no parameter. Revert of r26135 [ruby-core:27080], as per [ruby-core:32952].

History

Updated by Yukihiro Matsumoto about 2 years ago

Hi,

In message "Re: [ruby-core:27080] [Feature #2451] BasicObject.initialize with variable number of argument"
    on Mon, 7 Dec 2009 10:18:36 +0900, Marc-Andre Lafortune <redmine@ruby-lang.org> writes:

|This could be made much more flexible if BasicObject.initialize accepted any number of arguments.
|Would there be a downsize to have BasicObject.initialize accept many arguments?

I don't think so.  Please check in the fix.

							matz.

Updated by Marc-Andre Lafortune about 2 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100
This issue was solved with changeset r26135.
Marc-Andre, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

Also available in: Atom PDF