Ruby Hash populated from Array.product yields unexpected behavior
up vote
0
down vote
favorite
I wanted to pre-populate a Hash, given an array of keys and a default value (an empty array). I attempted to do this using the #product method of Array.
> hash = Hash[[:foo, :bar].product([])] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>[:baz]
I don't understand why the value is being applied to all keys in the hash. If instead, I use the returned value of product and populate the hash directly from that, I get expected behavior.
> [:foo, :bar].product([]) # => [[:foo, ], [:bar, ]]
> hash = Hash[[[:foo, ], [:bar, ]]] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>
I am using ruby 2.3.6
ruby hash
add a comment |
up vote
0
down vote
favorite
I wanted to pre-populate a Hash, given an array of keys and a default value (an empty array). I attempted to do this using the #product method of Array.
> hash = Hash[[:foo, :bar].product([])] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>[:baz]
I don't understand why the value is being applied to all keys in the hash. If instead, I use the returned value of product and populate the hash directly from that, I get expected behavior.
> [:foo, :bar].product([]) # => [[:foo, ], [:bar, ]]
> hash = Hash[[[:foo, ], [:bar, ]]] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>
I am using ruby 2.3.6
ruby hash
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I wanted to pre-populate a Hash, given an array of keys and a default value (an empty array). I attempted to do this using the #product method of Array.
> hash = Hash[[:foo, :bar].product([])] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>[:baz]
I don't understand why the value is being applied to all keys in the hash. If instead, I use the returned value of product and populate the hash directly from that, I get expected behavior.
> [:foo, :bar].product([]) # => [[:foo, ], [:bar, ]]
> hash = Hash[[[:foo, ], [:bar, ]]] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>
I am using ruby 2.3.6
ruby hash
I wanted to pre-populate a Hash, given an array of keys and a default value (an empty array). I attempted to do this using the #product method of Array.
> hash = Hash[[:foo, :bar].product([])] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>[:baz]
I don't understand why the value is being applied to all keys in the hash. If instead, I use the returned value of product and populate the hash directly from that, I get expected behavior.
> [:foo, :bar].product([]) # => [[:foo, ], [:bar, ]]
> hash = Hash[[[:foo, ], [:bar, ]]] # => :foo=>, :bar=>
> hash[:foo].push(:baz) # => :foo=>[:baz], :bar=>
I am using ruby 2.3.6
ruby hash
ruby hash
asked Nov 8 at 17:21
myles
186
186
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
It's because the arrays that you pass to your hash initializer are the same object, so if you modify said object, the changes will be present everywhere it is used:
> hash = Hash[[:foo, :bar].product([])]
# => :foo=>, :bar=>
> hash[:foo].object_id
# => 47106586247680
> hash[:bar].object_id
# => 47106586247680
If you copy-paste the output of your product, you're using 2 different arrays as they get instantiated separately.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
It's because the arrays that you pass to your hash initializer are the same object, so if you modify said object, the changes will be present everywhere it is used:
> hash = Hash[[:foo, :bar].product([])]
# => :foo=>, :bar=>
> hash[:foo].object_id
# => 47106586247680
> hash[:bar].object_id
# => 47106586247680
If you copy-paste the output of your product, you're using 2 different arrays as they get instantiated separately.
add a comment |
up vote
1
down vote
accepted
It's because the arrays that you pass to your hash initializer are the same object, so if you modify said object, the changes will be present everywhere it is used:
> hash = Hash[[:foo, :bar].product([])]
# => :foo=>, :bar=>
> hash[:foo].object_id
# => 47106586247680
> hash[:bar].object_id
# => 47106586247680
If you copy-paste the output of your product, you're using 2 different arrays as they get instantiated separately.
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
It's because the arrays that you pass to your hash initializer are the same object, so if you modify said object, the changes will be present everywhere it is used:
> hash = Hash[[:foo, :bar].product([])]
# => :foo=>, :bar=>
> hash[:foo].object_id
# => 47106586247680
> hash[:bar].object_id
# => 47106586247680
If you copy-paste the output of your product, you're using 2 different arrays as they get instantiated separately.
It's because the arrays that you pass to your hash initializer are the same object, so if you modify said object, the changes will be present everywhere it is used:
> hash = Hash[[:foo, :bar].product([])]
# => :foo=>, :bar=>
> hash[:foo].object_id
# => 47106586247680
> hash[:bar].object_id
# => 47106586247680
If you copy-paste the output of your product, you're using 2 different arrays as they get instantiated separately.
answered Nov 8 at 17:25
Marcin Kołodziej
3,113313
3,113313
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53213044%2fruby-hash-populated-from-array-product-yields-unexpected-behavior%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown