confusion about object method scoping

C

Christopher Carver

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()
 
D

Daniel Roux

[Note: parts of this message were removed to make it a legal post.]

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


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)
 
R

Robert Klemme

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()

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
 
C

Christopher Carver

I just realized I made a couple of typos. I forgot to pass an
argument to Calculator.factorial and in factorial I used the =3D
operator instead of +=3D. 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?
 
R

Rick DeNatale

Hello,

I am defining a class. =A0That class has several methods. =A0In one of th= e
class methods I'm trying to use a previously defined method. =A0It's
throwing an exception. =A0Here's some code that demonstrates my problem.
=A0Am I really unable to have a class use some of it's own methods if
they've already been defined? =A0Thanks in advance!

class Calculator

=A0private
=A0def add(x,y)
=A0 x+y
=A0end

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.
=A0public
=A0def Calculator.factorial(x)
=A0 result =3D 0

=A0 (1..x).each { |number|
=A0 =A0 result =3D add(result,number)
=A0 }

=A0 result
=A0end

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 =3D 0
(1..x).each { |number|
result =3D 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 =3D 0
(1..x).each { |number|
result =3D 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.

--=20
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
 
C

Christopher Carver

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
 
R

Robert Klemme

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top