zoukankan      html  css  js  c++  java
  • rails delegate机制

    Delegate是一种应用composite来代替extend的机制,可以有效地降低代码的耦合性。

    Rails 2.2增加了delegate方法,可以十分方便地实现delegate机制。

    01.def delegate(*methods)  
    02.  options = methods.pop  
    03.  unless options.is_a?(Hash) && to = options[:to]  
    04.    raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
    05.  end
    06.   
    07.  if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/  
    08.    raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
    09.  end
    10.   
    11.  prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
    12.  
    13.  methods.each do |method|  
    14.    module_eval(<<-EOS, "(__DELEGATION__)", 1)  
    15.      def #{prefix}#{method}(*args, &block)  
    16.        #{to}.__send__(#{method.inspect}, *args, &block)  
    17.      end
    18.    EOS
    19.  end
    20.end

    delegate方法首先检查传入的参数,正确参数形式为:method1, :method2, ..., :methodN, :to => klass[, :prefix => prefix]

    delegate要求参数的最后必须是一个Hash,:to表示需要代理的类,:prefix表示代理的方法是否要加前缀,如果:prefix => true,则代理的方法名为klass_method1,

    klass_method2, ..., klass_methodN,如果:prefix => prefix (prefix为string),则代理的方法名为prefix_method1, prefix_method2, ..., prefix_methodN。

    最终通过module_eval动态生成每个方法定义。通过__send__方法调用:to类的方法。

    来看看调用的例子:

    简单的调用:

    01.class Greeter < ActiveRecord::Base  
    02.  def hello()   "hello"  end
    03.  def goodbye() "goodbye" end
    04.end
    05.   
    06.class Foo < ActiveRecord::Base  
    07.  delegate :hello, :goodbye, :to => :greeter
    08.end
    09.   
    10.Foo.new.hello   # => "hello"  
    11.Foo.new.goodbye # => "goodbye"

    增加:prefix => true:

    1.class Foo < ActiveRecord::Base  
    2.  delegate :hello, :goodbye, :to => :greeter, :prefix => true
    3.end
    4.   
    5.Foo.new.greeter_hello   # => "hello"  
    6.Foo.new.greeter_goodbye # => "goodbye"  

    自定义前缀名:

    1.class Foo < ActiveRecord::Base  
    2.  delegate :hello, :goodbye, :to => :greeter, :prefix => :foo
    3.end
    4.  
    5.Foo.new.foo_hello   # => "hello"  
    6.Foo.new.foo_goodbye # => "goodbye" 

    ruby的动态性再一次发挥了强大的功能!

    转自:http://www.cnblogs.com/orez88/articles/1717438.html

  • 相关阅读:
    【转】聚集索引和非聚集索引的区别
    【转】【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式,并把SQLite的数据库文件存储在SD卡中!!!
    【转】数据库范式(1NF 2NF 3NF BCNF)详解一
    【转】数据库 无损连接分解
    如何防止被路由器限速如何更改电脑网卡的MAC地址
    BZOJ 1497 最大权闭合图
    POJ 1966 无向图点联通度 最小割
    POJ 1815 最小割
    POJ 2987 最大权闭合图
    POJ 2391 floyd+二分+最大流
  • 原文地址:https://www.cnblogs.com/gdpdroid/p/6846188.html
Copyright © 2011-2022 走看看