Permalink
Browse files

refactor #set

  • Loading branch information...
1 parent e47195a commit e9e3c8500a1797b431923b99aa30a6d289747f42 @rkh rkh committed Jun 5, 2011
Showing with 60 additions and 16 deletions.
  1. +34 −16 lib/sinatra/base.rb
  2. +26 −0 test/settings_test.rb
View
@@ -822,20 +822,43 @@ def middleware
# Sets an option to the given value. If the value is a proc,
# the proc will be called every time the option is accessed.
- def set(option, value = (not_set = true), &block)
+ def set(option, value = (not_set = true), ignore_setter = false, &block)
raise ArgumentError if block and !not_set
- value = block if block
- if value.kind_of?(Proc)
- metadef(option, &value)
- metadef("#{option}?") { !!__send__(option) }
- metadef("#{option}=") { |val| metadef(option, &Proc.new{val}) }
- elsif not_set
+ value, not_set = block, false if block
+
+ if not_set
raise ArgumentError unless option.respond_to?(:each)
option.each { |k,v| set(k, v) }
- elsif respond_to?("#{option}=")
- __send__ "#{option}=", value
- else
- set option, Proc.new{value}
+ return self
+ end
+
+ if respond_to?("#{option}=") and not ignore_setter
+ return __send__("#{option}=", value)
+ end
+
+ setter = proc { |val| set option, val, true }
+ getter = proc { value }
+
+ case value
+ when Proc
+ getter = value
+ when Symbol, Fixnum, FalseClass, TrueClass, NilClass
+ # we have a lot of enable and disable calls, let's optimize those
+ class_eval "def self.#{option}() #{value.inspect} end"
+ getter = nil
+ when Hash
+ setter = proc do |val|
+ val = value.merge val if Hash === val
+ set option, val, true
+ end
+ end
+
+ (class << self; self; end).class_eval do
+ define_method("#{option}=", &setter) if setter
+ define_method(option, &getter) if getter
+ unless method_defined? "#{option}?"
+ class_eval "def #{option}?() !!#{option} end"
+ end
end
self
end
@@ -1212,11 +1235,6 @@ def synchronize(&block)
end
end
- def metadef(message, &block)
- (class << self; self; end).
- send :define_method, message, &block
- end
-
public
CALLERS_TO_IGNORE = [ # :nodoc:
/\/sinatra(\/(base|main|showexceptions))?\.rb$/, # all sinatra code
View
@@ -115,6 +115,32 @@ def foo=(value)
assert_equal 'oops', @base.foo
end
+ it 'merges values of multiple set calls if those are hashes' do
+ @base.set :foo, :a => 1
+ sub = Class.new(@base)
+ sub.set :foo, :b => 2
+ assert_equal({:a => 1, :b => 2}, sub.foo)
+ end
+
+ it 'merging does not affect the superclass' do
+ @base.set :foo, :a => 1
+ sub = Class.new(@base)
+ sub.set :foo, :b => 2
+ assert_equal({:a => 1}, @base.foo)
+ end
+
+ it 'is possible to change a value from a hash to something else' do
+ @base.set :foo, :a => 1
+ @base.set :foo, :bar
+ assert_equal(:bar, @base.foo)
+ end
+
+ it 'merges values with values of the superclass if those are hashes' do
+ @base.set :foo, :a => 1
+ @base.set :foo, :b => 2
+ assert_equal({:a => 1, :b => 2}, @base.foo)
+ end
+
it "sets multiple settings to true with #enable" do
@base.enable :sessions, :foo, :bar
assert @base.sessions

0 comments on commit e9e3c85

Please sign in to comment.