How does Ruby make #initialize private?

I understand that the Ruby #initialize method is private . However, what stumps me is how Ruby makes the method private.

Usually we define classes as follows:

class Cat def initialize(name) @name = name end def say_name puts @name end end 

where #initialize seems to be defined publicly next to #say_name . How did Ruby manage to #initialize private after class definition?

+7
private ruby
source share
2 answers

Yukihiro Matsumoto (inventor of Ruby) said :

#initialize in its construction is supposed to be called only from within #new to split into initialization of each object / class from #new, so you do not need to redefine #new. When you need / need to override #new, I find this to be a bad design.

One reason: #initialize private is to tell you a bad design.

So, in the end, this is a built-in Ruby function that #initialize is automatically closed, and therefore it will not be easy for developers to call it outside the method of the .new class.

+9
source share

Very interesting question! I researched it and found interesting things about Ruby, although I did not find the exact answer you are looking for.

initialize is a private instance method that should be overridden for most objects. It comes from BasicObject , the Ruby class from which all objects and classes are inherited.

Any new class created in Ruby will have a private instance method initialize :

 class Q ; end Q.private_instance_methods.include?(:initialize) => true 

This instance method inherits 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 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. This makes sense since you are expected to override initialize with your implementation code in your class.

All that was said, your initial question was about why initialize does not become a public method when you define it in public space in the definition of your class. I dont know. Usually, if you do this 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 think that somewhere else deep in the source code that defines the method called "initialize", it is handled differently than other methods. I could not find him, but maybe someone else can.

+3
source share

All Articles