Skip to content

Commit

Permalink
In Ruby repeated fields, each_index actually iterates over the index (#…
Browse files Browse the repository at this point in the history
…11767)

Currently we're aliasing `each_index` to `each_with_index`, incorrectly passing both the index and the value of a repeated field to the block.

What we want is to just pass the index. Luckily this is a method on Ruby arrays, so we just wrap the native Ruby array method.

Fixes #7806

Closes #11767

COPYBARA_INTEGRATE_REVIEW=#11767 from shaldengeki:shaldengeki-repeated-field-each-index-returns-actual-index 874916c
PiperOrigin-RevId: 593835025
  • Loading branch information
shaldengeki authored and copybara-github committed Dec 26, 2023
1 parent da56def commit f869cfa
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
14 changes: 14 additions & 0 deletions ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,20 @@ def test_each
end


def test_each_index
m = TestMessage.new
5.times{|i| m.repeated_string << 'string' }

expected = 0
m.repeated_string.each_index do |idx|
assert_equal expected, idx
expected += 1
assert_equal 'string', m.repeated_string[idx]
end
assert_equal 5, expected
end


def test_empty?
m = TestMessage.new
assert_empty m.repeated_string
Expand Down
3 changes: 1 addition & 2 deletions ruby/lib/google/protobuf/repeated_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ def empty?
end

# array aliases into enumerable
alias_method :each_index, :each_with_index
alias_method :slice, :[]
alias_method :values_at, :select
alias_method :map, :collect
Expand Down Expand Up @@ -145,7 +144,7 @@ def define_array_wrapper_with_result_method(method_name)
end


%w(collect! compact! delete_if fill flatten! insert reverse!
%w(collect! compact! delete_if each_index fill flatten! insert reverse!
rotate! select! shuffle! sort! sort_by! uniq!).each do |method_name|
define_array_wrapper_with_result_method(method_name)
end
Expand Down
14 changes: 14 additions & 0 deletions ruby/tests/repeated_field_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ def test_each
end


def test_each_index
m = TestMessage.new
5.times{|i| m.repeated_string << 'string' }

expected = 0
m.repeated_string.each_index do |idx|
assert_equal expected, idx
expected += 1
assert_equal 'string', m.repeated_string[idx]
end
assert_equal 5, expected
end


def test_empty?
m = TestMessage.new
assert_empty m.repeated_string
Expand Down

0 comments on commit f869cfa

Please sign in to comment.