Enumerable меняет мое поведение `to_json`

У меня есть приложение rails и класс, который я написал как его часть (не ActiveRecord или что-то еще). Данные хранятся в простых переменных экземпляра (строка, целые числа, массивы...)

Когда я призываю to_json в случае этого я получаю то, что ожидаю. Объект JSON, содержащий все переменные экземпляра как объекты JSON.

Тем не менее, когда я добавляю include Enumerable к определению класса, поведение to_json меняется, и я получаю пустой объект: "[]"

Любая идея, почему это? Есть ли Enumerable как-то определяется или не определяет то, что влияет to_json?

Спасибо!

1 ответ

Решение

Итак, что происходит, это:

Rails загружается в ActiveSupport. ActiveSupport внедряет (обезьяны патчи) эти as_json методы на несколько классов и модулей, в том числе Enumerable:

module Enumerable
  def as_json(options = nil) #:nodoc:
    to_a.as_json(options)
  end
end

Вы, вероятно, ничего не возвращаете для each Метод Enumerable требует от вас, чтобы 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}"
Другие вопросы по тегам