继承HTTParty模块

Inherit HTTParty module

如何继承HTTParty模块设置一些默认值?

module SuperClient
  include HTTParty

  headers 'Auth' => 'Basic'
end

module ServiceApiClient
  include SuperClient

  headers 'X-Prop' => 'Some specific data'
  base_uri 'https://example.com'

  def self.posts
    self.get '/posts'
    # Expected to send headers Auth and X-Prop
  end
end

我需要一些自定义模块,它可以包含在客户端 类 中并且表现得像本地 HTTParty 模块。

您可以将 SuperClient 保留为 class 并从中继承其他客户端。像这样的东西。 headers 'Auth' 和 'X-Prop' 都将包含在请求中。

require 'httparty'

class SuperClient 
    include HTTParty

    headers 'Auth' => 'Basic'
    # Uncomment below line to print logs in terminal
    # debug_output STDOUT
end

class ServiceApiClient < SuperClient

    headers 'X-Prop' => 'Some specific data'
    base_uri 'https://example.com'

    def posts
        self.class.get '/posts'
        # Expected to send headers Auth and X-Prop
  end
end         

client = ServiceApiClient.new

client.posts()

如果唯一的目的是设置默认值而不是重新定义方法,则以下方法可以解决问题:

module SuperClient
  def self.included(base)
    base.include HTTParty

    # defaults
    base.headers 'Auth' => 'Basic'
    # or
    base.class_eval do
      headers 'Auth' => 'Basic'
    end
  end
end

当您包含 SuperClient 时,它将包含 HTTParty 并设置一些默认值。如果这是您需要的唯一功能,如果您还计划重新定义方法,请阅读更多内容。


如果您打算重新定义方法,这不会起作用。 HTTParty 将在 SuperClient 之前添加到祖先堆栈中。当调用由 SuperClientHTTParty 定义的方法时,将首先调用 HTTParty 变体,这意味着永远不会到达 SuperClient 变体。

这可能比您需要的信息更多,但可以通过以下方式解决上述问题:

module SuperClient
  def self.included(base)
    base.include HTTParty
    base.include InstanceMethods
    base.extend  ClassMethods

    # defaults
    # ...
  end

  module InstanceMethods
    # ...
  end

  module ClassMethods
    # ...
  end
end

通过包含 InstanceMethods 并在包含 HTTParty 之后扩展 ClassMethods,它们将位于堆栈的更高位置,允许您重新定义方法并调用 super

class C
  include SuperClient
end

# methods are search for from top to bottom
puts C.ancestors
# C
# SuperClient::InstanceMethods
# HTTParty::ModuleInheritableAttributes
# HTTParty
# SuperClient
# Object
# JSON::Ext::Generator::GeneratorMethods::Object
# Kernel
# BasicObject

puts C.singleton_class.ancestors
# #<Class:C>
# SuperClient::ClassMethods
# HTTParty::ModuleInheritableAttributes::ClassMethods
# HTTParty::ClassMethods
# #<Class:Object>
# #<Class:BasicObject>
# Class
# Module
# Object
# JSON::Ext::Generator::GeneratorMethods::Object
# Kernel
# BasicObject