Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
* [#2726](https://github.com/ruby-grape/grape/pull/2726): Reuse one `AttributesIterator` per validator and drop the unused `Enumerable` mixin - [@ericproulx](https://github.com/ericproulx).
* [#2728](https://github.com/ruby-grape/grape/pull/2728): Deprecate passing a positional options Hash to `auth`/`http_basic`/`http_digest`; pass keyword arguments instead - [@ericproulx](https://github.com/ericproulx).
* [#2733](https://github.com/ruby-grape/grape/pull/2733): Drop the dead `active_support/core_ext/hash/reverse_merge` require; call `ActiveSupport::HashWithIndifferentAccess.new(...)` directly at call sites - [@ericproulx](https://github.com/ericproulx).
* [#2740](https://github.com/ruby-grape/grape/pull/2740): Lazy-allocate `@api_class` and `@point_in_time_copies` on `Grape::Util::InheritableSetting` so unused settings layers don't carry an empty Hash and empty Array each - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

#### Fixes
Expand Down
17 changes: 13 additions & 4 deletions lib/grape/util/inheritable_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ module Util
# A branchable, inheritable settings object which can store both stackable
# and inheritable values (see InheritableValues and StackableValues).
class InheritableSetting
attr_reader :route, :api_class, :namespace, :namespace_inheritable, :namespace_stackable, :namespace_reverse_stackable, :parent, :point_in_time_copies
attr_reader :route, :namespace, :namespace_inheritable, :namespace_stackable, :namespace_reverse_stackable, :parent

# Lazy-allocated; +api_class+ and +point_in_time_copies+ are rarely
# written on most settings layers, so don't pay for a Hash/Array each.
def api_class
@api_class ||= {}
end

def point_in_time_copies
@point_in_time_copies ||= []
end

# Retrieve global settings.
def self.global
Expand All @@ -24,14 +34,13 @@ def self.reset_global!
# #inherit_from).
def initialize
@route = {}
@api_class = {}
@namespace = InheritableValues.new # only inheritable from a parent when
# used with a mount, or should every API::Class be a separate namespace by default?
@namespace_inheritable = InheritableValues.new
@namespace_stackable = StackableValues.new
@namespace_reverse_stackable = ReverseStackableValues.new
@point_in_time_copies = []
@parent = nil
# @api_class and @point_in_time_copies stay nil until first access.
end

# Return the class-level global properties.
Expand All @@ -53,7 +62,7 @@ def inherit_from(parent)
namespace_reverse_stackable.inherited_values = parent.namespace_reverse_stackable
@route = parent.route.merge(route)

point_in_time_copies.each { |cloned_one| cloned_one.inherit_from parent }
@point_in_time_copies&.each { |cloned_one| cloned_one.inherit_from parent }
end

# Create a point-in-time copy of this settings instance, with clones of
Expand Down
Loading