Module: HTTPClient::IncludeClient

Defined in:
lib/httpclient/include_client.rb

Instance Method Summary collapse

Instance Method Details

#include_http_client(*args, &block) ⇒ Object

[View source]

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/httpclient/include_client.rb', line 45

def include_http_client(*args, &block)
  # We're going to dynamically define a class
  # to hold our state, namespaced, as well as possibly dynamic
  # name of cover method. 
  method_name = (args.last.delete(:method_name) if args.last.kind_of? Hash) || :http_client
  args.pop if args.last == {} # if last arg was named methods now empty, remove it.       
  
  # By the amazingness of closures, we can create these things
  # in local vars here and use em in our method, we don't even
  # need iVars for state. 
  client_instance = nil
  client_mutex = Mutex.new
  client_args = args
  client_block = block

  # to define a _class method_ on the specific class that's currently
  # `self`, we have to use this bit of metaprogramming, sorry. 
  (class << self; self ; end).instance_eval do      
    define_method(method_name) do                            
      # implementation copied from ruby stdlib singleton
      # to create this global obj thread-safely.
      return client_instance if client_instance
      client_mutex.synchronize do
        return client_instance if client_instance
        # init HTTPClient with specified args/block  
        client_instance = HTTPClient.new(*client_args)
        client_block.call(client_instance) if client_block
      end
      return client_instance
    end
  end
  
  # And for convenience, an  _instance method_ on the class that just
  # delegates to the class method. 
  define_method(method_name) do
    self.class.send(method_name)
  end
      
end