[#67346] Future of test suites for Ruby — Charles Oliver Nutter <headius@...>
I'll try to be brief so we can discuss all this. tl;dr: RubySpec is
19 messages
2015/01/05
[#67353] Re: Future of test suites for Ruby
— Tanaka Akira <akr@...>
2015/01/05
2015-01-06 7:18 GMT+09:00 Charles Oliver Nutter <headius@headius.com>:
[#67444] [ruby-trunk - Feature #10718] [Open] IO#close should not raise IOError on closed IO objects. — akr@...
Issue #10718 has been reported by Akira Tanaka.
3 messages
2015/01/09
[#67689] Keyword Arguments — Anthony Crumley <anthony.crumley@...>
Please forgive my ignorance as I am new to MRI development and am still
5 messages
2015/01/20
[#67733] [ruby-trunk - Bug #10761] Marshal.dump 100% slower in 2.2.0 vs 2.1.5 — normalperson@...
Issue #10761 has been updated by Eric Wong.
4 messages
2015/01/21
[#67736] Re: [ruby-trunk - Bug #10761] Marshal.dump 100% slower in 2.2.0 vs 2.1.5
— Eric Wong <normalperson@...>
2015/01/22
normalperson@yhbt.net wrote:
[#67772] Preventing Redundant Email Messages — Jeremy Evans <code@...>
For a long time, I've wondered why I sometimes receive redundant email
5 messages
2015/01/23
[ruby-core:67423] [ruby-trunk - Bug #10713] Assigning default value for a Hash as an empty Array creating unpredictable results
From:
davidm@...
Date:
2015-01-08 04:42:05 UTC
List:
ruby-core #67423
Issue #10713 has been updated by David MacMahon.
Arvinder Singh wrote:
> ~~~
> irb(main):001:0> letters = Hash.new([])
> => {}
> irb(main):002:0> letters[:a] << 1
> => [1]
> ~~~
The `letters[:a]` part of the second line returns the "default value" of the Hash because the `:a` key does not exist in the Hash. The `<< 1` part pushes a `1` onto the end of the default value, but it does not assign the default value (and certainly not a modified copy of the default value) to the `:a` key of the Hash.
To get the behavior you expect/desire you can use `letters[:a] <<= 1`, which is equivalent to `letters[:a] = letters[:a] << 1`, but be careful when using Hashes with default objects:
~~~
irb(main):001:0> letters = Hash.new([]) # Default object == single instance
=> {}
irb(main):002:0> letters[:a] <<= 1
=> [1]
irb(main):003:0> letters[:a]
=> [1]
irb(main):004:0> letters
=> {:a=>[1]}
irb(main):005:0> letters[:b] # Returns default object (same object as letters[:a])!
=> [1]
~~~
To get a different object for each fetch of a non-existent key, use a Hash with a default Proc that returns new object every time:
~~~
irb(main):001:0> letters = Hash.new {[]} # Default Proc returns new instance each call
=> {}
irb(main):002:0> letters[:a] <<= 1
=> [1]
irb(main):003:0> letters[:a]
=> [1]
irb(main):004:0> letters
=> {:a=>[1]}
irb(main):005:0> letters[:b] # Returns different empty Array until letters[:b] is assigned
=> []
irb(main):006:0> letters[:b].object_id
=> 2152992900
irb(main):007:0> letters[:b].object_id
=> 2153118760
irb(main):008:0> letters[:b].object_id
=> 2153112180
irb(main):009:0> letters[:b] = letters[:b]
=> []
irb(main):010:0> letters[:b].object_id
=> 2156907140
irb(main):011:0> letters[:b].object_id
=> 2156907140
~~~
Given all the trickiness and because sometimes you don't have control over the creation of the Hash, I generally end up doing this instead:
~~~
>> # h is any Hash, e.g. from method call
>> h[:a] ||= []
=> []
>> h[:a] << 1
=> [1]
# etc...
~~~
This uses the "||=" idiom, which can obliterate an existing `nil` or `false` value, so you still have to be a little careful (though it's very rarely an issue).
----------------------------------------
Bug #10713: Assigning default value for a Hash as an empty Array creating unpredictable results
https://bugs.ruby-lang.org/issues/10713#change-50853
* Author: Arvinder Singh
* Status: Rejected
* Priority: Normal
* Assignee:
* Category: core
* Target version: current: 2.2.0
* ruby -v: ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
Creating a Hash with a default value works fine, unless the default value is an empty Array.
E.g. the following returns an empty Hash...
~~~
irb(main):001:0> letters = Hash.new([])
=> {}
irb(main):002:0> letters[:a] << 1
=> [1]
irb(main):003:0> letters[:a] << 2
=> [1, 2]
irb(main):004:0> letters[:a]
=> [1, 2]
irb(main):005:0> letters
=> {}
~~~
whereas the following code explicitly defining hash keys works.
~~~
irb(main):001:0> letters = {a: [], b: []}
=> {:a=>[], :b=>[]}
irb(main):002:0> letters[:a] << 1
=> [1]
irb(main):003:0> letters[:a] << 2
=> [1, 2]
irb(main):004:0> letters[:a]
=> [1, 2]
irb(main):005:0> letters
=> {:a=>[1, 2], :b=>[]}
~~~
Is this an unpredictable(bug) or an expected behavior(feature). I tend to lean towards the former, but I might be wrong.
--
https://bugs.ruby-lang.org/