<< for Hash?

class Hash
  def <<(arg)
    self.merge!(arg)
  end
end

Eg,

thing = {
  :foo => 1,
}

thing << {
  :bar => 2,
   :baz => 3,
}

thing #=> {:foo=>1, :bar=>2, :baz=>3 }

Of course it overwrites existing keys. I think it's a little sexier than

thing.merge!({
   :bar => 2,
   :baz => 3,
})

or
thing[:bar] = 1
thing[:baz] = 3

Is it safe to use this? Is there some good reason why << is not already
defined for Hash?

Simon
(newbie)

Ps, my first ruby project:
http://tiddlyspot.com/

···

--
Simon Baird <simon.baird@gmail.com>

{:foo,1}.merge! :bar => 2
# {:foo=>1, :bar=>2}

···

On Monday 26 June 2006 13:11, Simon Baird wrote:

class Hash
  def <<(arg)
    self.merge!(arg)
  end
end

Eg,

thing = {

  :foo => 1,

}

thing << {

  :bar => 2,
  :
   :baz => 3,

}

thing #=> {:foo=>1, :bar=>2, :baz=>3 }

Of course it overwrites existing keys. I think it's a little sexier than

thing.merge!({

   :bar => 2,
   :baz => 3,

})

or
thing[:bar] = 1
thing[:baz] = 3

Is it safe to use this? Is there some good reason why << is not already
defined for Hash?

Simon
(newbie)

Ps, my first ruby project:
http://tiddlyspot.com/

The reason is probably that your << appends a complete collection (a
hash) to the hash while usually it appends just a single element (see
for example Array#<< and IO#<<). While I think about it, String#<<
appends the same type (String) to a String...

Kind regards

robert

···

2006/6/26, Simon Baird <simon.baird@gmail.com>:

class Hash
  def <<(arg)
    self.merge!(arg)
  end
end

Eg,

thing = {
  :foo => 1,
}

thing << {
  :bar => 2,
   :baz => 3,
}

thing #=> {:foo=>1, :bar=>2, :baz=>3 }

Of course it overwrites existing keys. I think it's a little sexier than

thing.merge!({
   :bar => 2,
   :baz => 3,
})

or
thing[:bar] = 1
thing[:baz] = 3

Is it safe to use this? Is there some good reason why << is not already
defined for Hash?

--
Have a look: Robert K. | Flickr

but this screws up the scemantics

"<<" is append... and you cant "append" something in a hash , there is
no way to add anything to the end of a hash since items are inserted
based on hashed index.

···

--
Posted via http://www.ruby-forum.com/.

I like Michael's solution.

The {}'s are not needed, as long as the hash is the only or last
argument to a method.

{:a => 1, :b => 2}.merge(:c => 3, :d => 4)
#=> {:a => 1, :b => 2, :c => 3, :d => 4)

···

On 6/26/06, Michael Fellinger <m.fellinger@gmail.com> wrote:

{:foo,1}.merge! :bar => 2
# {:foo=>1, :bar=>2}

On Monday 26 June 2006 13:11, Simon Baird wrote:
> class Hash
> def <<(arg)
> self.merge!(arg)
> end
> end
>
> Eg,
>
> thing = {
>
> :foo => 1,
>
> }
>
> thing << {
>
> :bar => 2,
> :
> :baz => 3,
>
> }
>
> thing #=> {:foo=>1, :bar=>2, :baz=>3 }
>
> Of course it overwrites existing keys. I think it's a little sexier than
>
> thing.merge!({
>
> :bar => 2,
> :baz => 3,
>
> })
>
> or
> thing[:bar] = 1
> thing[:baz] = 3
>
> Is it safe to use this? Is there some good reason why << is not already
> defined for Hash?
>
> Simon
> (newbie)
>
> Ps, my first ruby project:
> http://tiddlyspot.com/

--
Matt

Roger Johansson wrote:

but this screws up the scemantics

"<<" is append... and you cant "append" something in a hash , there is
no way to add anything to the end of a hash since items are inserted
based on hashed index.

That doesn't seem to stop Set#<< :

irb(main):001:0> s = Set[1,2,3]
=> #<Set: {1, 2, 3}>
irb(main):002:0> s << 4
=> #<Set: {1, 2, 3, 4}>

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

I noticed this:

class Hash
  def <<(arg)
    self.merge!(arg)
  end
end

x = { :a => 1 }

x.<< :f => 1, :g => 1 # works

x << :h => 1, :i => 1 # syntax error

Is there a way to make the above work? I don't care really since I think the
following is clearer:
x << { :h => 1, :i => 1 } # my preferred

Cheers,
Simon.

···

On 6/26/06, Matthew Harris <shugotenshi@gmail.com> wrote:

I like Michael's solution.

The {}'s are not needed, as long as the hash is the only or last
argument to a method.

{:a => 1, :b => 2}.merge(:c => 3, :d => 4)
#=> {:a => 1, :b => 2, :c => 3, :d => 4)

--
Simon Baird <simon.baird@gmail.com>

That doesn't seem to stop Set#<< :

irb(main):001:0> s = Set[1,2,3]
=> #<Set: {1, 2, 3}>
irb(main):002:0> s << 4
=> #<Set: {1, 2, 3, 4}>

That's because the semantics make sense in the context of Set. Set acts like
an unordered list, not like a Hash. There's certanily some hand-waiving
going on to make << work with the Hash, but as has been shown, that's not
too tough. IMO, appending '5' to a list of numbers {1,2,3,4} makes sense
while appending a key/value pair doesn't.

From the doc: 'Set
<http://www.ruby-doc.org/core/classes/Set.html&gt;implements a collection
of unordered values with no duplicates. This is a
hybrid of Array <http://www.ruby-doc.org/core/classes/Array.html&gt;&#39;s
intuitive inter-operation facilities and
Hash<http://www.ruby-doc.org/core/classes/Hash.html&gt;&#39;s
fast lookup."

···

On 6/29/06, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

Dean

No, sorry.. as pointed out in another recent thread, overriding the <<
method can change the behaviour but not the syntax of the << operator.

Curses, huh.

;D

···

On 6/27/06, Simon Baird <simon.baird@gmail.com> wrote:

On 6/26/06, Matthew Harris <shugotenshi@gmail.com> wrote:

> I like Michael's solution.
>
> The {}'s are not needed, as long as the hash is the only or last
> argument to a method.
>
> {:a => 1, :b => 2}.merge(:c => 3, :d => 4)
> #=> {:a => 1, :b => 2, :c => 3, :d => 4)
>
I noticed this:

class Hash
  def <<(arg)
    self.merge!(arg)
  end
end

x = { :a => 1 }

x.<< :f => 1, :g => 1 # works

x << :h => 1, :i => 1 # syntax error

Is there a way to make the above work? I don't care really since I think
the
following is clearer:
x << { :h => 1, :i => 1 } # my preferred

--
Daniel Baird
http://danielbaird.com (TiddlyW;nks! :: Whiteboard Koala :: Blog :: Things
That Suck)

Simon Baird wrote:

class Hash
def <<(arg)
   self.merge!(arg)
end
end

class Hash
  alias << merge!
end

cheers

Simon

> That doesn't seem to stop Set#<< :
>
> irb(main):001:0> s = Set[1,2,3]
> => #<Set: {1, 2, 3}>
> irb(main):002:0> s << 4
> => #<Set: {1, 2, 3, 4}>

That's because the semantics make sense in the context of Set. Set acts like
an unordered list, not like a Hash.

I disagree. Mathematically, a essentially hash is just a set of key,
value pairs. It's not *just* a set, due to the requirement that keys
be unique, but it's close enough. So if you can "append" to a set by
adding a value, why not append to a hash by adding a pair?

IMO, appending '5' to a list of numbers {1,2,3,4} makes sense
while appending a key/value pair doesn't.

I don't see any problem with appending a pair to a Hash, as in my mind
it is equivalent to appending a value to a Set. However, I will point
out that the semantics of the proposed Hash#<< and Set#<< *are*
different. Array#<< and Set#<< each expect a single value; if you give
another Array or Set as the argument, it's added as a unit, rather
than iterating over the contents. The proposed Hash#<< on the other
hand *requires* that the argument be a collection of pairs which can
be iterated over. So there is that difference.

I think the utility can overcome that minor semantic difference, however.

Jacob Fugal

···

On 6/29/06, Dean Strelau <dstrelau@gmail.com> wrote:

On 6/29/06, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

imho both appending to set and appending to hash make equal sense/nonsense as
both containers are unorder and have no 'end'.

incidentally, '<<' is not a pure append operator in ruby

   class << self
   end

   42 << 2

   string = <<hdoc
     foobar
   hdoc

food for thought.

-a

···

On Fri, 30 Jun 2006, Dean Strelau wrote:

That's because the semantics make sense in the context of Set. Set acts like
an unordered list, not like a Hash. There's certanily some hand-waiving
going on to make << work with the Hash, but as has been shown, that's not
too tough. IMO, appending '5' to a list of numbers {1,2,3,4} makes sense
while appending a key/value pair doesn't.

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

So if you can "append" to a set by
adding a value, why not append to a hash by adding a pair?

Okay, fair enough.

However, I will point

out that the semantics of the proposed Hash#<< and Set#<< *are*
different. Array#<< and Set#<< each expect a single value; if you give
another Array or Set as the argument, it's added as a unit, rather
than iterating over the contents.

I think this is closer to the point I was trying (unsuccessfully) to make. I
think that having Hash#<< is useful only so long as it complies with the
semantics of what << normally does. As proposed, Hash#<< is really just
Hash#merge! in diguise. There is no reason to make a semantically ambiguous
definition (which you pointed out above) when you could simply use #merge!
instead.

You could write Hash#<< to only accept a single key/value pair and be
semantically meaningful, but there are a few problems with this:

1) As pointed out,

{ :foo => bar } << :a => 1

still doesn't work. It has to be

{ :foo => bar }.<< :a => 1

which IMO is just ugly.

2) When someone tries to append a Hash to a Hash with #<< , what happens?
{ :foo => bar }.<< { :a => 1, :b => 2} #ERR

You can't really do this because it still doesn't make semantic sense. The
whole hash should get added (not each element), but without a key, you can't
add it.

3) Because of the way a Hash works, you can't add multiple values for the
same key, and this is how << is supposed to work. When you say

[1,2,3,4] << 4

=> [1,2,3,4,4] #not [1,2,3,4]
The behavior here is what you would expect from something that "appends,"
while Hash#<< doesn't do the same.

I'm not saying it's a terrible, evil, awful thing to have Hash#<<. I just
think you should think there are a lot of potential negatives, especially
when you could just as easily say Hash#merge!.

···

On 6/29/06, Jacob Fugal <lukfugl@gmail.com> wrote:

Dean

...

incidentally, '<<' is not a pure append operator in ruby

  class << self
  end

  42 << 2

  string = <<hdoc
    foobar
  hdoc

But those aren't other uses of the << operator. Those are "just" syntax.

···

ara.t.howard@noaa.gov wrote:

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Ah, but this is just how a Set works:

  require 'set'
  x = Set[ 1, 2, 3, 4 ]
  x << 4
  p x
  # => #<Set: {1, 2, 3, 4}>, not #<Set: {1, 2, 3, 4, 4}>

And you didn't seem to have a problem with Set#<< earlier... :wink:

Jacob Fugal

···

On 6/29/06, Dean Strelau <dstrelau@gmail.com> wrote:

3) Because of the way a Hash works, you can't add multiple values for the
same key, and this is how << is supposed to work. When you say
> [1,2,3,4] << 4
=> [1,2,3,4,4] #not [1,2,3,4]
The behavior here is what you would expect from something that "appends,"
while Hash#<< doesn't do the same.

hmmm. you are right in two of three. but Fixnum#<< is definitely a method.
in any case ruby has precedent for '<<' meaning other things besides only
'append'.

cheers.

-a

···

On Fri, 30 Jun 2006, Joel VanderWerf wrote:

ara.t.howard@noaa.gov wrote:
...

incidentally, '<<' is not a pure append operator in ruby

  class << self
  end

  42 << 2

  string = <<hdoc
    foobar
  hdoc

But those aren't other uses of the << operator. Those are "just" syntax.

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

...

incidentally, '<<' is not a pure append operator in ruby

  class << self
  end

  42 << 2

  string = <<hdoc
    foobar
  hdoc

But those aren't other uses of the << operator. Those are "just" syntax.

hmmm. you are right in two of three. but Fixnum#<< is definitely a method.
in any case ruby has precedent for '<<' meaning other things besides only
'append'.

Can't we see shifting an Integer the same as appending zeroes on one end of it? Just to play the devil's advocate...

Guillaume.

···

Le 29 juin 06, à 19:04, ara.t.howard@noaa.gov a écrit :

On Fri, 30 Jun 2006, Joel VanderWerf wrote:

ara.t.howard@noaa.gov wrote:

cheers.

-a
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama