Skip to content

Commit f760ccd

Browse files
committed
ActiveSupport::Delegation optimize self.class delegation
Since `self.class` can't possible be `nil`, we can skip the useless `nil` checks and generate more efficient code.
1 parent cc63348 commit f760ccd

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

activesupport/lib/active_support/current_attributes.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def attribute(*names, default: nil)
132132
end
133133
end
134134

135-
Delegation.generate(singleton_class, names.flat_map { |name| [name, "#{name}="] }, to: :instance, as: self)
135+
Delegation.generate(singleton_class, names.flat_map { |name| [name, "#{name}="] }, to: :instance, as: self, nilable: false)
136136

137137
self.defaults = defaults.merge(names.index_with { default })
138138
end
@@ -184,7 +184,7 @@ def method_added(name)
184184
return if name == :initialize
185185
return unless public_method_defined?(name)
186186
return if respond_to?(name, true)
187-
Delegation.generate(singleton_class, [name], to: :instance, as: self)
187+
Delegation.generate(singleton_class, [name], to: :instance, as: self, nilable: false)
188188
end
189189
end
190190

activesupport/lib/active_support/delegation.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module Delegation # :nodoc:
2020
RESERVED_METHOD_NAMES = (RUBY_RESERVED_KEYWORDS + %w(_ arg args block)).to_set.freeze
2121

2222
class << self
23-
def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil, private: nil, as: nil)
23+
def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil, nilable: true, private: nil, as: nil)
2424
unless to
2525
raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)."
2626
end
@@ -49,6 +49,7 @@ def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil
4949
elsif to.is_a?(Module)
5050
to.singleton_class
5151
elsif receiver == "self.class"
52+
nilable = false # self.class can't possibly be nil
5253
owner.singleton_class
5354
end
5455

@@ -98,7 +99,12 @@ def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil
9899
# On the other hand it could be that the target has side-effects,
99100
# whereas conceptually, from the user point of view, the delegator should
100101
# be doing one call.
101-
if allow_nil
102+
if nilable == false
103+
method_def <<
104+
"def #{method_name}(#{definition})" <<
105+
" (#{receiver}).#{method}(#{definition})" <<
106+
"end"
107+
elsif allow_nil
102108
method = method.to_s
103109

104110
method_def <<

activesupport/lib/active_support/duration.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def calculate_total_seconds(parts)
221221
end
222222
end
223223

224-
Delegation.generate(self, [:to_f, :positive?, :negative?, :zero?, :abs], to: :@value, as: Integer)
224+
Delegation.generate(self, [:to_f, :positive?, :negative?, :zero?, :abs], to: :@value, as: Integer, nilable: false)
225225

226226
def initialize(value, parts, variable = nil) # :nodoc:
227227
@value, @parts = value, parts

0 commit comments

Comments
 (0)