• #32 楼 @springwq 楼主,我非常想入手你那款,但不知道从哪里购入 请问楼主哪里购入的~ 谢谢!

  • 理解 ActiveSupport::Concern at 2016年07月18日
    module M
      def self.included(base)
        base.extend ClassMethods
        base.class_eval do
          scope :disabled, -> { where(disabled: true) }
        end
    
        include InstanceMethods
     # include InstanceMethods shoule be base.include InstanceMethods
      end
    
      module ClassMethods
        def say_hello
          puts "say hello"
        end
      end
    
      module InstanceMethods
        def say_no
          puts "say no"
        end
      end
    end
    
    
    
  • 元编程代码的解释 at 2016年04月28日

    我认为 each_setup 这个方法难理解的就在于它接收一个代码块,在代码块中又有代码块执行,分两步就可以搞清楚关系了。 举例说明:

    lambda_1 = ->(setup) {setup.call}  #这是一个可调用对象,它接收另外一个可调用对象作为参数
    lambda_1.call("hehe") # 报错,因为参数不是可调用对象
    lambda_1.call(Proc.new {puts "hehe"}) #=> hehe
    

    回到书中的实例代码,在调用 each_setup 的时候挂载了一个代码块,

    each_setup do |setup|
      setup.call
    end
    #这里的setup.call不就相当于上面例子中的setup.call 嘛
    #回到定义中,block.call(setup) 等价于
    #proc_1 = ->(hehe) {hehe.call}
    #proc_1.call(setup) 这里的setup会替换上一行中的hehe,也就是最后执行的是setup可调用对象
    
  • 我的理解就是当一个 Speaker 的实例对象调用类 Speaker 中的 speak 方法时,根据 Ruby 的 Method lookup 机制, 先寻找到的是 action_module 中的 speak 方法。 因为我们之前在 action_module 中通过 define_method,动态的定义了一个 speak 方法,这个方法的实现就在代码块中。

    send :define_method, options[:for] do |*args, &block|
      send method_name
      super(*args, &block)
    end
    

    所以先去调用 method_name 指代的方法,然后携带参数 (如果有的话),继续调用继承链上一级也就是类 Speaker 的 speak 方法。 这样就实现了 before_action 机制。

    觉得 Ruby 真是自带鸡汤 before_action 这一段代码信息量不小。