继承类中的ruby method_alias

标签 ruby metaprogramming alias-method class-eval

我正在深入研究 ruby​​ 元编程并有下一个问题。 示例:

module ExampleAliaser
  def do_example_alias(prefix=:origin)

    class_eval  <<-EOS
       class << self 
           alias_method :#{prefix}_example, :example
           def example
              puts "in aliase will call :#{prefix}_example"
              #{prefix}_example
           end  
        end
    EOS

  end   
end  

class Example1
 def self.example
    puts "Example"
 end 
end


Example1.extend(ExampleAliaser)

class Example1 
 do_example_alias(:origin)
end
class Example2 <  Example1
 do_example_alias(:origin)
end



     Example1.example
    in aliase will call :origin_example
    Example
     => nil 

     Example2.example
in aliase will call :origin_example
in aliase will call :origin_example
in aliase will call :origin_example
    SystemStackError: stack level too deep
        from /Users/igorfedoronchuk/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/irb/workspace.rb:80
    Maybe IRB bug!!

所以当 mixin 使用 2 次时会导致错误。 解决此类问题的最佳方法是什么?如何确定混合存在并在新的混合之前将其去除

最佳答案

遵循方法的定义,看看为什么会这样。

您首先在 Example1 的类定义中定义 Example1::example。它向控制台写入一个字符串。

然后扩展 ExampleAliaser。当您调用 Example1::do_example_alias 时,您将方法 example 别名为 origin_example 并将方法 example 重新定义为将不同的字符串写入控制台并调用 origin_example

然后定义继承自 Example1 的类 Example2,它现在定义了两个方法:origin_exampleexample 。当您调用 Example2::do_example_alias 时,您将方法 example 别名为 origin_example。但请记住,example 已被重新定义为调用 origin_example。如此有效,Example2::example 将调用自身,直到堆栈空间用完。


如果你想避免双重别名,你可以在 do_example_alias 中包含某种守卫:

def do_example_alias(prefix = :origin)
  unless methods.include?("#{prefix}_example")
    # do the aliasing
  end
end

您还可以在子类中undef :method_name 来删除您不再希望定义的方法。

关于继承类中的ruby method_alias,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9430755/

相关文章:

Ruby 并行排序

macros - 使用 Lisp 宏创建类似的函数

javascript - 以编程方式获取在 javascript 中起作用的局部变量值?

ruby - 包含模块时 __callee__ 的意外值——这是 Ruby 错误吗?

ruby-on-rails - alias_method、alias_method_chain 和 self.included

javascript - 同一 link_to 助手的不同行为 - 模板丢失

ruby-on-rails - 为什么rails会在controller中生成对象实例变量

ruby - Hadoop环境变量

ruby-on-rails - Ruby 2.0 如何在包含模块后从模块中取消包含模块?