Skip to content

Commit 950b394

Browse files
committed
Fix keyword arguments warnings in Active Job
Related rails#38053, rails#38187, rails#38105. This is a reattempt to fix keyword arguments warnings in Active Job. Now Ruby (master) has `Hash.ruby2_keywords_hash{?,}` and that will be backported to 2.7.1. ruby/ruby#2818 https://bugs.ruby-lang.org/issues/16486 I've emulated that for 2.7.0 and older versions.
1 parent d72f940 commit 950b394

File tree

5 files changed

+43
-3
lines changed

5 files changed

+43
-3
lines changed

activejob/lib/active_job/arguments.rb

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ def deserialize(arguments)
5252
# :nodoc:
5353
SYMBOL_KEYS_KEY = "_aj_symbol_keys"
5454
# :nodoc:
55+
RUBY2_KEYWORDS_KEY = "_aj_ruby2_keywords"
56+
# :nodoc:
5557
WITH_INDIFFERENT_ACCESS_KEY = "_aj_hash_with_indifferent_access"
5658
# :nodoc:
5759
OBJECT_SERIALIZER_KEY = "_aj_serialized"
@@ -60,10 +62,39 @@ def deserialize(arguments)
6062
RESERVED_KEYS = [
6163
GLOBALID_KEY, GLOBALID_KEY.to_sym,
6264
SYMBOL_KEYS_KEY, SYMBOL_KEYS_KEY.to_sym,
65+
RUBY2_KEYWORDS_KEY, RUBY2_KEYWORDS_KEY.to_sym,
6366
OBJECT_SERIALIZER_KEY, OBJECT_SERIALIZER_KEY.to_sym,
6467
WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym,
6568
]
66-
private_constant :PERMITTED_TYPES, :RESERVED_KEYS, :GLOBALID_KEY, :SYMBOL_KEYS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
69+
private_constant :PERMITTED_TYPES, :RESERVED_KEYS, :GLOBALID_KEY,
70+
:SYMBOL_KEYS_KEY, :RUBY2_KEYWORDS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
71+
72+
unless Hash.respond_to?(:ruby2_keywords_hash?) && Hash.respond_to?(:ruby2_keywords_hash)
73+
using Module.new {
74+
refine Hash do
75+
class << Hash
76+
if RUBY_VERSION >= "2.7"
77+
def ruby2_keywords_hash?(hash)
78+
!new(*[hash]).default.equal?(hash)
79+
end
80+
else
81+
def ruby2_keywords_hash?(hash)
82+
false
83+
end
84+
end
85+
86+
def ruby2_keywords_hash(hash)
87+
_ruby2_keywords_hash(**hash)
88+
end
89+
90+
private def _ruby2_keywords_hash(*args)
91+
args.last
92+
end
93+
ruby2_keywords(:_ruby2_keywords_hash) if respond_to?(:ruby2_keywords, true)
94+
end
95+
end
96+
}
97+
end
6798

6899
def serialize_argument(argument)
69100
case argument
@@ -76,9 +107,10 @@ def serialize_argument(argument)
76107
when ActiveSupport::HashWithIndifferentAccess
77108
serialize_indifferent_hash(argument)
78109
when Hash
79-
symbol_keys = argument.each_key.grep(Symbol).map(&:to_s)
110+
symbol_keys = argument.each_key.grep(Symbol).map!(&:to_s)
80111
result = serialize_hash(argument)
81112
result[SYMBOL_KEYS_KEY] = symbol_keys
113+
result[RUBY2_KEYWORDS_KEY] = true if Hash.ruby2_keywords_hash?(argument)
82114
result
83115
when -> (arg) { arg.respond_to?(:permitted?) }
84116
serialize_indifferent_hash(argument.to_h)
@@ -132,6 +164,10 @@ def deserialize_hash(serialized_hash)
132164
result = result.with_indifferent_access
133165
elsif symbol_keys = result.delete(SYMBOL_KEYS_KEY)
134166
result = transform_symbol_keys(result, symbol_keys)
167+
168+
if result.delete(RUBY2_KEYWORDS_KEY)
169+
result = Hash.ruby2_keywords_hash(result)
170+
end
135171
end
136172
result
137173
end

activejob/lib/active_job/core.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def initialize(*arguments)
8686
@executions = 0
8787
@exception_executions = {}
8888
end
89+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
8990

9091
# Returns a hash with the job data that can safely be passed to the
9192
# queuing adapter.

activejob/lib/active_job/enqueuing.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ module ClassMethods
2121
def perform_later(*args)
2222
job_or_instantiate(*args).enqueue
2323
end
24+
ruby2_keywords(:perform_later) if respond_to?(:ruby2_keywords, true)
2425

2526
private
2627
def job_or_instantiate(*args) # :doc:
2728
args.first.is_a?(self) ? args.first : new(*args)
2829
end
30+
ruby2_keywords(:job_or_instantiate) if respond_to?(:ruby2_keywords, true)
2931
end
3032

3133
# Enqueues the job to be performed by the queue adapter.

activejob/lib/active_job/execution.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module ClassMethods
1717
def perform_now(*args)
1818
job_or_instantiate(*args).perform_now
1919
end
20+
ruby2_keywords(:perform_now) if respond_to?(:ruby2_keywords, true)
2021

2122
def execute(job_data) #:nodoc:
2223
ActiveJob::Callbacks.run_callbacks(:execute) do

activejob/test/cases/argument_serialization_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class ClassArgument; end
170170
end
171171

172172
test "allows for keyword arguments" do
173-
KwargsJob.perform_later(argument: 2)
173+
KwargsJob.perform_now(argument: 2)
174174

175175
assert_equal "Job with argument: 2", JobBuffer.last_value
176176
end

0 commit comments

Comments
 (0)