如何在Ruby的子类中对动态定义的方法调用super?

如何在Ruby的子类中对动态定义的方法调用super?,ruby,exception,metaprogramming,Ruby,Exception,Metaprogramming,我有一个元编程场景,它涉及到Ruby的一些更好的特性,我不太确定如何解决这些特性 每个人都可以轻松地编写下面的示例来完成它应该做的事情,但是我需要在超类和派生子类中动态地定义方法 在这个示例中,基类有一个动态定义的方法:foo和of cource,它向子类B公开。 然而,当我在动态定义的方法中检测到子类B的实例上调用:foo时,我似乎无法将它从B类实例传递到我想要的a类实例 wierd ruby在子类中也像这样定义了方法,但无论如何,这就是我要解决的问题 有什么线索吗 class A def

我有一个元编程场景,它涉及到Ruby的一些更好的特性,我不太确定如何解决这些特性

每个人都可以轻松地编写下面的示例来完成它应该做的事情,但是我需要在超类和派生子类中动态地定义方法

在这个示例中,基类有一个动态定义的方法:foo和of cource,它向子类B公开。 然而,当我在动态定义的方法中检测到子类B的实例上调用:foo时,我似乎无法将它从B类实例传递到我想要的a类实例

wierd ruby在子类中也像这样定义了方法,但无论如何,这就是我要解决的问题

有什么线索吗

class A
  def self.some_method method,*_params
    puts "#{name}: defining #{method}"
    define_method method do |*args|
      puts "#{self.class.name}: called #{method}"
      super *args unless self.class.instance_methods(false).include?(method)
    end
  end
end

class B < A
end

A.some_method :foo

B.new.foo
A类
def self.some_方法,*_参数
放置“#{name}:定义#{method}”
定义_方法do |*args|
放置“#{self.class.name}:调用#{method}”
super*args,除非self.class.instance_方法(false)。include?(方法)
结束
结束
结束
B类
输出

A: defining foo
B: called foo
NoMethodError: super: no superclass method `foo' for #<B:0x007f9eab85bfa0>
A: defining foo
B: called foo
A: has method foo
A:定义foo
B:叫福
NoMethodError:super:没有超类方法“foo”#

我认为你的逻辑有缺陷

将动态方法定义到超类
A
。调用
B.new.foo
B
中找不到任何方法,因此它会上升到继承行。它在
A
中找到
foo
方法,因此使用该方法。
这意味着

super*参数,除非self.class.instance\u方法(false)。include?(方法)

零件根本不需要


在我看来,经典方法继承就是你所需要的一切

我认为你的逻辑有缺陷

将动态方法定义到超类
A
。调用
B.new.foo
B
中找不到任何方法,因此它会上升到继承行。它在
A
中找到
foo
方法,因此使用该方法。
这意味着

super*参数,除非self.class.instance\u方法(false)。include?(方法)

零件根本不需要


在我看来,经典方法继承就是你所需要的一切

我认为你的逻辑有缺陷

将动态方法定义到超类
A
。调用
B.new.foo
B
中找不到任何方法,因此它会上升到继承行。它在
A
中找到
foo
方法,因此使用该方法。
这意味着

super*参数,除非self.class.instance\u方法(false)。include?(方法)

零件根本不需要


在我看来,经典方法继承就是你所需要的一切

我认为你的逻辑有缺陷

将动态方法定义到超类
A
。调用
B.new.foo
B
中找不到任何方法,因此它会上升到继承行。它在
A
中找到
foo
方法,因此使用该方法。
这意味着

super*参数,除非self.class.instance\u方法(false)。include?(方法)

零件根本不需要


在我看来,经典方法继承就是你所需要的一切

逻辑确实有缺陷。当然,需要在何处访问已定义了方法的类,而super在这方面帮不了你

以下是问题的解决方案:

class A
  def self.some_method method,*_params
    puts "#{name}: defining #{method}"
    define_method method do |*args|
      puts "#{self.class.name}: called #{method}"

      klass = self.class
      klass = klass.superclass while !klass.instance_methods(false).include?(method)

      # klass is now where the instance method is defined
      # and you can now access its class variables etc.
      puts "#{klass.name}: has method #{method}"
    end
  end
end

class B < A
end

A.some_method :foo

B.new.foo

这一逻辑确实存在缺陷。当然,需要在何处访问已定义了方法的类,而super在这方面帮不了你

以下是问题的解决方案:

class A
  def self.some_method method,*_params
    puts "#{name}: defining #{method}"
    define_method method do |*args|
      puts "#{self.class.name}: called #{method}"

      klass = self.class
      klass = klass.superclass while !klass.instance_methods(false).include?(method)

      # klass is now where the instance method is defined
      # and you can now access its class variables etc.
      puts "#{klass.name}: has method #{method}"
    end
  end
end

class B < A
end

A.some_method :foo

B.new.foo

这一逻辑确实存在缺陷。当然,需要在何处访问已定义了方法的类,而super在这方面帮不了你

以下是问题的解决方案:

class A
  def self.some_method method,*_params
    puts "#{name}: defining #{method}"
    define_method method do |*args|
      puts "#{self.class.name}: called #{method}"

      klass = self.class
      klass = klass.superclass while !klass.instance_methods(false).include?(method)

      # klass is now where the instance method is defined
      # and you can now access its class variables etc.
      puts "#{klass.name}: has method #{method}"
    end
  end
end

class B < A
end

A.some_method :foo

B.new.foo

这一逻辑确实存在缺陷。当然,需要在何处访问已定义了方法的类,而super在这方面帮不了你

以下是问题的解决方案:

class A
  def self.some_method method,*_params
    puts "#{name}: defining #{method}"
    define_method method do |*args|
      puts "#{self.class.name}: called #{method}"

      klass = self.class
      klass = klass.superclass while !klass.instance_methods(false).include?(method)

      # klass is now where the instance method is defined
      # and you can now access its class variables etc.
      puts "#{klass.name}: has method #{method}"
    end
  end
end

class B < A
end

A.some_method :foo

B.new.foo

顺便说一句:我试图避免方法_缺失。顺便说一句:我试图避免方法_缺失。顺便说一句:我试图避免方法_缺失。顺便说一句:我试图避免方法_缺失。这一点输入足以让我意识到我的需要是知道什么类定义了访问超类类变量的方法,这很容易做到:current=self.class;current=current.superclass while!current.instance_方法(false).include?(方法),因此感谢您轻推我的大理石!我明白了。。。您是否考虑过为共享方法而不是类继承包含一个特殊模块?它可能会被证明是一种更灵活的做事方式。是的,但我有一个相当细粒度的需求。(只要看一眼可可宝石,你就会知道)。正如我们所说的,重新定义体系结构。这一点输入足以让我意识到我的需要是知道什么类定义了访问超类类变量的方法,这可以很容易地用:current=self.class;current=current.superclass while!current.instance_方法(false).include?(方法),因此感谢您轻推我的大理石!我明白了。。。您是否考虑过为共享方法而不是类继承包含一个特殊模块?它可能会被证明是一种更灵活的做事方式。是的,但我有一个相当细粒度的需求。(只要看一眼可可宝石,你就会知道)。正如我们所说的,重新定义体系结构。这一点输入足以让我意识到我的需要是知道什么类定义了访问超类类变量的方法,这可以很容易地用:current=self.class;current=current.superclass while!current.instance_方法(false).include?(方法),因此感谢您轻推我的大理石!我明白了。。。您是否考虑过为共享方法而不是类继承包含一个特殊模块?这可能是一种更灵活的方式