confusion about object method scoping

Discussion in 'Ruby' started by Christopher Carver, Jun 15, 2009.

  1. 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()
    Christopher Carver, Jun 15, 2009
    #1
    1. Advertising

  2. Christopher Carver

    Daniel Roux Guest

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

    On Mon, Jun 15, 2009 at 11:31 AM, 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



    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
    Daniel Roux, Jun 15, 2009
    #2
    1. Advertising

  3. 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.rubybestpractices.com/
    Robert Klemme, Jun 15, 2009
    #3
  4. 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<> 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()
    >
    Christopher Carver, Jun 15, 2009
    #4
  5. On Mon, Jun 15, 2009 at 12:31 PM, Christopher Carver<> 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.denhaven2.com/
    Twitter: http://twitter.com/RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
    Rick DeNatale, Jun 15, 2009
    #5
  6. 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<> 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.rubybestpractices.com/
    >
    >
    Christopher Carver, Jun 15, 2009
    #6
  7. 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.rubybestpractices.com/
    Robert Klemme, Jun 15, 2009
    #7
  8. Rick DeNatale, Jun 15, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RGF2ZQ==?=

    Stupid Scoping Problem?

    =?Utf-8?B?RGF2ZQ==?=, Jan 30, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    333
    =?Utf-8?B?RGF2ZQ==?=
    Jan 30, 2004
  2. No One

    Scoping of components

    No One, Oct 23, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    345
    Kevin Spencer
    Oct 25, 2004
  3. walterbyrd
    Replies:
    16
    Views:
    464
    Steven D'Aprano
    Dec 18, 2008
  4. Elf M. Sternberg
    Replies:
    15
    Views:
    257
    Matthias Reitinger
    Jul 29, 2009
  5. Chris Gernon
    Replies:
    1
    Views:
    105
Loading...

Share This Page