在Ruby中的'main'方法中调用方法时,未定义的方法错误?

时间:2011-10-05 23:03:32

标签: ruby

我想知道是否可以在Ruby中的'main'方法中调用类方法。

以下代码会产生错误。

test.rb

class Client
    def printtwo
        puts 2
    end

    if __FILE__ == $0       #if this file gets run by an interpreter, run below codes
                            #just like main() method in java

        printtwo()           #this throws below error
                            #undefined method `printtwo' for Client:Class (NoMethodError)
    end
end

如果我运行它们,没有类声明的代码运行正常

test2.rb

def printtwo
    puts 2
end

if __FILE__ == $
    printtwo()           #this prints 2
end

我想在类声明中使用这个可执行文件的原因是因为,我想通过设置attr_accessor来使用类变量。我相信这个attr_accessor必须在课堂上使用。正确?

如何解决此问题,以便方法调用不会产生错误?

4 个答案:

答案 0 :(得分:4)

如果像第一个例子中那样定义该方法,那么它是一个实例方法而不是类方法,这就是为什么你不能调用它 - 因为你没有一个实例来调用它。但是如果你把它作为一个类方法,通过将self.添加到方法名称,它将起作用:

class Client
    def self.printtwo
        puts 2
    end

    printtwo
end

但我得到的印象是你可能想要更多地思考你正在做的事情。您很少需要在类声明中运行这样的代码(除非您以编程方式定义一堆函数或实例变量)。你应该再研究一下attr_accessor - 这通常就是你需要的东西:

class Client
    attr_accessor :ivar_one
    attr_accessor :ivar_two
end

希望这有帮助!

答案 1 :(得分:2)

这是因为printtwo是一个实例方法。它可以从Client类中的其他实例方法调用,但由于您在任何其他方法之外调用该方法,它将无法工作。

加载文件时,将读取类,因此在实例化Client类之前调用​​printtwo方法。要像您一样调用printtwo,您必须将其定义为:

def self.printtwo
   # code
end

http://repl.it/Bax/1

请注意,在示例中,我在类中调用了哪个方法,并在外部调用该方法。

答案 2 :(得分:0)

好的,这并不奇怪。如果没有类的实例(在您的示例中就是这种情况),则无法调用方法

您可以尝试将方法设为静态(使用self)它应该可以正常工作。

class Client
    def self.printtwo
        puts 2
    end

    if __FILE__ == $0       #if this file gets run by an interpreter, run below codes
                            #just like main() method in java

        printtwo()           #this throws below error
                            #undefined method `printtwo' for Client:Class (NoMethodError)
    end
end

另请注意,您无法将实例属性(@var)访问到静态类中,因为您没有任何实例。您只能对属性进行分类(@@ var)。

这就是说,您可以随时在对象中设置新的attr_accessor。 Ruby允许你编写代码代码......非常棒的元编程语言。

Here is a question explaining how to do create a attr_accessor through a method.

答案 3 :(得分:0)

除了其他答案之外,我还要补充一点,if __FILE__ == $0内的任何代码通常只会在最后几行,在完成上述所有定义工作后启动程序:

class Client
  def printtwo
     puts 2
  end
end

if __FILE__ == $0
  Client.new.printtwo
end

如果你在每个类定义中出现if __FILE__ == $0条件,那将太难以管理。如果您明确地运行该文件,该代码仅按定义工作,但为了灵活性,您通常希望您编写的任何代码(通过include)可用于程序的其他部分以及其他程序。相反,只需将它保持在文件的主要上下文中的一个位置即可。

此外,除了方法定义和实例/类变量声明之外,在类上下文中运行任何代码并不常见,即使是在进行元编程时,也不一定存在问题,它只是不倾向于在Ruby中大量出现。