railstutorial来自哪里的调试信息

时间:2016-04-15 19:44:15

标签: ruby-on-rails ruby railstutorial.org

在第7章中,我使用

获得以下输出
--- !ruby/hash-with-ivars:ActionController::Parameters
elements:
  controller: static_pages
  action: home
ivars:
  :@permitted: false

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

1 个答案:

答案 0 :(得分:22)

有趣的问题!我搜索了'hash-with-ivars'的rails项目的所有库源,并且只出现了一个地方:psych ruby library for(de-)将任意对象序列化为YAML。具体来说,这些是指向readingwriting此YAML结构的源代码的链接。

在Rails教程的Chapter 7中,此输出作为您被指示放入模板的debug(params)命令的输出。 debug命令显然调用psych库来显示对象的可读表示(在这种情况下为params)。

现在,params - 用于保存从URL或表单传递的参数的通用Rails数据结构 - 是一个行为类似于Hash但不是纯哈希的对象:它是一个实例类ActionController::Parameters 这是<{1}} 的子类,让我们看看class definition

Hash

module ActionController # ... class Parameters < ActiveSupport::HashWithIndifferentAccess # ... end end HashWithIndifferentAccess的直接子类。

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

所以,总而言之,这个调试打印只是说调试的对象是ivars类的一个实例,它是ActionController::Parameters的子类,除了它的哈希元素之外还定义了一个Hash实例变量,它当前设置为@permitted。顺便提一下,falsecontroller这两个元素是Rails内部用于路由的参数。

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

@permitted

最后,从documentation我们可以得出结论,class Parameters < ActiveSupport::HashWithIndifferentAccess # ... def initialize(attributes = nil) super(attributes) @permitted = self.class.permit_all_parameters end end 变量保存了params权限的状态。即在使用@permitted方法允许参数后将其设置为true

permit

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

RailsTutorial的调试输出略有不同 - 它不会打印permitted = params.require(:person).permit(:name, :age) permitted.permitted? # this prints out the @permitted instance variable # => true 。为什么?这是因为序列化ivar的功能已添加到version 2.0.9中的hash-with-ivars gem中。 psych gem现在是Ruby标准库的一部分,其特定版本已经added到stdlib 2.3.0 preview1版本

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