簡體   English   中英

繼承類中的ruby method_alias

[英]ruby method_alias in inherited class

我正在深入研究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使用兩次時會導致錯誤。 解決此類問題的最佳方法是什么? 如何確定是否存在混合並在新混合之前將其刪除

遵循方法的定義以了解為什么會發生這種情況。

首先定義Example1::example中的類定義Example1 它將字符串寫入控制台。

然后,擴展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刪除不再需要定義的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM