【问题标题】:Enumerable changes my `to_json` behavior可枚举改变了我的 `to_json` 行为
【发布时间】:2012-12-16 03:36:08
【问题描述】:
我有一个 Rails 应用程序和一个作为其中一部分编写的类(不是 ActiveRecord 或任何东西......)。数据存储在简单的实例变量中(字符串、整数、数组...)
当我在它的一个实例上调用to_json 时,我得到了我期望的结果。一个 JSON 对象,也包含所有实例变量作为 JSON 对象。
但是,当我将 include Enumerable 添加到类定义中时,to_json 的行为发生了变化,我得到了一个空对象:"[]"
知道为什么吗? Enumerable 是否以某种方式定义或取消定义了影响 to_json 的东西?
谢谢!
【问题讨论】:
标签:
ruby
json
ruby-on-rails-3.2
ruby-1.9.3
enumerable
【解决方案1】:
那么,会发生什么:
Rails 在 ActiveSupport 中加载。 ActiveSupport 将这些as_json 方法注入(猴子补丁)到几个类和模块中,包括Enumerable:
module Enumerable
def as_json(options = nil) #:nodoc:
to_a.as_json(options)
end
end
对于 Enumerable 要求您拥有的 each 方法,您可能没有返回任何内容,因此 to_a 返回 [],并且一个空数组被转换为字符串 "[]"。
您可以在这里做的是,将您的对象绑定到一个不可枚举的继承类中,并使用它的.as_json 方法。
像这样:
class A
def as_json(*)
Object.instance_method(:as_json).bind(self).call
end
end
演示:
➜ pry
require 'active_support/all'
=> true
class A
def initialize
@a = 1
end
end
=> nil
A.new.to_json
=> "{\"a\":1}"
class A
include Enumerable
def each
end
end
=> nil
A.new.to_json
=> "[]"
class A
def as_json(*)
Object.instance_method(:as_json).bind(self).call
end
end
=> nil
A.new.to_json
=> "{\"a\":1}"