【问题标题】:Undefined method error when the method is called within 'main' method in Ruby?在Ruby的'main'方法中调用方法时出现未定义的方法错误?
【发布时间】:2011-10-06 07:31:00
【问题描述】:

我想知道是否可以在 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 必须在课堂上使用。对吧?

我怎样才能解决这个问题,使方法调用不会产生错误?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    如果您像在第一个示例中那样定义该方法,它是一个实例方法而不是类方法,这就是您不能调用它的原因 - 因为您没有实例可以调用它。但是如果你把它变成一个类方法,通过在方法名称前面加上self.,它就会起作用:

    class Client
        def self.printtwo
            puts 2
        end
    
        printtwo
    end
    

    但我的印象是,您可能想多考虑一下自己在做什么。您很少需要在类声明中运行这样的代码(除非,比如说,您正在以编程方式定义一堆函数或实例变量)。你应该多看看attr_accessor - 通常你只需要这样的东西:

    class Client
        attr_accessor :ivar_one
        attr_accessor :ivar_two
    end
    

    希望这会有所帮助!

    【讨论】:

    • 那么,def self.method_name 是否类似于 Java 中的私有方法,因为它只能在类内部调用?
    • @user482594 - 实际上(或多或少)等价于static;这意味着您调用MyClass.method 而不是instance_of_myclass.method。它不会影响可访问性。
    【解决方案2】:

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

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

    def self.printtwo
       # code
    end
    

    http://repl.it/Bax/1

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

    【讨论】:

      【解决方案3】:

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

      class Client
        def printtwo
           puts 2
        end
      end
      
      if __FILE__ == $0
        Client.new.printtwo
      end
      

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

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

      【讨论】:

        【解决方案4】:

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

        您可以尝试将方法设为静态(通过使用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.

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-15
          相关资源
          最近更新 更多