refactor #set
This commit is contained in:
parent
e47195a17a
commit
e9e3c8500a
|
@ -822,20 +822,43 @@ module Sinatra
|
|||
|
||||
# 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 @@ module Sinatra
|
|||
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
|
||||
|
|
|
@ -115,6 +115,32 @@ class SettingsTest < Test::Unit::TestCase
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue