Newbie's need for help

I’m learning to write Ruby using classes (as opposed to scripts).
I can’t get the following (extremely simple) class to run (although I
get the corresponding script right). What do I need to do to fix it?

Here is the class:

class Input1

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

def sum
@n1 + @n2
end

end

puts "Enter first number: "
@n1 = gets
puts "Enter second number: "
@n2 = gets

puts result = Input1(new).sum.to_s

result = Input1.new( 10, 20 ).sum.to_s

= 30

?

On Mon, Aug 4, 2014 at 11:13 AM, Marc C. [email protected]

Marc,

You must first instantiate the class in order to access the instance
variables within the object. Here is what you could do. It isn’t the
best
way to write this code, but it should serve to help you understand how
to
instantiate the class.

class Input1

attr_accessor :n1, :n2

def sum
@n1 + @n2
end

end

test_object = Input1.new

test_object.n1 = gets.chomp.to_i
test_object.n2 = gets.chomp.to_i

test_object.sum

Like I said, this isn’t a beautiful example. However, in order to
access the instance variable held within the class, you need to set up
the attr_accessor.

If you have any questions about this, feel free to email me.

Phill

On Sun, Aug 3, 2014 at 9:16 PM, Brett Herford-Fell
[email protected]

Thanks for the answer but that’s not what I want to do. I want to use a
keyboard dialog where I prompt the use to enter two values separately. I
know how to write the script for that, I’m having problems with writing
the
equivalent class.

class Input1

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

def sum
@n1 + @n2
end

end

puts "Enter first number: "
@n1 = gets
puts "Enter second number: "
@n2 = gets

puts result = Input1(new).sum.to_s

Here is what happens when I run the class above:

~/desktop marcc$ ruby test1.rb

Enter first number:

12

Enter second number:

13

test1.rb:19:in <main>': undefined local variable or method new’ for
main:Object (NameError)

On Sun, Aug 3, 2014 at 6:16 PM, Brett Herford-Fell
[email protected]

There way to do it has been answered. The two main problems that I see
here
are:

Problem 1
Input1(new) …to create a new Input1 object, you should call
Input1.new (i.e. call the new method on the Input1 class)

Problem 2
the gets method is returning a string, so you need to cast the
variables
to integers somewhere (using .to_i) this can be in the class, or on gets
(i.e. gets.to_i)

On Sun, Aug 3, 2014 at 9:13 PM, Marc C. [email protected]

Thanks for the answer.
In your example, however, there’s no user interaction. I want to prompt
the user to enter information as shown in my original code.
Marc

Sent from mobile device - Pardon possible typos!

you don’t pass new as a parameter, the following code works

class Input1

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

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

end

puts "Enter first number: "
@n1 = gets
puts "Enter second number: "
@n2 = gets

puts ‘--------------’
puts result = Input1.new(@n1, @n2).sum.to_s

➜ ruby git:(master) ✗ ruby test1.rb
Enter first number:
1
Enter second number:
2

3
➜ ruby git:(master) ✗

On Mon, Aug 4, 2014 at 11:31 AM, Phillip B. [email protected]

On 4 August 2014 15:09, Marc C. [email protected] wrote:

Thanks for the answer.
In your example, however, there’s no user interaction. I want to prompt
the user to enter information as shown in my original code.
Marc

​Actually, there is user interaction – it calls gets twice. It just
doesn’t print anything. Surely you’re capable of adding some putses,
though.​

Thanks for the answer, Brett, it helped a lot. Now I can see clearly
what I was doing wrong.
Marc

Sent from mobile device - Pardon possible typos!

Thanks for the answer, Jakub, that was very helpful.
Marc

Sent from mobile device - Pardon possible typos!

Yes, correct. I just realized that right after I sent my reply!
Thanks.

Sent from mobile device - Pardon possible typos!

Thanks, Robert. I like the idea. It makes the class more general and the
instantiation cleaner.
Marc

On Mon, Aug 4, 2014 at 4:40 AM, Robert K.
[email protected]

On Mon, Aug 4, 2014 at 7:15 AM, Marc C. [email protected]
wrote:

the gets method is returning a string, so you need to cast the variables
to integers somewhere (using .to_i) this can be in the class, or on gets
(i.e. gets.to_i)

In this example it may not make a difference but I would do the
conversion when the instance variables are set. Reason: then the data
members always have the proper type and you detect wrong values early
on. Also, it’s more efficient in case someone is invoking #sum over
and over again. Thusly:

class Input1

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

def sum
@n1 + @n2
end

end

puts "Enter first number: "
n1 = gets
puts "Enter second number: "
n2 = gets

puts Input1.new(n1, n2).sum

or, more verbose and reusing your variable assignment

result = Input1.new(n1, n2).sum
puts result

or holding on to the created instance of Input

data = Input1.new(n1, n2)
puts data.sum

Note: you do not need #to_s because puts does this implicitly.

I also fixed “problem” 3: using instance variables for input. This is
of course possible but a local variable seems more appropriate here.

Kind regards

robert

On Mon, Aug 4, 2014 at 12:02 PM, Marc C. [email protected]
wrote:

Thanks, Robert. I like the idea. It makes the class more general and the
instantiation cleaner.

Have fun learning Ruby! Your question was answered but I hope this
helps understand the context too:
http://codelikethis.com/lessons/ruby_objects/classes

common mistake I used to make always instationate a class and dont
forget
your getter/setter method which in ruby is your _attr_aceessor it has
the
getter setter both built in

Thanks, Alex.
Interesting and concise. Good learning tool.

Sent from mobile device - Pardon possible typos!

Thanks. I’m practicing all the good advice I’ve had on this list.
Thanks!