railstutorial来自哪里的调试信息

DCR*_*DCR 11 ruby ruby-on-rails railstutorial.org

在第7章中,我得到了以下输出

--- !ruby/hash-with-ivars:ActionController::Parameters
elements:
  controller: static_pages
  action: home
ivars:
  :@permitted: false
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下hash-with-ivars来自哪里以及ivars:@permitted:false意味着什么?

Bor*_*aMa 22

有趣的问题!我搜索了一个rails项目的所有库源代码,'hash-with-ivars'并且只出现了一个地方:psychruby库,用于(取消)将任意对象序列化为YAML.具体来说,这些是用于读取写入此YAML结构的源代码的链接.

在Rails教程的第7章中,此输出作为debug(params)您被指示放入模板的命令的输出.该debug命令显然调用psych库以显示对象的可读表示(params在本例中).

现在,params-通用Rails的数据结构来保存从URL或形式传递的参数-是其行为类似的对象Hash,但不是纯哈希:它是类的一个实例ActionController::Parameters是一个子类Hash,让我们来看看类的定义:

module ActionController
  # ...
  class Parameters < ActiveSupport::HashWithIndifferentAccess
    # ...
  end
end
Run Code Online (Sandbox Code Playgroud)

同时HashWithIndifferentAccess也直接子类Hash.

作为子类Hash,该params对象可以保存除散列本身之外的其他数据,这是psych在尝试以可读形式打印对象时实际支持的内容.除了打印所有哈希元素(在elements键下),它还会尝试列出对象的所有实例变量并将其打印在ivars键下.

所以,这一切的一切,这个调试打印简单地说,调试的对象是的实例ActionController::Parameters类,它是一个子类Hash,,除了它的哈希元素也有一个@permitted定义的实例变量,它当前设置为false.两个元件,由所述方式,controlleraction是由导轨路由内部使用的参数.

当您再次查看类的源代码时,您确实会@permitted在构造函数中找到该变量:

class Parameters < ActiveSupport::HashWithIndifferentAccess
  # ...
  def initialize(attributes = nil)
    super(attributes)
    @permitted = self.class.permit_all_parameters
  end
end
Run Code Online (Sandbox Code Playgroud)

最后,从文档中我们可以得出结论,@permitted变量保存了params权限的状态.即,true在使用该permit方法允许参数之后设置为:

permitted = params.require(:person).permit(:name, :age)
permitted.permitted? # this prints out the @permitted instance variable
# => true
Run Code Online (Sandbox Code Playgroud)

更新:为什么RailsTutorial的调试输出不同

RailsTutorial的调试输出略有不同 - 它不打印ivars.为什么?这是因为序列化的功能在2.0.9版本中hash-with-ivars添加到了psychgem中.该宝石现在是Ruby标准库的一部分,它的这种特殊的版本已经加入到STDLIB 2.3.0 preview1版本.psych

因此,神秘不同的输出有一个简单的解释:RailsTutorial作者最有可能在编写本书时使用ruby 2.2或更早版本,而且这个ruby版本还没有在Hash调试输出中显示实例变量.实际上,教程中有一些提示表明作者使用了ruby 2.1.5.