Abhinay
Abhinay

Reputation: 1816

ArgumentError: wrong number of arguments in 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.

Upvotes: 4

Views: 14805

Answers (4)

Arup Rakshit
Arup Rakshit

Reputation: 118261

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

Upvotes: 9

Andrii Furmanets
Andrii Furmanets

Reputation: 1161

Please, take a look at code below:

class Person
  attr_reader :name

  def initialize(name)
    @name = name
  end

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

person = Person.new("ak")
person.greet("aks")

#=> Hi aks, my name is ak

Upvotes: 1

Gregory Witek
Gregory Witek

Reputation: 1226

The problem is that to create new object you need to call method new on class, and not initialize on the object.

So code looks like this:

p = Person.new("John")

Upvotes: 3

robotcookies
robotcookies

Reputation: 1059

You need to call the methods on the object (not just call the methods) and initialize is automatically called when creating a new object:

p = Person.new("ak")
p.greet("aks")          #=> "Hi aks, my name is ak"

Upvotes: 4

Related Questions