railstutorial来自哪里的调试信息

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

--- !ruby/hash-with-ivars:ActionController::Parameters elements: controller: static_pages action: home ivars: :@permitted: false 

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

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

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

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

 module ActionController # ... class Parameters < ActiveSupport::HashWithIndifferentAccess # ... end end 

HashWithIndifferentAccessHash的直接子类。

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

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

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

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

最后,从文档中我们可以得出结论, @permitted变量保存了params权限的状态。 也就是说,在使用permit方法允许params之后它被设置为true

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

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

RailsTutorial的调试输出略有不同 - 它不会打印ivar 。 为什么? 这是因为序列化hash-with-ivars被添加到版本2.0.9中的psych gem中。 psych gem现在是Ruby标准库的一部分,它的特定版本已添加到stdlib 2.3.0 preview1版本中

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