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
而HashWithIndifferentAccess
是Hash
的直接子类。
作为Hash
的子类, params
对象除了哈希本身之外还可以保存其他数据,这是psych
在尝试以可读forms打印对象时实际支持的内容。 除了打印所有哈希元素(在elements
键下),它还尝试列出对象的所有实例变量并在ivars
键下打印它。
总而言之,这个调试打印只是说调试的对象是ActionController::Parameters
类的一个实例,它是Hash
的子类,除了它的哈希元素还定义了一个@permitted
实例变量,它当前是设为false
。 顺便提一下,这两个元素是controller
和action
是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。