Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArgumentError: wrong number of arguments in Ruby

Tags:

ruby

Trying to solve this problem,

  class Person
      def initialize(name)
        @name=name
      end

      def greet(other_name)
       puts "Hi #{other_name}, my name is #{name}"
      end
    end

    initialize("ak")
    greet("aks")

but I am getting the error like:

ArgumentError: wrong number of arguments calling `initialize` (1 for 0)

I don't understand what is asking here, if its just the argument then why the error is like (1 for 0). can someone help me understand this problem.

like image 777
Abhinay Avatar asked Dec 03 '22 20:12

Abhinay


1 Answers

Look at this code:

class Person
  attr_reader :name

  def initialize( name )
    puts "Initializing Person instance #{object_id}"
    @name = name
  end

  def greet( name )
    puts "Hi #{name}, I'm #{name()}"
  end
end

When you wrote initialize without explicit receiver:

initialize( "ak" )

It was only a matter of luck that your message was recognized. Look who has responded:

method( :initialize ).owner
#=> BasicObject

BasicObject, the foremother of all Object instances, herself responded to your call, by scolding you about wrong number of arguments, because:

method( :initialize ).arity
#=> 0

Not only this method does not expect any arguments, but also you are not expected to call it at all. In fact, you are not expected to call #initialize on any object by yourself, save for exceptional situations. Class#new method handles calling of Person#initialize method for you:

A = Person.new( 'Abhinay' )
Initializing Person instance -605867998 
#=> #<Person:0xb7c66044 @name="Abhinay">

Person.new handled creation of a new instance and automatically called its #initialize method. Also, #initialize method is created private, even if you did not specify it explitcitly. The technical term for such irregular behavior is magic. Person#initialize is magically private:

A.initialize( 'Fred' )
NoMethodError: private method `initialize' called for #<Person:0xb7c66044 @name="Abhinay">

You cannot just reinitialize yourself to 'Fred', you know. All other methods are public unless prescribed otherwise:

A.greet "Arup"
Hi Arup, I'm Abhinay
#=> nil
like image 89
Arup Rakshit Avatar answered Jan 07 '23 08:01

Arup Rakshit