YAML - TypeError:无法转储匿名模块 [英] YAML - TypeError: can't dump anonymous module

查看:14
本文介绍了YAML - TypeError:无法转储匿名模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 application_controller 的一个动作中,如果我们尝试:

In an action of application_controller, if we try:

p request.env.to_yaml

我会收到这个错误:

    TypeError: can't dump anonymous module: #<Module:0x007fee26e34ad8>
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:267:in `visit_Module'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:447:in `block in dump_ivars'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `each'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `dump_ivars'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:124:in `visit_Object'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:447:in `block in dump_ivars'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `each'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:445:in `dump_ivars'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:124:in `visit_Object'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:292:in `block in visit_Hash'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:290:in `each'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:290:in `visit_Hash'
    from /Users/twer/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:102:in `accept'

我的问题是:如何将 request.env 序列化为 yaml?

My question is: how can I serialize request.env to yaml?

实际上,我应该将 request.env 传递给delayed_job 并发送电子邮件,但我得到了这个错误,因为delayed_job 需要将对象序列化到数据库中.

Actually, I was supposed to pass request.env to delayed_job and send out email, and I got this error because delayed_job need serializing object into DB.

推荐答案

问题是 request.env 哈希有很多嵌套对象(尤其是模块),无法转换为 yaml.诀窍是删除那些无法转换的哈希部分.

The problem is, that the request.env hash has a lot of nested objects (and especially modules), which can't be converted to yaml. The trick is to delete those parts of the hash, that can't be converted.

tmp_env = request.env.clone
tmp_env.delete "action_dispatch.routes"
tmp_env.delete "action_controller.instance"
tmp_env["action_dispatch.remote_ip"] = tmp_env["action_dispatch.remote_ip"].to_s 
p tmp_env.to_yaml # now it works

我们首先克隆原始 env 哈希,以免意外修改它.然后我们从副本中删除这些键,这会导致错误.

We first clone the original env hash, to not accidentally modify it. Then we delete those keys from our copy, which cause errors.

tmp_env["action_dispatch.routes"] 包含对 ActionDispatch::Routing::RouteSet 对象中未命名模块的引用,这是导致错误的原因.我们最好删除它.

tmp_env["action_dispatch.routes"] contains a reference to an unnamed module within a ActionDispatch::Routing::RouteSet object, which is the cause of your error. We better delete it.

tmp_env["action_controller.instance"] 包含对原始 env-hash 的引用(我们无法转换).删除它.

tmp_env["action_controller.instance"] contains a reference to the original env-hash (which we cannot convert). Delete it.

最后 tmp_env["action_dispatch.remote_ip"] 看起来像一个字符串(当检查它时),但它是一个 ActionDispatch::RemoteIp::GetIp 实例.它包含对原始 env 散列的另一个引用.我们将其转换为字符串,因为我不知道您以后是否对那个键感兴趣.

And finally tmp_env["action_dispatch.remote_ip"] looks like a string (when inspecting it), but it is a ActionDispatch::RemoteIp::GetIp instance. It contains another reference to the original env hash. We convert it to a string, because I don't know if your are interested in that key later.

此外,您可以删除更多键以减小 yaml 输出的大小.但是,这应该不会抛出您遇到的错误.一个更精简的解决方案是从一个空的 Hash 开始,并且只在 yaml 输出中复制您真正需要的键.

Additionally, you may remove many more keys to reduce the size of your yaml output. However, this should work without throwing the error you experienced. A leaner solution would be to start with an empty Hash and only copy the keys you really need in your yaml output.

用 ruby​​ 1.9.3 和 rails 3.2.13 测试

Tested with ruby 1.9.3 and rails 3.2.13

这篇关于YAML - TypeError:无法转储匿名模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆