Another newbie frustration with class instantiation

Context:
So far, I’ve been “writing” Ruby scripts to learn the basics. Now I want
to use O-O such as class instantiation. Some of my attempts work pretty
well, but the following one has been frustrating me for a while. I get
the following error to my really simple program (below):

/Users/marcc/.rvm/rubies/ruby-2.1.0/bin/ruby -e
$stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)
/Users/marcc/RubymineProjects/Tests/adder.rb
Enter first number:
34
Enter second number:
23
/Users/marcc/RubymineProjects/Tests/adder.rb:5:in initialize': wrong number of arguments (0 for 2) (ArgumentError) from /Users/marcc/RubymineProjects/Tests/adder.rb:20:innew’
from /Users/marcc/RubymineProjects/Tests/adder.rb:20:in <top (required)>' from -e:1:inload’
from -e:1:in `’

Process finished with exit code 1

Here is my code:

Add numbers from user input

class Adder

def initialize(n1, n2)
@n1 = n1
@n2 = n2
end

def calculate_sum(n1, n2)
n1 + n2
end
end

puts 'Enter first number: ’
n1 = gets.chomp
puts 'Enter second number: ’
n2 = gets.chomp

my_sum = Adder.new
my_sum.calculate_sum(n1, n2)
puts my_sum

The error is coming from “my_sum = Adder.new”

You wrote “initialize” inside the Adder class to accept two arguments:
n1 and n2. When you call Adder.new, you need to pass it those arguments
or it will throw an error.

By the way, you create the instance variables @n1 and @n2 but you never
use them.

Joel P. wrote in post #1179810:

The error is coming from “my_sum = Adder.new”

You wrote “initialize” inside the Adder class to accept two arguments:
n1 and n2. When you call Adder.new, you need to pass it those arguments
or it will throw an error.

By the way, you create the instance variables @n1 and @n2 but you never
use them.

Thanks for the answer. I’ve written quite complicated scripts so far, I
don’t understand why I’m stumbling on such a minor snag!

I did add arguments as you mentioned:

my_sum = Adder.new(n1, n2)
my_sum.calculate_sum(n1, n2)
puts 'Result: ’ + my_sum.to_s

I don’t have an error anymore, however, I don’t get a result (even when
I add to_s as above. The result is as follows:

Enter first number:
34
Enter second number:
12
Result: #Adder:0x0000010285b440

Process finished with exit code 0

Finally, I did notice that I don’t use the instance vars I created, but
if I get rid of initialize, I get an error.

Joel P. wrote in post #1179816:

class Adder

def initialize
end

def calculate_sum(n1, n2)
n1 + n2
end

end

puts 'Enter first number: ’
n1 = gets.to_i
puts 'Enter second number: ’
n2 = gets.to_i

my_sum = Adder.new
puts my_sum.calculate_sum(n1, n2)

Thanks. There are two things I need to work on for now: to_i and
constructors (i.e., when you need them and when you don’t). Thanks
again.

constructors (i.e., when you need them and when you don’t).

You can think of the “default values” for your class.

def initialize

can accept arguments. They will get passed when you invoke .new such as:

class Foo
def initialize
end
end

foo = Foo.new

or

foo = Foo.new(ARGV) # ARGV has commandline arguments

In that case you must change “def initialize” to accept arguments:

class Foo
def initialize(commandline_arguments = ARGV)
end
end

All methods can have arguments with default values. Inside of
initialize(), you can also assign to @instance_variables to keep
track of state.

Just play with it for a while, eventually you realize that it is really
simple.

You can think of classes as the blueprint for your objects, which you
can manipulate the way you want them to behave, either by changing the
class itself, or by ad-hoc adding or removing methods onto your specific
object (but usually, modifying the class is easier and better and
simpler - all good things start with a solid design, keep that in mind)

class Adder

def initialize
end

def calculate_sum(n1, n2)
n1 + n2
end

end

puts 'Enter first number: ’
n1 = gets.to_i
puts 'Enter second number: ’
n2 = gets.to_i

my_sum = Adder.new
puts my_sum.calculate_sum(n1, n2)

Robert H. wrote in post #1179848:

constructors (i.e., when you need them and when you don’t).

You can think of the “default values” for your class.

def initialize

can accept arguments. They will get passed when you invoke .new such as:

class Foo
def initialize
end
end

foo = Foo.new

or

foo = Foo.new(ARGV) # ARGV has commandline arguments

In that case you must change “def initialize” to accept arguments:

class Foo
def initialize(commandline_arguments = ARGV)
end
end

All methods can have arguments with default values. Inside of
initialize(), you can also assign to @instance_variables to keep
track of state.

Just play with it for a while, eventually you realize that it is really
simple.

You can think of classes as the blueprint for your objects, which you
can manipulate the way you want them to behave, either by changing the
class itself, or by ad-hoc adding or removing methods onto your specific
object (but usually, modifying the class is easier and better and
simpler - all good things start with a solid design, keep that in mind)

Thanks for the reply. I’ve been playing around with my original “silly”
program just explore constructors. Below are my original program (no
constructor), followed by the same program (with a constructor). I’m
always surprised how Ruby allows one to do the same things in different
ways.

class UserInput3

def initialize
# no constructor required in this case
end

def calculate_sum(n1, n2)
n1 + n2
end
end

print 'Enter first number: ’
n1 = gets.to_i
print 'Enter second number: ’
n2 = gets.to_i

my_sum = UserInput3.new
print "\tResult: ", my_sum.calculate_sum(n1, n2)

Now, with constructor:

class UserInput1

def initialize(n1, n2)
@n1 = n1
@n2 = n2
end

def sum
@n1.to_i + @n2.to_i
end
end

print 'Enter first number: ’
@n1 = gets
print 'Enter second number: ’
@n2 = gets

puts result = ’ Result: ’ + UserInput1.new(@n1, @n2).sum.to_s