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

  • 理解 ActiveSupport::Concern at 2016年7月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年4月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 这一段代码信息量不小。