From afcca35789401373f48907bc2df64104c82c57f6 Mon Sep 17 00:00:00 2001 From: Eric Proulx Date: Sun, 15 Dec 2019 20:32:29 +0100 Subject: [PATCH] AttributeTranslator optimization (#1944) Added request_method and requirements has methods instead using method_missing since it's defined by defaults. Added regexp and index in Any class instead of falling back on method_missing --- CHANGELOG.md | 1 + lib/grape/router.rb | 7 +++++-- lib/grape/router/attribute_translator.rb | 24 ++++++++++++++++-------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9eb3604fb..7721c05772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ #### Features * Your contribution here. +* [#1944](https://github.com/ruby-grape/grape/pull/1944): Reduced attribute_translator string allocations - [@ericproulx](https://github.com/ericproulx). * [#1942](https://github.com/ruby-grape/grape/pull/1942): Optimized retained memory methods - [@ericproulx](https://github.com/ericproulx). * [#1941](https://github.com/ruby-grape/grape/pull/1941): Frozen string literal - [@ericproulx](https://github.com/ericproulx). * [#1940](https://github.com/ruby-grape/grape/pull/1940): Get rid of a needless step in HashWithIndifferentAccess - [@dnesteryuk](https://github.com/dnesteryuk). diff --git a/lib/grape/router.rb b/lib/grape/router.rb index 9706990040..509c1a2730 100644 --- a/lib/grape/router.rb +++ b/lib/grape/router.rb @@ -7,8 +7,11 @@ class Router attr_reader :map, :compiled class Any < AttributeTranslator - def initialize(pattern, **attributes) + attr_reader :pattern, :regexp, :index + def initialize(pattern, regexp, index, **attributes) @pattern = pattern + @regexp = regexp + @index = index super(attributes) end end @@ -51,7 +54,7 @@ def append(route) def associate_routes(pattern, **options) regexp = /(?<_#{@neutral_map.length}>)#{pattern.to_regexp}/ - @neutral_map << Any.new(pattern, regexp: regexp, index: @neutral_map.length, **options) + @neutral_map << Any.new(pattern, regexp, @neutral_map.length, **options) end def call(env) diff --git a/lib/grape/router/attribute_translator.rb b/lib/grape/router/attribute_translator.rb index aa66662ff4..ad2d03855e 100644 --- a/lib/grape/router/attribute_translator.rb +++ b/lib/grape/router/attribute_translator.rb @@ -4,31 +4,39 @@ module Grape class Router # this could be an OpenStruct, but doesn't work in Ruby 2.3.0, see https://bugs.ruby-lang.org/issues/12251 class AttributeTranslator + attr_reader :attributes, :request_method, :requirements + def initialize(attributes = {}) @attributes = attributes + @request_method = attributes[:request_method] + @requirements = attributes[:requirements] end def to_h - @attributes + attributes end - def method_missing(m, *args) - if m[-1] == '=' - @attributes[m[0..-1]] = *args - elsif m[-1] != '=' - @attributes[m] + def method_missing(method_name, *args) # rubocop:disable Style/MethodMissing + if setter?(method_name[-1]) + attributes[method_name[0..-1]] = *args else - super + attributes[method_name] end end def respond_to_missing?(method_name, _include_private = false) - if method_name[-1] == '=' + if setter?(method_name[-1]) true else @attributes.key?(method_name) end end + + private + + def setter?(method_name) + method_name[-1] == '=' + end end end end