Module: HTTPClientPatch::IncludeClient

Instance Method Summary collapse

Instance Method Details

#include_http_client(*args, &block) ⇒ Object



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
84
# File 'lib/http_client_patch/include_client.rb', line 46

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