HTTParty - JSON для строго типизированного объекта - PullRequest
0 голосов
/ 10 февраля 2012

Можно ли заставить HTTParty десериализовать результаты из GET в строго типизированный объект ruby? Например

class Myclass
 include HTTParty

end

x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')

puts x.total
puts x.questions[0].title

Сейчас он десериализует его в хеш

puts x["total"]

Мой вопрос на самом деле, если HTTParty поддерживает этот OTB, а не путем установки дополнительных гемов.

Редактировать

Я все еще новичок в Ruby, но я вспоминаю, что все поля класса являются частными, поэтому к ним нужно будет обращаться через методы получения / установки. Так что, может быть, этот вопрос не является правильным?

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Если вы просто хотите использовать синтаксис метода, вы можете использовать открытую структуру.

require 'httparty'
require 'ostruct'

result = HTTParty.get 'http://api.stackoverflow.com/1.0/questions?tags=HTTParty'
object = OpenStruct.new result
object.total # => 2634237

Возможным недостатком является то, что этот объект полностью открыт, так что если вы вызываете несуществующий метод для него, он будетпросто верните nil (если вы вызываете сеттер, он создаст и сеттер, и геттер)

1 голос
/ 10 февраля 2012

Похоже, вы хотите, чтобы возвращаемое значение Myclass::get было экземпляром Myclass.Если это так, вы можете кешировать возвращаемое значение из HTTP-запроса и реализовать method_missing для возврата значений из этого хеша:

class Myclass
  include HTTParty

  attr_accessor :retrieved_values

  def method_missing(method, *args, &block)
    if retrieved_values.key?(method)
      retrieved_values[method]
    else
      super
    end
  end

  def self.get_with_massaging(url)
    new.tap do |instance|
      instance.retrieved_values = get_without_massaging(url)
    end
  end

  class << self
    alias_method :get_without_massaging, :get
    alias_method :get, :get_with_massaging
  end
end

Это не совсем то, что вы просили, потому что это работает толькона один уровень глубины - т. е. x.questions[0].title должно быть x.questions[0][:title]

x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')
p x.total
p x.questions[0][:title]

Возможно, вы могли бы придумать какой-нибудь гибрид этого ответа и Джошуа Крик, чтобы воспользоваться преимуществом OpenStruct.* Я также должен отметить, что все хитрости псевдонимов методов не нужны, если у вашего метода нет с именем get.

...