[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

confusion about object method scoping

Christopher Carver

6/15/2009 4:31:00 PM

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

7 Answers

Daniel Roux

6/15/2009 4:41:00 PM

0

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

On Mon, Jun 15, 2009 at 11:31 AM, Christopher Carver <ccarver0@gmail.com>wrote:

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

--
Daniel Roux

Robert Klemme

6/15/2009 4:41:00 PM

0

On 15.06.2009 18:31, Christopher Carver wrote:
> 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


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestprac...

Christopher Carver

6/15/2009 4:44:00 PM

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 =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?

On Mon, Jun 15, 2009 at 12:31 PM, Christopher Carver<ccarver0@gmail.com> wr=
ote:
> 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
>
> =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
>
> puts Calculator.factorial()
>

Rick DeNatale

6/15/2009 4:50:00 PM

0

On Mon, Jun 15, 2009 at 12:31 PM, Christopher Carver<ccarver0@gmail.com> wr=
ote:
> 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.denh...
Twitter: http://twitter.com/Ri...
WWR: http://www.workingwithrails.com/person/9021-ric...
LinkedIn: http://www.linkedin.com/in/ri...

Christopher Carver

6/15/2009 4:57:00 PM

0

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
Klemme<shortcutter@googlemail.com> wrote:
> On 15.06.2009 18:31, Christopher Carver wrote:
>>
>> Hello,
>>
>> I am defining a class. =A0That class has several methods. =A0In one of t=
he
>> 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
>>
>> =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
>>
>> puts Calculator.factorial()
>>
>
> You are mixing class and instance methods. =A0You need to make add also a
> class method, e.g. by doing something like this
>
> class Calculator
> =A0class <<self
> =A0 =A0def factorial(x)
> =A0 =A0 =A0result =3D 0
> =A0 =A0 =A0(1..x).each { |number|
> =A0 =A0 =A0 result =3D add(result, number)
> =A0 =A0 =A0}
> =A0 =A0 =A0result
> =A0 =A0end
>
> =A0private
> =A0 =A0def add(x,y) x + y end
> =A0end
> end
>
> Btw, the naming "factorial" seems a bit odd for a sum.
>
> Kind regards
>
> =A0 =A0 =A0 =A0robert
>
>
> --
> remember.guy do |as, often| as.you_can - without end
> http://blog.rubybestprac...
>
>

Robert Klemme

6/15/2009 5:02:00 PM

0

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

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestprac...

Rick DeNatale

6/15/2009 6:28:00 PM

0

On Mon, Jun 15, 2009 at 12:56 PM, Christopher Carver<ccarver0@gmail.com> wr=
ote:
> Thanks! =A0That worked. =A0It's actually computing the factorial (sum of
> all digits leading up to the argument).

Well not exactly: http://en.wikipedia.org/wiki...

--=20
Rick DeNatale

Blog: http://talklikeaduck.denh...
Twitter: http://twitter.com/Ri...
WWR: http://www.workingwithrails.com/person/9021-ric...
LinkedIn: http://www.linkedin.com/in/ri...