From 7e1449a4eafdc9ae4ba4c514b93239ca14f30181 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Sun, 17 Apr 2011 10:30:21 +0200 Subject: [PATCH] use respond_to? rather than arity checks to play nice with method_missing proxies --- lib/sinatra/base.rb | 9 +----- test/delegator_test.rb | 63 ++++++------------------------------------ 2 files changed, 9 insertions(+), 63 deletions(-) diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 4df83f98..9e59bc79 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -1490,14 +1490,7 @@ module Sinatra methods.each do |method_name| eval <<-RUBY, binding, '(__DELEGATE__)', 1 def #{method_name}(*args, &b) - arity = ::Sinatra::Delegator.target.method(#{method_name.inspect}).arity - if arity < 0 ? args.size < -arity - 1 : args.size != arity - begin - return super - rescue NameError => e - raise e unless e.message.include? #{method_name.to_s.inspect} - end - end + return super if respond_to? #{method_name.inspect} ::Sinatra::Delegator.target.send(#{method_name.inspect}, *args, &b) end private #{method_name.inspect} diff --git a/test/delegator_test.rb b/test/delegator_test.rb index d43a8324..7430ec9d 100644 --- a/test/delegator_test.rb +++ b/test/delegator_test.rb @@ -115,70 +115,23 @@ class DelegatorTest < Test::Unit::TestCase it "should work with method_missing proxies for options" do mixin = Module.new do + def respond_to?(method, *) + method.to_sym == :options or super + end + def method_missing(method, *args, &block) return super unless method.to_sym == :options {:some => :option} end end - app = mirror - def app.options(arg, *rest) "yay" end - - a = b = c = nil - delegate do + value = nil + mirror do extend mixin - a, b, c = options, options(1), options(1, 2) + value = options end - assert_equal({:some => :option}, a) - assert_equal("yay", b) - assert_equal("yay", c) - end - - it "should work with method_missing proxies for methods arity > 0" do - mixin = Module.new do - def method_missing(method, *args, &block) - return super unless method.to_sym == :options - {:some => :option} - end - end - - app = mirror - def app.options(arg) "yay" end - - a = b = c = nil - delegate do - extend mixin - a, b, c = options, options(1), options(1, 2) - end - - assert_equal({:some => :option}, a) - assert_equal("yay", b) - assert_equal({:some => :option}, c) - end - - it "should not raise a NameError for methods not handled by a proxy" do - app = mirror - def app.options(arg) "yay" end - assert_raises(ArgumentError) { delegate { options }} - end - - it "should not swallow any NameErrors" do - mixin = Module.new do - def method_missing(method, *args, &block) - return super unless method.to_sym == :options - foobar - end - end - - app = mirror - def app.options(arg) "yay" end - assert_raises NameError do - delegate do - extend mixin - options - end - end + assert_equal({:some => :option}, value) end delegates 'get'