Project

General

Profile

Actions

Bug #17181

closed

Hash with default block breaks after transforming values

Added by crashtech (Carlos Silva) over 3 years ago. Updated over 3 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
[ruby-core:100062]

Description

I found a problem with Hashes that use a default proc.

x = Hash.new { |h, k| h[k] = [] }
x[:a] << 1
x[:b] << 2

I expected that transforming the values as follows:

y = x.transform_values { |arr| arr.map(&:next) }

should create a new array, and I should still be able to push a new element into it as follows:

y[:c] << 3
y # => {:a=>[2], :b=>[3], :c=>[3]}

But the result is weird.

y[:c] << 3 # >> TypeError (callable object is expected)
y[:c] # => the default_proc Proc object
Y[:c].call # 'h' is nil, meaning that it doesn't have the reference to the hash anymore

Updated by jeremyevans0 (Jeremy Evans) over 3 years ago

Thanks for the report. I can confirm the issue. It looks like rb_hash_transform_values is missing COPY_DEFAULT(result, hash);. I'll update the tests and submit a PR to fix this tonight.

Updated by jeremyevans0 (Jeremy Evans) over 3 years ago

jeremyevans0 (Jeremy Evans) wrote in #note-1:

Thanks for the report. I can confirm the issue. It looks like rb_hash_transform_values is missing COPY_DEFAULT(result, hash);. I'll update the tests and submit a PR to fix this tonight.

Actually, it looks like the tests specify there shouldn't be a default in the returned object, they just only test for the default proc and not for the default itself. Still, the fix should be simple and I'll try to submit a PR for it tonight.

Actions #4

Updated by sawa (Tsuyoshi Sawada) over 3 years ago

  • Subject changed from Hash with default block breaks after transform values to Hash with default block breaks after transforming values
  • Description updated (diff)
Actions #5

Updated by jeremyevans (Jeremy Evans) over 3 years ago

  • Status changed from Open to Closed

Applied in changeset git|df14c758fc705c49c2aaf4c9276a8f7229438fbf.


Make hash returned by Hash#transform_values not have a default

This sets an explicit default of nil. There is probably a better
approach of removing the default.

Fixes [Bug #17181]

Actions #6

Updated by nagachika (Tomoyuki Chikanaga) over 3 years ago

  • Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) over 3 years ago

  • Backport changed from 2.5: DONTNEED, 2.6: DONTNEED, 2.7: REQUIRED to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONE

ruby_2_7 665589cbdf7bf652067113dd1c0bc49012b990e0 merged revision(s) df14c758fc705c49c2aaf4c9276a8f7229438fbf.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0