# Defining \<\<

**URL:** <https://www.ruby-forum.com/t/defining/84815>\
**Category:** Ruby\
**Created:** [February 7, 2007, 10:46pm UTC](https://www.ruby-forum.com/t/defining/84815 "2007-02-07T22:46:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![technodolt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e99b99/32.png) [@technodolt](https://www.ruby-forum.com/u/technodolt)\
**Post date:** [February 7, 2007, 10:46pm UTC](https://www.ruby-forum.com/t/defining/84815/1 "2007-02-07T22:46:53Z")

</div>

I’m not 100% how exactly to search to find out if someone else has posed  
this question, but why does the following happen?

Given:

class Hash  
def \<\< (key, val=nil)  
self.store(key, val)  
end  
end

h = {}  
h \<\< ‘test’  
h \<\< ‘test’, ‘bob’

Gives back:

test.rb:9: parse error, unexpected ‘,’, expecting $  
h \<\< ‘test’, ‘bob’

If I change the last line to:

h \<\< (‘test’, ‘bob’)

I get back:

test.rb:9: parse error, unexpected ‘,’, expecting ‘)’  
h \<\< (‘test’, ‘bob’)

---

<div class="post-metadata">

**Author:** ![technodolt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e99b99/32.png) [@technodolt](https://www.ruby-forum.com/u/technodolt)\
**Post date:** [February 7, 2007, 10:51pm UTC](https://www.ruby-forum.com/t/defining/84815/2 "2007-02-07T22:51:49Z")

</div>

on occasion this space  
def \<\< (key, val=nil)

---

<div class="post-metadata">

**Author:** ![technodolt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e99b99/32.png) [@technodolt](https://www.ruby-forum.com/u/technodolt)\
**Post date:** [February 7, 2007, 10:52pm UTC](https://www.ruby-forum.com/t/defining/84815/3 "2007-02-07T22:52:12Z")

</div>

on occasion this space  
def \<\< (key, val=nil)  
^

causes problems

---

<div class="post-metadata">

**Author:** ![technodolt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e99b99/32.png) [@technodolt](https://www.ruby-forum.com/u/technodolt)\
**Post date:** [February 7, 2007, 10:59pm UTC](https://www.ruby-forum.com/t/defining/84815/4 "2007-02-07T22:59:49Z")

</div>

On Feb 7, 2007, at 4:46 PM, Luke I. wrote:

> end
> 
> h = {}  
> h \<\< ‘test’  
> h \<\< ‘test’, ‘bob’

The syntax rules for the \<\< operator don’t allow it to take multiple  
arguments when called via infix notation:

h \<\< arg1 # one argument only

you can call the method with multiple arguments but you’ve got to do  
it like:

h.\<\<(arg1, arg2) # dot-style method invocation

You can use an array to ‘cheat’:

h \<\< [arg1, arg2]

But the method will only see one argument, an array, and you would have  
to expect that and/or test for it in your definition for Hash#\<\<.

Gary W.

---

<div class="post-metadata">

**Author:** ![technodolt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e99b99/32.png) [@technodolt](https://www.ruby-forum.com/u/technodolt)\
**Post date:** [February 8, 2007, 10:05am UTC](https://www.ruby-forum.com/t/defining/84815/5 "2007-02-08T10:05:43Z")

</div>

Robert K. wrote:

> […]  
> irb(main):013:0\> h \<\< “foo” \<\< “bar” \<\< “key” \<\< 234  
> […]
> 
> Not that I would recommend it…

Yeah, i like

h \<= “foo” \> “bar” \<= “key” \> 42

🙂

unfortunately there is no =\> operator…

cheers

Simon

---

<div class="post-metadata">

**Author:** ![technodolt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e99b99/32.png) [@technodolt](https://www.ruby-forum.com/u/technodolt)\
**Post date:** [February 7, 2007, 11:11pm UTC](https://www.ruby-forum.com/t/defining/84815/6 "2007-02-07T23:11:52Z")

</div>

On 07.02.2007 22:58, Gary W. wrote:

> > ```
> > self.store(key, val)
> > 
> > ```
> 
> h \<\< arg1 # one argument only  
> But the method will only see one argument, an array, and you would have  
> to expect that and/or test for it in your definition for Hash#\<\<.

Here’s another variant:

class Hash  
Proxy = Struct.new :parent, :key do  
def \<\<(val)  
parent[key] = val  
parent  
end  
end  
def \<\<(key)  
Proxy.new self, key  
end  
end

irb(main):012:0\> h ={}  
=\> {}  
irb(main):013:0\> h \<\< “foo” \<\< “bar” \<\< “key” \<\< 234  
=\> {“foo”=\>“bar”, “key”=\>234}  
irb(main):014:0\> h \<\< 2 \<\< 3  
=\> {2=\>3, “foo”=\>“bar”, “key”=\>234}  
irb(main):015:0\> h  
=\> {2=\>3, “foo”=\>“bar”, “key”=\>234}

Not that I would recommend it…

Kind regards

robert
