无法获取对象方法来调用其他对象方法

时间:2015-05-23 11:34:23

标签: ruby

我已经构建了一个实现对象类和方法创建的程序。我是个菜鸟。这是我的代码:

    class Orange_Tree

    def initialize 
        @age = 0 
        @height = 0.3 
        @yield = 0 

        puts "The orange seed you planted has grown into a sapling, what will you call it?"
        @name = gets.chomp
        puts @name + "?!?  What a glorious name!  I see great things in this sprout's future."
        puts @height
    end

        # Creates instance variables of this object upon creation.
        # Prompts user for input and assigns answer to @name.

    def talk
        puts "You spend a little time each day talking to " + @name +".     "
        @height += @height * 1.5
        if @yield == 0
            if ((@height >= 1) and (@height < 3))
                @yield +=  2
            elsif ((@height >= 3) and (@height < 7))
                @yield +=  5
            elsif @height >= 7 
                @yield += 10
            else 
            end

            puts "Well that certainly helped!  Even if your neighbours did think you were crazy.  Here we are 1 year later and " + @name.to_s + " is now " + @height.to_s + " metres tall and now has " + @yield.to_s + " oranges."
        else
            puts @name + "'s produced all their fruit for this year."
        end
    end

        #Method for helping the tree grow.
        # Multiplies height by a factor of 1.5.
        # Increases yield by continually greater number relative to the @height instance variable.
        #Updates user with a string including new values of instance variables.

    def sing 
        puts "You serenade " + @name + " once a day."
        @height += @height * 2
        if @yield == 0
            if ((@height >= 1) and (@height < 3))
                @yield +=  4
            elsif ((@height >= 3) and (@height < 7))
                @yield += 10
            elsif @height >= 7
                @yield += 20
            else
            end

            puts "That's the trick.  I've never seen such growth!  Here we are 1 year later and " + @name.to_s + " is now " + @height.to_s + " metres tall and now has " + @yield.to_s + " oranges." 
        else
            puts @name + "'s produced all their fruit for this year."
        end
    end

        # Similar to talk method above.

    def eat oranges
        if @yield >= oranges.to_i
            puts "You can't take it any longer.  Those oranges look too delicious"
            @yield -= oranges
            puts "Mmmm....tasty."
        else 
            puts "There aren't enough oranges."
        end
    end

        # Method which allows user to eat their chosen number of oranges, if there are enough.

    def count
        puts "There are " + @yield.to_s + " oranges."
    end

        # Allows user to check the number of oranges.

    def too_old

        if @height > 150
                puts "There comes a time in person's life when you have to let go of childish fancies such as orange trees.  That time has sadly come.  Many good times were had and oranges ate.  Fairwell dear " + @name + ".  We'll never forget you."

                exit
        else
        end
    end

    # This method is called by the pass_time method.
    # If the if statement evaluates to true the user is shown message and the program ends.


    def pass_time
        @age += 1
        @yield = 0
        Orange_Tree.too_old
    end

        # Method which increases @age 1 year per call and ends the program when @age increases past 10.
        # Each year that passes resets @yield to 0.

end

tree = Orange_Tree.new
tree.talk
tree.count
tree.eat 1
tree.pass_time
tree.sing 
tree.eat 1
tree.count
tree.pass_time
tree.talk
tree.count
tree.eat 1
tree.pass_time
tree.sing 
tree.eat 1
tree.count
tree.pass_time
tree.talk
tree.count
tree.eat 1
tree.pass_time
tree.sing 
tree.eat 1
tree.count
tree.pass_time
tree.sing

当跑步时给出:

orange_tree.rb:97:in `pass_time': undefined method `too_old' for Orange_Tree:Class (NoMethodError)
    from orange_tree.rb:109:in `<main>'

在这里做了一些搜索后,我想我知道问题是什么。我已经定义了&#34; too_old&#34;方法作为实例方法,它需要是我的程序按需工作的类方法(每当调用&#34; pass_time&#34;方法时,它调用&#34;太旧&#34;方法。)

所以我改变了#34; too_old&#34;方法:

def self.too_old

    if @height > 150
            puts "There comes a time in person's life when you have to let go of childish fancies such as orange trees.  That time has sadly come.  Many good times were had and oranges ate.  Fairwell dear " + @name + ".  We'll never forget you."

            exit
    else
    end
end

哪位给了我:

orange_tree.rb:82:in `too_old': undefined method `>' for nil:NilClass (NoMethodError)
from orange_tree.rb:97:in `pass_time'
from orange_tree.rb:109:in `<main>'

所以现在我被卡住了。我非常感谢你的帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

too_old是类Orange_tree上的实例方法。这意味着您必须在Orange_tree的实例上调用它。在原始代码中,您在整个类Orange_tree上调用它

试试这个:

def pass_time
    @age += 1
    @yield = 0
    self.too_old
end

对pass_time方法的一次修改允许程序在没有错误的情况下运行。

答案 1 :(得分:0)

问题是当你调用Orange_Tree.too_old方法时,你永远不会创建一个真正的Orange_Tree类实例。如果不创建实例,则永远不会调用类初始化方法(调用Orange_Tree.new时将调用initialize)。在你的情况下,initialize方法会将@height变量初始化为0.3,但是因为它从未发生过,所以@height为零,这就是你得到undefined method&gt;'的原因。对于nil:NilClass(NoMethodError)`

我的建议是使用普通def self.too_old方法替换def too_old方法,并在pass_time方法中创建Orange_Tree的新实例

总结:

def pass_time
  @age += 1
  @yield = 0
  Orange_Tree.new.too_old
end

P.S。 在ruby中,我们将类命名为OrangeTree而不是Orange_Tree(约定)