Skip to content

Commit ea27c2d

Browse files
committed
Simplify endpoint block execution and deprecate return call in it
1 parent 5dca095 commit ea27c2d

File tree

2 files changed

+10
-55
lines changed

2 files changed

+10
-55
lines changed

lib/grape/endpoint.rb

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,33 +37,6 @@ def run_before_each(endpoint)
3737
superclass.run_before_each(endpoint) unless self == Endpoint
3838
before_each.each { |blk| blk.try(:call, endpoint) }
3939
end
40-
41-
# @api private
42-
#
43-
# Create an UnboundMethod that is appropriate for executing an endpoint
44-
# route.
45-
#
46-
# The unbound method allows explicit calls to +return+ without raising a
47-
# +LocalJumpError+. The method will be removed, but a +Proc+ reference to
48-
# it will be returned. The returned +Proc+ expects a single argument: the
49-
# instance of +Endpoint+ to bind to the method during the call.
50-
#
51-
# @param [String, Symbol] method_name
52-
# @return [Proc]
53-
# @raise [NameError] an instance method with the same name already exists
54-
def generate_api_method(method_name, &block)
55-
raise NameError.new("method #{method_name.inspect} already exists and cannot be used as an unbound method name") if method_defined?(method_name)
56-
57-
define_method(method_name, &block)
58-
method = instance_method(method_name)
59-
remove_method(method_name)
60-
61-
proc do |endpoint_instance|
62-
ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do
63-
method.bind_call(endpoint_instance)
64-
end
65-
end
66-
end
6740
end
6841

6942
# Create a new endpoint.
@@ -108,12 +81,18 @@ def initialize(new_settings, options = {}, &block)
10881
@status = nil
10982
@stream = nil
11083
@body = nil
111-
@proc = nil
11284

11385
return unless block
11486

11587
@source = block
116-
@block = self.class.generate_api_method(method_name, &block)
88+
@block = @block = lambda do |endpoint_instance|
89+
ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do
90+
endpoint_instance.instance_exec(&block)
91+
rescue LocalJumpError => e
92+
Grape.deprecator.warn 'Using `return` in an endpoint has been deprecated.'
93+
return e.exit_value
94+
end
95+
end
11796
end
11897

11998
# Update our settings from a given set of stackable parameters. Used when
@@ -131,14 +110,6 @@ def require_option(options, key)
131110
raise Grape::Exceptions::MissingOption.new(key) unless options.key?(key)
132111
end
133112

134-
def method_name
135-
[options[:method],
136-
Namespace.joined_space(namespace_stackable(:namespace)),
137-
(namespace_stackable(:mount_path) || []).join('/'),
138-
options[:path].join('/')]
139-
.join(' ')
140-
end
141-
142113
def routes
143114
@routes ||= endpoints&.collect(&:routes)&.flatten || to_routes
144115
end

spec/grape/endpoint_spec.rb

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -785,29 +785,13 @@ def memoized
785785
return 'Hello'
786786
end
787787

788+
expect(Grape.deprecator).to receive(:warn).with('Using `return` in an endpoint has been deprecated.')
789+
788790
get '/home'
789791
expect(last_response.status).to eq(200)
790792
expect(last_response.body).to eq('Hello')
791793
end
792794

793-
describe '.generate_api_method' do
794-
it 'raises NameError if the method name is already in use' do
795-
expect do
796-
described_class.generate_api_method('version', &proc {})
797-
end.to raise_error(NameError)
798-
end
799-
800-
it 'raises ArgumentError if a block is not given' do
801-
expect do
802-
described_class.generate_api_method('GET without a block method')
803-
end.to raise_error(ArgumentError)
804-
end
805-
806-
it 'returns a Proc' do
807-
expect(described_class.generate_api_method('GET test for a proc', &proc {})).to be_a Proc
808-
end
809-
end
810-
811795
context 'filters' do
812796
describe 'before filters' do
813797
it 'runs the before filter if set' do

0 commit comments

Comments
 (0)