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 -