Ruby Can';t get object方法调用其他对象方法

Ruby Can';t get object方法调用其他对象方法,ruby,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 =

我已经建立了一个程序来练习对象类和方法的创建。我是个笨蛋。这是我的密码:

    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: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>'
orange\u tree.rb:82:in'too\u old':nil:NilClass(NoMethodError)的未定义方法“>”
来自橘子树。rb:97:in'pass\u time'
来自橘子树。rb:109:in`'

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

问题是当您调用Orange_Tree时。太旧的方法,您永远不会创建Orange_Tree类的真实实例。当您不创建实例时,您永远不会调用类初始化方法(当您调用
Orange\u Tree.new
时将调用initialize)。在您的例子中,initialize方法会将@height变量初始化为0.3,但由于它从未发生,@height是nil,这就是为什么您得到nil:NilClass(NoMethodError)的
未定义的方法`

我的建议是将
def self.too_old
方法替换为普通
def too_old
方法,并在
pass_time
方法中创建
Orange_树的新实例

总而言之:

def pass_time
  @age += 1
  @yield = 0
  Orange_Tree.new.too_old
end
附言。
在ruby中,我们将类命名为OrangeTree而不是Orange_Tree(约定)

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

试试这个:

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

对pass_time方法的一次修改使您的程序可以毫无错误地运行。

感谢您抽出时间。这个错误与我相信的“传递时间”方法有关。如果您查看第一个代码块的底部,我确实创建了一个Orange_类的实例:tree=Orange_tree.new。程序的其余部分工作正常。这只是因为一旦@age达到某一点,“pass_time”就应该结束程序。这是唯一没有发生的事情。我的意思是说“太旧”的方法应该结束程序。谢谢。对我来说运行时也没有错误,但是程序没有正常运行。“太旧”的方法应该会杀死程序,所以看起来它根本就没有被调用。Alex,不再在家,所以不能再运行它,但只是眼巴巴地看着它,也许在程序结束之前没有足够的增长达到>150的高度?尝试将原始高度设置为120或类似的高度,然后看看是否太旧会导致死亡。或者制作一个控制器,让用户选择操作,然后继续选择操作(如果您想继续开发,这似乎是合乎逻辑的下一步)。Hey Lost,感谢您的回复。根据我运行的@height实例变量为~380的程序的信息,当任何大于150的值都应该退出程序。我将在今晚或明天再次尝试,届时将更新。谢谢你的建议。亚历克斯,对不起。我已经批准了其他用户对我答案的编辑,因为我认为这主要是在我对答案的描述中,而且更完整。不幸的是,我没有在手机上注意到他们也编辑了部分代码,这破坏了解决方案。我最初加入并重新加入的self.too_old似乎很好用。我测试了它,初始高度设置为100,程序以第一次通过时间结束。要调整结束游戏所需的圈数,只需适当设置起始高度。再次为编辑造成的混乱表示歉意。这很奇怪……如果我用我原来帖子中的代码运行程序(包括你的修改),它将无法结束。但是,通过将initialize方法变量@height更改为从151开始,并专门调用“pass_time”一次,程序将按预期结束。到目前为止没有任何意义。不过很有趣。非常感谢你的帮助。现在我知道了如何对实例而不是类调用方法。谢谢。
def pass_time
  @age += 1
  @yield = 0
  Orange_Tree.new.too_old
end
def pass_time
    @age += 1
    @yield = 0
    self.too_old
end