lib/faraday/options.rb in faraday-0.9.0.rc5 vs lib/faraday/options.rb in faraday-0.9.0.rc6
- old
+ new
@@ -16,20 +16,20 @@
# Public
def update(obj)
obj.each do |key, value|
if sub_options = self.class.options_for(key)
- value = sub_options.from(value)
+ value = sub_options.from(value) if value
elsif Hash === value
hash = {}
value.each do |hash_key, hash_value|
hash[hash_key] = hash_value
end
value = hash
end
- self.send("#{key}=", value)
+ self.send("#{key}=", value) unless value.nil?
end
self
end
alias merge! update
@@ -45,13 +45,24 @@
def merge(value)
dup.update(value)
end
# Public
- def fetch(key, default = nil)
- send(key) || send("#{key}=", default ||
- (block_given? ? Proc.new.call : nil))
+ def fetch(key, *args)
+ return send(key) if symbolized_key_set.include?(key.to_sym)
+
+ key_setter = "#{key}="
+
+ if args.size > 0
+ return send(key_setter, args.first)
+ end
+
+ if block_given?
+ return send(key_setter, Proc.new.call(key))
+ end
+
+ raise self.class.fetch_error_class, "key not found: #{key.inspect}"
end
# Public
def values_at(*keys)
keys.map { |key| send(key) }
@@ -96,10 +107,48 @@
# Internal
def self.attribute_options
@attribute_options ||= {}
end
+
+ def self.memoized(key)
+ memoized_attributes[key.to_sym] = Proc.new
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
+ def #{key}() self[:#{key}]; end
+ RUBY
+ end
+
+ def self.memoized_attributes
+ @memoized_attributes ||= {}
+ end
+
+ def [](key)
+ key = key.to_sym
+ if method = self.class.memoized_attributes[key]
+ super(key) || (self[key] = instance_eval(&method))
+ else
+ super
+ end
+ end
+
+ def symbolized_key_set
+ @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
+ end
+
+ def self.inherited(subclass)
+ super
+ subclass.attribute_options.update(attribute_options)
+ subclass.memoized_attributes.update(memoized_attributes)
+ end
+
+ def self.fetch_error_class
+ @fetch_error_class ||= if Object.const_defined?(:KeyError)
+ ::KeyError
+ else
+ ::IndexError
+ end
+ end
end
class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
:timeout, :open_timeout, :boundary,
:oauth)
@@ -112,11 +161,11 @@
end
end
end
class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
- :cert_store, :client_cert, :client_key, :verify_depth, :version)
+ :cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth, :version)
def verify?
verify != false
end
@@ -139,35 +188,24 @@
end
end
super(value)
end
- def user
- self[:user] ||= Utils.unescape(uri.user)
- end
-
- def password
- self[:password] ||= Utils.unescape(uri.password)
- end
+ memoized(:user) { uri.user && Utils.unescape(uri.user) }
+ memoized(:password) { uri.password && Utils.unescape(uri.password) }
end
class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
:parallel_manager, :params, :headers, :builder_class)
options :request => RequestOptions, :ssl => SSLOptions
- def request
- self[:request] ||= self.class.options_for(:request).new
- end
+ memoized(:request) { self.class.options_for(:request).new }
- def ssl
- self[:ssl] ||= self.class.options_for(:ssl).new
- end
+ memoized(:ssl) { self.class.options_for(:ssl).new }
- def builder_class
- self[:builder_class] ||= RackBuilder
- end
+ memoized(:builder_class) { RackBuilder }
def new_builder(block)
builder_class.new(&block)
end
end
@@ -188,28 +226,84 @@
extend Forwardable
def_delegators :request, :params_encoder
+ # Public
+ def [](key)
+ if in_member_set?(key)
+ super(key)
+ else
+ custom_members[key]
+ end
+ end
+
+ # Public
+ def []=(key, value)
+ if in_member_set?(key)
+ super(key, value)
+ else
+ custom_members[key] = value
+ end
+ end
+
+ # Public
def success?
SuccessfulStatuses.include?(status)
end
+ # Public
def needs_body?
!body && MethodsWithBodies.include?(method)
end
+ # Public
def clear_body
request_headers[ContentLength] = '0'
self.body = ''
end
+ # Public
def parse_body?
!StatusesWithoutBody.include?(status)
end
+ # Public
def parallel?
!!parallel_manager
end
+
+ def inspect
+ attrs = [nil]
+ members.each do |mem|
+ if value = send(mem)
+ attrs << "@#{mem}=#{value.inspect}"
+ end
+ end
+ if !custom_members.empty?
+ attrs << "@custom=#{custom_members.inspect}"
+ end
+ %(#<#{self.class}#{attrs.join(" ")}>)
+ end
+
+ # Internal
+ def custom_members
+ @custom_members ||= {}
+ end
+
+ # Internal
+ if members.first.is_a?(Symbol)
+ def in_member_set?(key)
+ self.class.member_set.include?(key.to_sym)
+ end
+ else
+ def in_member_set?(key)
+ self.class.member_set.include?(key.to_s)
+ end
+ end
+
+ # Internal
+ def self.member_set
+ @member_set ||= Set.new(members)
+ end
end
end
-