Getting error as "private method `initialize' called for", where as `initialize` is a publuic method

class Person
def initialize(name)
puts “I am calling by #{self}, which is #{self.class} object”
end
end

pr = Person.new(‘foo’)
pr.initialize

>> I am calling by #Person:0x19a4e10, which is Person object

<main>': private methodinitialize’ called for #Person:0x19a4e10

(NoMethodError)

This code is confusing to me. I found this behavior, while I am writing
a code in my other tasks.

As mush as I know, We wouldn’t be able to call any private methods with
an explicit receiver. But the I overrode initialize and it is public,
thus pr.initialize is successful and I got the output.

Now the fact that making me confused it, the second line, which is an
objection saying me that I am trying to call a private method
initialize.

These 2 behaviors contradict with my understanding. Can any one explain
what’s going on here ?

Thanks,
Arup

On Mon, Mar 10, 2014 at 11:55 AM, Arup R. [email protected]
wrote:

class Person
def initialize(name)
puts “I am calling by #{self}, which is #{self.class} object”
end
end

pr = Person.new(‘foo’)
pr.initialize

Now you are trying to initialize the instance a second time. That does
not make sense. Apart from that you are not providing enough
arguments.

>> I am calling by #Person:0x19a4e10, which is Person object

<main>': private method initialize’ called for #Person:0x19a4e10

(NoMethodError)

This code is confusing to me. I found this behavior, while I am writing
a code in my other tasks.

As mush as I know, We wouldn’t be able to call any private methods with
an explicit receiver. But the I overrode initialize and it is public,
thus pr.initialize is successful and I got the output.

No, it isn’t.

irb(main):001:0> class Foo; def initialize; end end
=> nil
irb(main):002:0> Foo.public_instance_methods.grep /init/
=> [:initialize_dup, :initialize_clone]
irb(main):003:0> Foo.private_instance_methods.grep /init/
=> [:initialize, :initialize_copy]

Now the fact that making me confused it, the second line, which is an
objection saying me that I am trying to call a private method
initialize.

These 2 behaviors contradict with my understanding. Can any one explain
what’s going on here ?

See above.

Cheers

robert

Robert K. wrote in post #1139363:

Now you are trying to initialize the instance a second time. That does
not make sense. Apart from that you are not providing enough
arguments.

class Person
def initialize(name)
name
end
end

pr = Person.new(‘foo’)
pr.initialize(12)

private method `initialize’ called for

#Person:0x19a4e10(NoMethodError)

So, even if I write the method #initialize in public scope, it
became private method by default. Is it the correct catch ?

Yes, it is correct behavior that #initialize is private.
#initialize is automatically called when #new is invoked, you will get
unexpected behavior if you run it again.

“ruby-talk” [email protected] wrote on 03/10/2014
07:16:14
AM:

Arup, your questions are always interesting, touching on edge cases of
the
language. Let me recommend you to purchase “The Ruby P.ming
Language”
(Flanagan & Matsumoto) and read it from cover to cover.

If I understand it correctly, your underlying question is: how come is
this
method private if I did not mark it as such.

Answer is on page 232 of that book. As a rule of thumb, methods are
public
unless declared otherwise, with the exception of “initialize” and
top-level methods outside a class definition.

unknown wrote in post #1139365:

Yes, it is correct behavior that #initialize is private.
#initialize is automatically called when #new is invoked

True. I am aware of.

, you will get

unexpected behavior if you run it again.

No, you can call initialize, but implicitly. See below.

class Person
def initialize(name)
“I am being called from #{name}”
end
def call_initialize
initialize(method)
end
end

pr = Person.new(‘foo’)
puts pr.call_initialize

I am being called from call_initialize

The fact to note here is - A method you are creating in the public
scope, became provate by the magic of Ruby’s internal. That is
misleading somehow. This is an Exception .

On Mon, Mar 10, 2014 at 12:41 PM, Arup R. [email protected]
wrote:

Xavier N. wrote in post #1139365:

initialize(__method__)

end
end

pr = Person.new(‘foo’)
puts pr.call_initialize

I am calling from call_initialize

Even this invocation will fail because of insufficient number of
arguments. Btw, you do not need to define another method, you can
simply use #send.

The fact to note here is - A method you are creating in the public
scope, became provate by the magic of Ruby’s internal. That is
misleading somehow.

I beg to differ: you do not invoke #initialize explicitly anyway. So
this exception helps us avoid errors.

This is an Exception .

Yes, as is mentioned in the book Xavier recommended earlier.

Cheers

robert

Xavier N. wrote in post #1139367:

Arup, your questions are always interesting, touching on edge cases of
the
language.

Thank you :slight_smile:

Answer is on page 232 of that book. As a rule of thumb, methods are
public
unless declared otherwise, with the exception of “initialize” and
top-level methods outside a class definition.

Yes. I was looking at book. But He wrote it long back. After that, as
far as I know, Ruby internal changed multiple times. I don’t know why
there is not a new edition although… :frowning: