Skip to content

Commit e1800cd

Browse files
authored
Merge pull request rails#50302 from Shopify/delegate-as-opt
Module#delegate takes a new private `as` parameter
2 parents f0d66d6 + be25850 commit e1800cd

File tree

5 files changed

+31
-28
lines changed

5 files changed

+31
-28
lines changed

actioncable/lib/action_cable/channel/broadcasting.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ module Channel
77
module Broadcasting
88
extend ActiveSupport::Concern
99

10-
included do
11-
delegate :broadcasting_for, :broadcast_to, to: :class
12-
end
13-
1410
module ClassMethods
1511
# Broadcast a hash to a unique broadcasting for this <tt>model</tt> in this channel.
1612
def broadcast_to(model, message)
@@ -38,6 +34,8 @@ def serialize_broadcasting(object) # :nodoc:
3834
end
3935
end
4036
end
37+
38+
delegate :broadcasting_for, :broadcast_to, to: :class, as: ClassMethods
4139
end
4240
end
4341
end

actioncable/lib/action_cable/channel/naming.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ def channel_name
1818
end
1919
end
2020

21-
included do
22-
# Delegates to the class's ::channel_name.
23-
delegate :channel_name, to: :class
24-
end
21+
delegate :channel_name, to: :class, as: ClassMethods
2522
end
2623
end
2724
end

actionview/lib/action_view/layouts.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,9 @@ module Layouts
209209

210210
included do
211211
class_attribute :_layout, instance_accessor: false
212-
class_attribute :_layout_conditions, instance_accessor: false, default: {}
212+
class_attribute :_layout_conditions, instance_accessor: false, instance_reader: true, default: {}
213213

214214
_write_layout_method
215-
216-
delegate :_layout_conditions, to: :class
217215
end
218216

219217
module ClassMethods

activesupport/lib/active_support/core_ext/module/delegation.rb

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class DelegationError < NoMethodError; end
168168
# Foo.new("Bar").name # raises NoMethodError: undefined method `name'
169169
#
170170
# The target method must be public, otherwise it will raise +NoMethodError+.
171-
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
171+
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil, as: nil)
172172
unless to
173173
raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)."
174174
end
@@ -190,6 +190,16 @@ def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
190190
receiver = to.to_s
191191
receiver = "self.#{receiver}" if DELEGATION_RESERVED_METHOD_NAMES.include?(receiver)
192192

193+
explicit_receiver = false
194+
receiver_class = if as
195+
explicit_receiver = true
196+
as
197+
elsif to.is_a?(Module)
198+
to.singleton_class
199+
elsif receiver == "self.class"
200+
singleton_class
201+
end
202+
193203
method_def = []
194204
method_names = []
195205

@@ -205,16 +215,14 @@ def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
205215
if /[^\]]=\z/.match?(method)
206216
"arg"
207217
else
208-
method_object =
218+
method_object = if receiver_class
209219
begin
210-
if to.is_a?(Module)
211-
to.method(method)
212-
elsif receiver == "self.class"
213-
method(method)
214-
end
220+
receiver_class.public_instance_method(method)
215221
rescue NameError
222+
raise if explicit_receiver
216223
# Do nothing. Fall back to `"..."`
217224
end
225+
end
218226

219227
if method_object
220228
parameters = method_object.parameters

activesupport/test/core_ext/module_test.rb

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,25 @@ def initialize(place)
586586
location.delegate(:street, :city, to: :@place, prefix: :the, private: true)
587587
end
588588

589-
def test_delegation_arity
589+
def test_delegation_arity_to_module
590590
c = Class.new do
591591
delegate :zero, :one, :two, to: ArityTester
592592
end
593593
assert_equal 0, c.instance_method(:zero).arity
594594
assert_equal 1, c.instance_method(:one).arity
595595
assert_equal 2, c.instance_method(:two).arity
596596

597+
e = Class.new do
598+
delegate :zero, to: ArityTesterModule
599+
end
600+
601+
assert_equal 0, e.instance_method(:zero).arity
602+
assert_nothing_raised do
603+
e.new.zero
604+
end
605+
end
606+
607+
def test_delegation_arity_to_self_class
597608
d = Class.new(ArityTester) do
598609
delegate :zero, :zero_with_block, :zero_with_implicit_block, :one, :one_with_block, :two, :opt,
599610
:kwargs, :kwargs_with_block, :opt_kwargs, :opt_kwargs_with_block, to: :class
@@ -623,14 +634,5 @@ def test_delegation_arity
623634
d.new.opt_kwargs(a: 1)
624635
d.new.opt_kwargs_with_block(a: 1, b: 2, c: 3)
625636
end
626-
627-
e = Class.new do
628-
delegate :zero, to: ArityTesterModule
629-
end
630-
631-
assert_equal 0, e.instance_method(:zero).arity
632-
assert_nothing_raised do
633-
e.new.zero
634-
end
635637
end
636638
end

0 commit comments

Comments
 (0)