【问题标题】:Get list of a class' instance methods获取类的实例方法列表
【发布时间】:2011-09-22 00:49:35
【问题描述】:

我有一堂课:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

如何获取我在这个类中的方法列表(method1method2method3)?

【问题讨论】:

    标签: ruby reflection ruby-1.9.2


    【解决方案1】:

    您实际上想要TestClass.instance_methods,除非您对TestClass 本身的功能感兴趣。

    class TestClass
      def method1
      end
    
      def method2
      end
    
      def method3
      end
    end
    
    TestClass.methods.grep(/method1/) # => []
    TestClass.instance_methods.grep(/method1/) # => ["method1"]
    TestClass.methods.grep(/new/) # => ["new"]
    

    或者你可以在对象上调用methods(不是instance_methods):

    test_object = TestClass.new
    test_object.methods.grep(/method1/) # => ["method1"]
    

    【讨论】:

    • 嘿,你比我快 47 秒。 +1
    • 当我尝试print TestClass.new.instance_methods 时,我收到此错误my_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
    • 你只需要TestClass.new.methods。也许“它”在我的回答中含糊不清。
    • 请注意,在 Ruby 1.9+ 下,方法名称数组是符号,而不是字符串。
    • @Phrogz:是的,但是您可以在它们上使用正则表达式。你甚至都不召唤克苏鲁! :) 虽然你会得到[:method1]
    【解决方案2】:
    TestClass.methods(false) 
    

    只获取属于该类的方法。

    TestClass.instance_methods(false) 将返回给定示例中的方法(因为它们是 TestClass 的实例方法)。

    【讨论】:

    • 这是测试一个类是否具有来自伪接口/抽象基类的多态方法的好方法,而无需尝试直接调用这些方法。
    • 接受的答案很棒,但这个答案可能是更多人会来这里的原因!
    • 这绝对应该是公认的答案。谢谢!
    • @Aaron:我非常怀疑这一点,因为这个答案是错误的Object#methods 返回您可以在 object调用 的方法。您可以在对象上调用哪些方法?在其 class 中定义的那些。这意味着TestClass.methods 返回您可以在TestClass调用 的方法列表,这些方法是在其类中定义的。 TestClass 的班级是什么?它是Class。因此,TestClass.methods 为您提供了在Class 中定义的方法,而不是在TestClass 中定义的方法。不知道这个答案是如何得到 116 票的,当有人甚至
    • ……最遥远的传递知识会立即识别它是错误的。或者,你知道,只要复制粘贴这段代码并运行它就会发现它是错误的。
    【解决方案3】:
    TestClass.instance_methods
    

    或者没有所有继承的方法

    TestClass.instance_methods - Object.methods
    

    (是'TestClass.methods - Object.methods')

    【讨论】:

    • 或没有继承方法:TestClass.methods(false).
    • @sawa TestClass.methods(false) 返回空
    • 这个答案是错误的;结果将不包括method1method2method3,因为它们是类的instances 方法,而不是TestClass 对象本身的方法。
    • @Phrogz:哎呀......是的,'TestClass.instance_methods - Object.methods',或'TestClass.new.methods - Object.methods'......这会教我不开火了一个控制台。我最好删除这个答案,还是编辑它?
    • @Pavling 绝对编辑你的答案是正确的。 (很快,在 OP 将功劳分配给其他人之前!:)
    【解决方案4】:
    $ irb --simple-prompt
    
    class TestClass
      def method1
      end
    
      def method2
      end
    
      def method3
      end
    end
    
    tc_list = TestClass.instance_methods(false)
    #[:method1, :method2, :method3]
    puts tc_list
    #method1
    #method2
    #method3
    

    【讨论】:

      【解决方案5】:

      您可以使用 debugginglooksee 等 gem 获得更详细的列表(例如,通过定义类进行结构化)。

      【讨论】:

        【解决方案6】:

        根据 Ruby 文档instance_methods

        返回一个包含公共和受保护名称的数组 接收器中的实例方法。对于一个模块,这些是公共的 和受保护的方法;对于一个类,它们是实例(不是 单例)方法。如果可选参数为 false,则 不包括任何祖先。 我以官方文档为例。

        module A
          def method1()  
            puts "method1 say hi"
          end
        end
        class B
          include A #mixin
          def method2()  
             puts "method2 say hi"
          end
        end
        class C < B #inheritance
          def method3() 
             puts "method3 say hi"
          end
        end
        

        让我们看看输出。

        A.instance_methods(false)
          => [:method1]
        
        A.instance_methods
          => [:method1]
        B.instance_methods
         => [:method2, :method1, :nil?, :===, ...# ] # methods inherited from parent class, most important :method1 is also visible because we mix module A in class B
        
        B.instance_methods(false)
          => [:method2]
        C.instance_methods
          => [:method3, :method2, :method1, :nil?, :===, ...#] # same as above
        C.instance_methods(false)
         => [:method3]
        

        【讨论】:

          【解决方案7】:

          只获取自己的方法,排除继承的方法:

          从实例内部:

          self.methods - self.class.superclass.instance_methods
          

          从外面:

          TestClass.instance_methods - TestClass.superclass.instance_methods
          

          将其添加到类中:

          class TestClass
            class << self
              def own_methods
                self.instance_methods - self.superclass.instance_methods
              end
            end
          end
          
          TestClass.own_methods
          => [:method1, :method2, :method3]
          

          (使用 ruby​​ 2.6.x)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-01-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-06
            • 2010-11-19
            相关资源
            最近更新 更多