undefined method `*' for nil:NilClass (NoMethodError)

Discussion in 'Ruby' started by Dwight Shackelford, Jul 18, 2009.

  1. First off, I'm a student taking Ruby for the first time, so bear with
    me. I've tried doing a web search and a search of this forum, and
    didn't see anything that addressed this specifically.

    on line 18 of the following code (@height = @height * 1.1 in the method
    oneYearPasses), I get the error message that is in the subject line.

    If I take that same line of code and put it up in the area where I'm
    defining variables, there is no error. I'm suspecting something has
    gone amiss in my method definition and the interpreter is getting
    confused.

    If I comment out that line, I get similar messages for my '>' operators
    below that.

    Probably a bump from you folks on that first problem will give me enough
    info to solve the others as they come up. Any help appreciated.
    Thanks.

    class OrangeTree
    @numFruit =0
    MAXAGE = 10
    FIRSTFRUIT = 20
    FIRSTHEIGHT = 3.0
    @age = 0
    @dead = false

    @height = FIRSTHEIGHT

    def getHeight
    return @height
    end

    def oneYearPasses
    if !@dead

    @height = @height * 1.1 #<<<<<<<<<<<< line causing error
    @age++

    if @age >= 3
    @numFruit = (1.2**(age -3)) * FIRSTFRUIT
    end

    if !(@age < MAXAGE)
    @dead = true
    end
    end
    end

    def countTheOranges
    return @numFruit
    end

    def pickAnOrange
    if @numFruit > 0
    @numFruit--
    puts {'That was delicious'}
    else
    puts {'There are no more oranges'}
    end
    end
    end

    myTree = OrangeTree.new
    myTree.oneYearPasses
    myTree.oneYearPasses
    myTree.pickAnOrange
    myTree.getHeight
    --
    Posted via http://www.ruby-forum.com/.
    Dwight Shackelford, Jul 18, 2009
    #1
    1. Advertising

  2. Dwight Shackelford

    Robert Dober Guest

    The problem here is instance variable scope.

    You define instance variables on the class object not the instance.
    Try to find David Black's excellent post some days ago about what he
    thinks is the most important thing for beginners to know, know your
    self. (as says Delphi's oracle already ;)
    In other words know what self is in any moment, let us try to explore
    and you will find it quite simple:

    502/3 > ruby -e 'class A; p self end'
    A

    ok in the class declaration part self is the class A object, now:

    504/5 > ruby -e 'class A; def a; p self end end; A::new.a'
    #<A:0x81babb8>

    Aha, in a method self is an instance object of the class A

    Now let us have a look at how this fits with instance variables

    507/8 > ruby -e 'class A; @a=3D42; end; p A.instance_variable_get( :mad:a
    ); p A::new.instance_variable_get( :mad:a )'
    42
    nil

    ok that explains your error, you @height was nil (an uninitialised
    ivar (1) ) that did not have the method "*"

    Now how can we fix it?

    When Ruby creates a new object with A::new it
    (i) creates a new object with allocate
    (ii) invokes the initialize method with all its own parameters on the
    object from (i)
    (iii) returns the object from (i)

    Thus initialize gives us the self you need ;)

    508/9 > ruby -e 'class A; @a=3D42; def initialize; @a=3D41 end end; p
    A.instance_variable_get( :mad:a ); p A::new.instance_variable_get( :mad:a )'
    42
    41

    I know those one liners are unreadable, thus please refer to:
    http://pastie.org/550502

    All you need to do now, is to define a method called initialize in
    your class and copy
    the ivar initialization code from your class body into the initialize
    method, where self is what you want it to be :)

    HTH
    Robert

    (1) Hint: Running ruby with -w (default in 1.9) might have given you a
    good clue.


    On 7/18/09, Dwight Shackelford <> wrote:
    > First off, I'm a student taking Ruby for the first time, so bear with
    > me. I've tried doing a web search and a search of this forum, and
    > didn't see anything that addressed this specifically.
    >
    > on line 18 of the following code (@height =3D @height * 1.1 in the method
    > oneYearPasses), I get the error message that is in the subject line.
    >
    > If I take that same line of code and put it up in the area where I'm
    > defining variables, there is no error. I'm suspecting something has
    > gone amiss in my method definition and the interpreter is getting
    > confused.
    >
    > If I comment out that line, I get similar messages for my '>' operators
    > below that.
    >
    > Probably a bump from you folks on that first problem will give me enough
    > info to solve the others as they come up. Any help appreciated.
    > Thanks.
    >
    > class OrangeTree
    > @numFruit =3D0
    > MAXAGE =3D 10
    > FIRSTFRUIT =3D 20
    > FIRSTHEIGHT =3D 3.0
    > @age =3D 0
    > @dead =3D false
    >
    > @height =3D FIRSTHEIGHT
    >
    > def getHeight
    > return @height
    > end
    >
    > def oneYearPasses
    > if !@dead
    >
    > @height =3D @height * 1.1 #<<<<<<<<<<<< line causing error
    > @age++
    >
    > if @age >=3D 3
    > @numFruit =3D (1.2**(age -3)) * FIRSTFRUIT
    > end
    >
    > if !(@age < MAXAGE)
    > @dead =3D true
    > end
    > end
    > end
    >
    > def countTheOranges
    > return @numFruit
    > end
    >
    > def pickAnOrange
    > if @numFruit > 0
    > @numFruit--
    > puts {'That was delicious'}
    > else
    > puts {'There are no more oranges'}
    > end
    > end
    > end
    >
    > myTree =3D OrangeTree.new
    > myTree.oneYearPasses
    > myTree.oneYearPasses
    > myTree.pickAnOrange
    > myTree.getHeight
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >



    --=20
    Toutes les grandes personnes ont d=92abord =E9t=E9 des enfants, mais peu
    d=92entre elles s=92en souviennent.

    All adults have been children first, but not many remember.

    [Antoine de Saint-Exup=E9ry]
    Robert Dober, Jul 18, 2009
    #2
    1. Advertising

  3. Hello Dwight,

    > on line 18 of the following code (@height = @height * 1.1 in the method
    > oneYearPasses), I get the error message that is in the subject line.


    As Robert told, you just have to add

    class OrangeTree
    MAXAGE = 10
    FIRSTFRUIT = 20
    FIRSTHEIGHT = 3.0

    def initialize
    @numFruit =0
    @age = 0
    @dead = false
    @height = FIRSTHEIGHT
    end

    ...
    end

    And it will (almost) work. Note that the construct '++' as in @age++
    does not exist in ruby, neither does the construct '--', you will have
    to write explicitly
    @age += 1
    and
    @numFruit -= 1


    Cheers,

    --
    JJ Fleck
    Fleck Jean-Julien, Jul 18, 2009
    #3

  4. >
    > And it will (almost) work. Note that the construct '++' as in @age++
    > does not exist in ruby, neither does the construct '--', you will have
    > to write explicitly
    > @age += 1
    > and
    > @numFruit -= 1
    >
    >
    > Cheers,


    Thank you very much, both of you.

    Yes, I figured I was using other languages mixed in. Studying too many
    languages at the same time, and already know some others. I was just
    going to have the debugger tell me what doesn't work.

    --
    Posted via http://www.ruby-forum.com/.
    Dwight Shackelford, Jul 18, 2009
    #4
    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. Petrucci Fabio
    Replies:
    1
    Views:
    98
    Jim Weirich
    Jul 13, 2004
  2. anon1m0us
    Replies:
    2
    Views:
    209
    anon1m0us
    Feb 6, 2007
  3. Iain Barnett
    Replies:
    2
    Views:
    463
    Iain Barnett
    Jul 20, 2010
  4. Esen Sagynov
    Replies:
    2
    Views:
    246
    Manivannan Jeganathan
    Dec 4, 2010
  5. Replies:
    1
    Views:
    81
    Chris Angelico
    Aug 5, 2013
Loading...

Share This Page