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

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

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

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

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

Спасибо!


person Zach Moshe    schedule 01.01.2013    source источник
comment
Проверьте это [stackoverflow.com/questions/10292739/ [1]: stackoverflow.com/questions/10292739/   -  person uokesita    schedule 01.01.2013


Ответы (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}"
person Dogbert    schedule 01.01.2013