代码之家  ›  专栏  ›  技术社区  ›  mikewilliamson

Rails 3:别名\u方法\u链是否仍在使用?

  •  34
  • mikewilliamson  · 技术社区  · 15 年前

    我刚刚读到了关于Gems/Plugin在rails3上的开发的文章,就遇到了 this post 也就是说不再使用别名\方法\链。我可以在activesupport-3.0.0/lib/active\u support/core\u ext/module中看到这个方法仍然存在/别名.rb.

    在Rails 3中,我应该仍然使用别名\u方法\u链吗?

    this 还反映了Rails3中想要修改ActiveRecord的gems/插件的最佳实践吗?

    3 回复  |  直到 15 年前
        1
  •  57
  •   Community Mohan Dere    9 年前

    不,它已经被在模块和 super

    基本上,您在一个包含的模块中定义原始函数,并在另一个包含的模块中重写它。当你打电话的时候 超级的 在重写函数中,它调用原始函数。但有一个问题。必须包含扩展模块 包括基本模块,并按您希望的顺序进行链接。

    class Something
      module Base  
        def my_method
          # (A) original functionality
        end
      end
    
      module PreExtension
        def my_method
          # (B) before the original
          super # calls whatever was my_method before this definition was made
        end
      end
    
      module PostExtension
        def my_method
          super # calls whatever was my_method before this definition was made
          # (C) after the original
        end
      end
    
      include Base # this is needed to place the base methods in the inheritance stack
      include PreExtension # this will override the original my_method
      include PostExtension # this will override my_method defined in PreExtension
    end
    
    s = Something.new
    s.my_method 
    #=> this is a twice extended method call that will execute code in this order:
    #=> (B) before the original
    #=> (A) the original
    #=> (C) after the original
    

    瑞安贝茨 Railscasts 谈论 how this is used in the Rails Routing code

    附言:功劳归于 Peeja

        2
  •  19
  •   Peeja    15 年前

    通常,模块永远不能重写类中的方法 它包含在。这是因为模块包含只起作用 比如子类化。超类不能重写其子类的 方法,也不是你所期望的。

    当一个模块包含在一个类中时,就会插入该模块 super 模块 的实现。

    class Something
      module PreExtension; end
      module PostExtension; end
    
      include PreExtension
      include PostExtension
    end
    
    Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
    

    无论何时对 Something 此列表按顺序排列并调用它找到的第一个实现。 如果实现需要 ,它一直在寻找

    这意味着后面包含的模块优先于 超级的 模块的实现。这是因为包含的模块 插入祖先链 紧接着 是edgerunner提到的路由代码的工作原理。那个密码 把所有东西都放在模块里,就像这样:

    class SomethingNew
      module Base
        def my_method
          puts "(A)"
        end
      end
    
      module Extension
        def my_method
          puts "(B)"
          super
        end
      end
    
      include Base
      include Extension
    end
    
    SomethingNew.new.my_method
    # Output:
    # >> (B)
    # >> (A)
    
    SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
    

    这就是为什么 alias_method_chain 一开始就存在。如果将基本代码放在模块中不是一个选项,那么我不知道如何实现 别名\u方法\u链 .

        3
  •  0
  •   Vikrant Chaudhary    14 年前

    我看到了 alias_method_chain http://api.rubyonrails.org/ 不上报 rails console 报告说是 undefined local variable or method .

    另请参见- https://rails.lighthouseapp.com/projects/8994/tickets/285-alias_method_chain-limits-extensibility#ticket-285-20

    别名\u方法\u链

    推荐文章