【问题标题】:An unexpected result was encountered when invoking the instance_methods method, resulted in the return of an empty array调用 instance_methods 方法时遇到意外结果,导致返回空数组
【发布时间】:2023-02-11 02:44:41
【问题描述】:

请考虑以下代码

class Execute
  def self.inherited(klass)
    puts "Class Inherited: #{klass}"
    klass.run
  end

  def self.run
    puts "Running Instance Methods"
    instance_methods(false).each do |m|
      if m.to_s.start_with?("test_")
        puts "Executing Method: #{m}"
        new.send(m)
      end
    end
  end
end

puts "Before class definition"

class Raja < Execute
  def test_1
    puts 'test_1'
  end

  def test_2
    puts 'test_2'
  end

  def test_3
    puts 'test_3'
  end
end

puts "After class definition"

我目前正在尝试通过实例化父类中的对象来访问 test_1、test_2 和 test_3 方法。检查程序后,可以理解我正在执行的操作。尽管如此,问题还是出现了,因为调用 instance_methods 方法会返回一个空数组,这与其提供实例方法名称(即 test_1、test_2 和 test_3)的预期行为相反。我不知道为什么会出现这种差异,非常感谢为解决此问题提供的任何帮助

【问题讨论】:

    标签: ruby


    【解决方案1】:

    Class#inherited在继承的时候被调用。 此时没有定义instance_methods(非继承的实例方法,因为你使用了false)。

    class Raja < Execute #inherited is called here 
     # methods are defined here
    end
    

    它将类似于以下内容

    class Raja;end 
    Raja.instance_methods(false) #=> []
    class Raja
      def test_1 = 'test1'
    end 
    Raja.instance_methods(false) #=> [:test_1]
    

    这是有充分理由的。举个例子

    module B 
      def hello = 'hi'
    end 
    
    class A 
      def self.inherited(klass) 
        klass.include(B) 
      end 
    end 
    
    class C < A 
      def hello = 'hello'
    end 
    

    在这种情况下,如果 inherited 在类主体 C#hello 之后触发,将被 B#hello 覆盖,就好像 B 被添加到 C 之前。

    您可以改为查看Module#method_added,但是我不清楚这段代码背后的原因是什么,所以我所能做的就是回答以下问题为什么你正在经历你正在经历的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多