Does Ruby even support compound operators like "<<|" and "<<&"? Dave On Aug 17, 2013, at 11:48 AM, alexeymuranov (Alexey Muranov) wrote: >=20 > Issue #8772 has been updated by alexeymuranov (Alexey Muranov). >=20 >=20 > =3Dbegin > How about (({Hash#<<})) for (({#merge!})) (plus, maybe extra = functionality suggested by Thomas), (({Hash#<<|})) for = (({#reverse_merge!})) (plus extra), (({Hash#<<&})) for (({#merge!})) = which only touches existing keys (plus extra): >=20 > { :a =3D> 1, :b =3D> 2 } << { :b =3D> 1, :c =3D> 2 } # =3D> { :a =3D>= 1, :b =3D> 1, :c =3D> 2 } >=20 > { :a =3D> 1, :b =3D> 2 } <<| { :b =3D> 1, :c =3D> 2 } # =3D> { :a =3D>= 1, :b =3D> 2, :c =3D> 2 } >=20 > { :a =3D> 1, :b =3D> 2 } <<& { :b =3D> 1, :c =3D> 2 } # =3D> { :a =3D>= 1, :b =3D> 1 } >=20 > Everything changes the receiver in place. >=20 > (I am not opening a new ticket for this because i am not yet sure i am = excited about quite different behavior of #<< in different classes.) > =3Dend >=20 > ---------------------------------------- > Feature #8772: Hash alias #| merge, and the case for Hash and Array = polymorphism > https://bugs.ruby-lang.org/issues/8772#change-41228 >=20 > Author: trans (Thomas Sawyer) > Status: Open > Priority: Normal > Assignee:=20 > Category: core > Target version: current: 2.1.0 >=20 >=20 > Ideally Hash and Array would be completely polymorphic in every manner = in which it is possible for them to be so. The reason for this is very = simple. It makes a programmer's life easier. For example, in a recent = program I was working on, I had a list of keyboard layouts. >=20 > layouts =3D [layout1, layout2, layout3] >=20 > Later I realized I wanted to identify them by a label not an index. = So... >=20 > layouts =3D {:foo =3D> layout1, :bar =3D> layout2, :baz =3D> layout3} >=20 > Unfortunately this broke my program in a number of places, and I had = to go through every use of `layouts` to translate what was an Array call = into a Hash call. If Array and and Hash were more polymorphic I would = have only had to adjust the places were I wanted to take advantage of = the Hash. Ideally almost nothing should have actually broken.=20 >=20 > The achieve optimal polymorphism between Hash and Array is to treat a = Hash's keys as indexes and its values as as the values of an array. e.g. >=20 > a =3D [:a,:b,:c] > h =3D {0=3D>:a,1=3D>:b,2=3D>:c} > a.to_a #=3D> [:a,:b,:c] > h.to_a #=3D> [:a,:b,:c] >=20 > Of course the ship has already sailed for some methods that are not = polymorphic, in particular #each. Nonetheless it would still be wise to = try to maximize the polymorphism going forward. (Perhaps even to be = willing to take a bold leap in Ruby 3.0 to break some backward = compatibility to improve upon this.) >=20 > In the mean time, let us consider what it might mean for Hash#+ as an = alias for #merge, *if the above were so*: >=20 > ([:a,:b] + [:c,:d]).to_a =3D> [:a,:b,:c,:d] > ({0=3D>:a,1=3D>:b} + {2=3D>:c,3=3D>:d}).to_a =3D> [:a,:b,:c,:d] >=20 > ([:a,:b] + [:a,:b]).to_a =3D> [:a,:b,:a,:b] > ({0=3D>:a,1=3D>:b} + {0=3D>:a,1=3D>:b}).to_a =3D> [:a,:b] >=20 > Damn! So it appears that #+ isn't the right operator. Let's try #| = instead. >=20 > ([:a,:b] | [:c,:d]).to_a =3D> [:a,:b,:c,:d] > ({0=3D>:a,1=3D>:b} | {2=3D>:c,3=3D>:d}).to_a =3D> [:a,:b,:c,:d] >=20 > ([:a,:b] | [:a,:b]).to_a =3D> [:a,:b] > ({0=3D>:a,1=3D>:b} | {0=3D>:a,1=3D>:b}).to_a =3D> [:a,:b] >=20 > Bingo. So I formally stand corrected. The best alias for merge is #| = not #+.=20 >=20 > Based on this line of reasoning I formally request the Hash#| be an = alias of Hash#merge. >=20 > P.S. Albeit, given the current state of polymorphism between Ruby's = Array and Hash, and the fact that it will probably never be improved = upon, I doubt it really matters which operator is actually used. >=20 >=20 >=20 > --=20 > http://bugs.ruby-lang.org/