Skip to content

Commit 05cd6f7

Browse files
committed
Merge pull request #1351 from dblock/global-namespace-function
Fix #1348: global functions called during mount.
2 parents 04fc869 + c887607 commit 05cd6f7

File tree

4 files changed

+65
-47
lines changed

4 files changed

+65
-47
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
0.16.2 (Next)
22
============
33

4+
* [#1348](https://github.com/ruby-grape/grape/pull/1348): Fix global functions polluting Grape::API scope - [@dblock](https://github.com/dblock).
45
* Your contribution here.
56

67
0.16.1 (4/3/2016)

lib/grape/router/attribute_translator.rb

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
1-
require 'delegate'
2-
require 'ostruct'
3-
41
module Grape
52
class Router
6-
class AttributeTranslator < DelegateClass(OpenStruct)
7-
def self.register(*attributes)
8-
AttributeTranslator.supported_attributes.concat(attributes)
9-
end
10-
11-
def self.supported_attributes
12-
@supported_attributes ||= []
13-
end
14-
3+
# this could be an OpenStruct, but doesn't work in Ruby 2.3.0, see https://bugs.ruby-lang.org/issues/12251
4+
class AttributeTranslator
155
def initialize(attributes = {})
16-
ostruct = OpenStruct.new(attributes)
17-
super ostruct
186
@attributes = attributes
19-
self.class.supported_attributes.each do |name|
20-
ostruct.send(:"#{name}=", nil) unless ostruct.respond_to?(name)
21-
self.class.instance_eval do
22-
define_method(name) { instance_variable_get(:"@#{name}") }
23-
end if name == :format
24-
end
257
end
268

279
def to_h
28-
@attributes.each_with_object({}) do |(key, _), attributes|
29-
attributes[key.to_sym] = send(:"#{key}")
30-
end
10+
@attributes
3111
end
3212

33-
private
13+
def method_missing(m, *args)
14+
if m[-1] == '='
15+
@attributes[m[0..-1]] = *args
16+
else
17+
@attributes[m]
18+
end
19+
end
3420

35-
def accessor_available?(name)
36-
respond_to?(name) && respond_to?(:"#{name}=")
21+
def respond_to_missing?(method_name, _include_private = false)
22+
if method_name[-1] == '='
23+
true
24+
else
25+
@attributes.key?(method_name)
26+
end
3727
end
3828
end
3929
end

lib/grape/router/route.rb

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,6 @@ class Router
88
class Route
99
ROUTE_ATTRIBUTE_REGEXP = /route_([_a-zA-Z]\w*)/.freeze
1010
SOURCE_LOCATION_REGEXP = /^(.*?):(\d+?)(?::in `.+?')?$/.freeze
11-
TRANSLATION_ATTRIBUTES = [
12-
:prefix,
13-
:version,
14-
:namespace,
15-
:settings,
16-
:format,
17-
:description,
18-
:http_codes,
19-
:headers,
20-
:entity,
21-
:details,
22-
:requirements,
23-
:request_method
24-
].freeze
2511

2612
attr_accessor :pattern, :translator, :app, :index, :regexp
2713

@@ -30,13 +16,6 @@ class Route
3016
extend Forwardable
3117
def_delegators :pattern, :path, :origin
3218

33-
def self.translate(*attributes)
34-
AttributeTranslator.register(*attributes)
35-
def_delegators :@translator, *attributes
36-
end
37-
38-
translate(*TRANSLATION_ATTRIBUTES)
39-
4019
def method_missing(method_id, *arguments)
4120
match = ROUTE_ATTRIBUTE_REGEXP.match(method_id.to_s)
4221
if match
@@ -48,6 +27,25 @@ def method_missing(method_id, *arguments)
4827
end
4928
end
5029

30+
[
31+
:prefix,
32+
:version,
33+
:settings,
34+
:format,
35+
:description,
36+
:http_codes,
37+
:headers,
38+
:entity,
39+
:details,
40+
:requirements,
41+
:request_method,
42+
:namespace
43+
].each do |method_name|
44+
define_method method_name do
45+
attributes.public_send method_name
46+
end
47+
end
48+
5149
def route_method
5250
warn_route_methods(:method, caller(1).shift, :request_method)
5351
request_method
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# see https://github.com/ruby-grape/grape/issues/1348
2+
3+
require 'spec_helper'
4+
5+
def namespace
6+
fail
7+
end
8+
9+
describe Grape::API do
10+
subject do
11+
Class.new(Grape::API) do
12+
format :json
13+
get do
14+
{ ok: true }
15+
end
16+
end
17+
end
18+
19+
def app
20+
subject
21+
end
22+
23+
context 'with a global namespace function' do
24+
it 'works' do
25+
get '/'
26+
expect(last_response.status).to eq 200
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)