From: Chris White Date: 2011-08-02T04:50:58+09:00 Subject: Re: newbie question > class Factorial > def fact(n) > if n == 0 > 1 > else > n * fact(n-1) > end > end > end > > my_fact = Factorial.new > puts "enter a positive integer: " > my_fact = gets.to_i > puts "factorial: #{fact(n)}" > > I get this error: > > marcc$ ruby factorial7.rb > enter a positive integer: 4 > factorial7.rb:14:in `
': undefined local variable or method `n' for > main:Object (NameError) > There's two issues here. The first is that you renamed `n` to `my_fact`, so it becomes undeclared as the error mentions. The other is that since fact is now part of the Factorial class, you need to change how fact() is called: puts "factorial: #{my_fact.fact(n)}" More interesting stuff to help you along the learning path. Right now in order to access your fact function, you have to create a new instance of the class. Instead you can utilize what is known as a singleton method. So the class can be rewritten as such: class Factorial def Factorial.fact(n) if n == 0 1 else n * fact(n-1) end end end puts Factorial.fact(10) Now we don't have to create a new instance just to call the method, and the method still remains encapsulated in the Factorial class for organizational purposes. Next up is to make the code a bit shorter: class Factorial def Factorial.fact(n) (n == 0) ? 1 : n * fact(n-1) end end puts Factorial.fact(10) This uses the ternary operator ( http://invisibleblocks.wordpress.com/2007/06/11/rubys-other-ternary-operator/ ) which has the format: (condition to test) ? if condition is true run this : if condition is false run this Finally for something even more advanced, you can use inject and kill the need for a recursive call all together: class Factorial def Factorial.fact(n) (1..n).inject(1, :*) end end puts Factorial.fact(10) More information on inject can be found here: http://www.ruby-doc.org/core/classes/Enumerable.html#M001494 I'd recommend reading it over and write some code that uses it. It is a very powerful tool! Regards, Chris White Twitter: http://www.twitter.com/cwgem