Very interesting question! I researched it and found some interesting things about Ruby, though I did not find the exact answer you're looking for.
initialize is a private instance method that is meant to be redefined on most objects. It comes from BasicObject, the Ruby class from which all objects and classes inherit.
Any new class you create in Ruby will have a private instance method called initialize:
class Q ; end
Q.private_instance_methods.include?(:initialize)
=> true
That instance method is inherited from BasicObject#initialize:
q = Q.new
q.method(:initialize)
=> #<Method: Q(BasicObject)#initialize>
And the method itself is not defined in Ruby, it comes from the C source of the language:
q.method(:initialize).source_location
=> nil
This is what that looks like in the Ruby source code (object.c file):
rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, 0);
rb_obj_dummy is basically a no-op function. Which makes sense because the expectation is that you'll override initialize with your own implementation code in your class.
All that said, your original question was about why initialize doesn't become a public method when you define it in the public space in your class definition. I don't know. Normally if you do that for any other method it will become a public method:
class Q
private
def my_private_method() "private" end
end
Q.new.my_private_method
NoMethodError: private method `my_private_method' called for #<Q:0x007fc5ea39eab0>
class Q
def my_private_method() "now i'm a public method" end
end
Q.new.my_private_method
=> "now i'm a public method"
So I guess somewhere else deep in the source code defining a method named "initialize" is handled differently from other methods. I couldn't find it, but maybe someone else can.
initializemethod is special. It hasn't been declared as private.