Rails 关于 Rails 源码中的 Rails::Initializable::Initializer#bind 方法,有个疑问请教

daqing · 2015年08月02日 · 最后由 lmorenbit 回复于 2015年08月02日 · 1761 次阅读

最近尝试阅读 Rails 源代码,遇到了一个小疑问,如下:

# railties/lib/rails/initializable.rb

class Initializer
  attr_reader :name, :block

  def initialize(name, context, options, &block)
    options[:group] ||= :default
    @name, @context, @options, @block = name, context, options, block
  end

  def before
    @options[:before]
  end

  def after
    @options[:after]
  end

  def belongs_to?(group)
    @options[:group] == group || @options[:group] == :all
  end

  def run(*args)
    @context.instance_exec(*args, &block)
  end

  def bind(context)
    return self if @context
    # 疑问: 这里为什么不直接设置 `@context = context`,而是要创建新对象呢?
    Initializer.new(@name, context, @options, &block)
  end
end

有没有同学指点一下呢?

这个是做什么的,是 config 下的那个初始化么?

我猜是因为 每次bind生成一个新的对象可以做到一套Initializer配置可以被bind多次,供不同的context复用。

不过只看railties下的代码也没有发现某个Initializerbind多次……

Ruby 把对象传递给方法,是对该对象的引用。bind 是为了不修改原来的对象。同样的效果当然可以把 name context option block 都传进来,重新创建一个新对象。,至于为什么这样,单独这么看意义不大,可以看看它的使用场景。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号