Confusion about object method scoping

Hello,

I am defining a class. That class has several methods. In one of the
class methods I’m trying to use a previously defined method. It’s
throwing an exception. Here’s some code that demonstrates my problem.
Am I really unable to have a class use some of it’s own methods if
they’ve already been defined? Thanks in advance!

class Calculator

private
def add(x,y)
x+y
end

public
def Calculator.factorial(x)
result = 0

(1…x).each { |number|
result = add(result,number)
}

result
end

end

puts Calculator.factorial()

On Mon, Jun 15, 2009 at 11:31 AM, Christopher Carver
[email protected]wrote:

private
}

result
end

end

Is it? ArgumentError: wrong number of arguments (0 for 1)
You’re calling your method without a required argument.

puts Calculator.factorial()

Which you defined when you wrote:

def Calculator.factorial(x)

You could send a default value if you don’t want to specify one
everytime

def Calculator.factorial(x = 0)

I just realized I made a couple of typos. I forgot to pass an
argument to Calculator.factorial and in factorial I used the =
operator instead of +=. But I think you see what I am trying to do.
How can I make a class method callable by another method in that
class?

On 15.06.2009 18:31, Christopher Carver wrote:

private
}

result
end

end

puts Calculator.factorial()

You are mixing class and instance methods. You need to make add also a
class method, e.g. by doing something like this

class Calculator
class <<self
def factorial(x)
result = 0
(1…x).each { |number|
result = add(result, number)
}
result
end

private
def add(x,y) x + y end
end
end

Btw, the naming “factorial” seems a bit odd for a sum.

Kind regards

robert

Thanks! That worked. It’s actually computing the factorial (sum of
all digits leading up to the argument). Can you give me a term for
what is going on in your example with the “<<” notation? I’d like to
read about it and understand it more. I’m a bit new to Ruby.

Thanks a lot for the help!

Chris

On Mon, Jun 15, 2009 at 12:45 PM, Robert

On 15.06.2009 18:56, Christopher Carver wrote:

Thanks! That worked. It’s actually computing the factorial (sum of
all digits leading up to the argument). Can you give me a term for
what is going on in your example with the “<<” notation? I’d like to
read about it and understand it more. I’m a bit new to Ruby.

It’s the singleton class of the class instance. I know this sounds a
bit weird but every object in Ruby has this singleton class and since
classes are objects, too, they do so as well. Methods defined in the
singleton class methods of that instance only. So basically these two
are equivalent:

o = … # any object
def o.meth
end

class <<o
def meth
end
end

Kind regards

robert

On Mon, Jun 15, 2009 at 12:56 PM, Christopher Carver[email protected]
wrote:

Thanks! That worked. It’s actually computing the factorial (sum of
all digits leading up to the argument).

Well not exactly: Factorial - Wikipedia


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

On Mon, Jun 15, 2009 at 12:31 PM, Christopher Carver[email protected]
wrote:

private
def add(x,y)
x+y
end

This defines a method add which any instances of the class Calculator
would have, if you had any, which you don’t in this code.

end

end

And this defines a method on the object which is the class called
Calculator. Since Calculator isn’t an instance of Calculator it
doesn’t have an add method.

Now how to fix it. One way is

class Calculator
class < self
def factorial(x)
result = 0
(1…x).each { |number|
result = add(result,number)
}
result
end

   def add(x, y)
      x + y
   end
end

end

puts Calculator.factorial(5)

Another way is to actually use an instance of Calculator:

class Calculator
def factorial(x)
result = 0
(1…x).each { |number|
result = add(result,number)
}
result
end

   def add(x, y)
      x + y
   end

end

puts Calculator.new.factorial(5)

BTW. I’ve not mentioned until now that your factorial is actually
computing the sum instead of the factorial, because I think that’s a
separate issue.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale