# Re: how to define \[\]=

**URL:** <https://www.ruby-forum.com/t/re-how-to-define/182149>\
**Category:** Ruby\
**Created:** [January 23, 2010, 3:30pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149 "2010-01-23T15:30:05Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 23, 2010, 3:30pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/1 "2010-01-23T15:30:05Z")

</div>

> But how do we define the set method `[]=’?

Just define it.

def []=(i, value)  
@ary[i] = value  
end

---

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 23, 2010, 4:55pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/2 "2010-01-23T16:55:31Z")

</div>

On Sat, Jan 23, 2010 at 2:29 PM, hagbard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > But how do we define the set method `[]='?
> 
> Just define it.  
> def []=(i, value)  
> @ary[i] = value  
> end

And for a two dimensional array:  
class QQ  
def initialize( arr ) ; @ary = arr ; end  
def []( i, j ) ; @ary[i][j] ; end  
def []=( i, j, value ) ; @ary[i][j] = value ; end  
end

a = [[0, 1], [10], [20, 21, 22] ]  
q = QQ.new( a )  
puts q[2, 1]  
q[2, 1] = 2211  
puts q[2, 1]

---

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 23, 2010, 5:28pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/3 "2010-01-23T17:28:43Z")

</div>

hagbard wrote:

> > But how do we define the set method `[]=’?
> 
> Just define it.
> 
> def []=(i, value)  
> @ary[i] = value  
> end

Thanks! 🙂

---

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 23, 2010, 5:30pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/4 "2010-01-23T17:30:24Z")

</div>

Colin B. wrote:

> On Sat, Jan 23, 2010 at 2:29 PM, hagbard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > > But how do we define the set method `[]='?
> > 
> > Just define it.  
> > def []=(i, value)  
> > ï¿½ @ary[i] = value  
> > end
> 
> And for a two dimensional array:  
> class QQ  
> def initialize( arr ) ; @ary = arr ; end  
> def []( i, j ) ; @ary[i][j] ; end  
> def []=( i, j, value ) ; @ary[i][j] = value ; end  
> end

I dint know it also works for multi-dimension arrays…  
Thanks!

---

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 23, 2010, 5:55pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/5 "2010-01-23T17:55:25Z")

</div>

Colin B. wrote:

> On Sat, Jan 23, 2010 at 2:29 PM, hagbard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > > But how do we define the set method `[]='?
> > 
> > Just define it.  
> > def []=(i, value)  
> > ï¿½ @ary[i] = value  
> > end
> 
> And for a two dimensional array:  
> class QQ  
> def initialize( arr ) ; @ary = arr ; end  
> def []( i, j ) ; @ary[i][j] ; end  
> def []=( i, j, value ) ; @ary[i][j] = value ; end  
> end

First of all, I don’t think that will work. Second, it’s a bad idea: to  
experienced Ruby programmers, [i, j] is slicing, not subscripting. Just  
use the standard [i][j].

> a = [[0, 1], [10], [20, 21, 22] ]  
> q = QQ.new( a )  
> puts q[2, 1]  
> q[2, 1] = 2211  
> puts q[2, 1]

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 24, 2010, 5:04am UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/6 "2010-01-24T05:04:41Z")

</div>

On Sat, Jan 23, 2010 at 4:56 PM, Marnen Laibow-Koser wrote:

> Second, it’s a bad idea: to experienced Ruby programmers,  
> [i, j] is slicing, not subscripting. Just use the standard [i][j].

You’re right to observe that it’s likely to be confused with slice,  
a point which had escaped me when I made my post:  
arr = [0, 1, 2, 3, 4] #=\> [0, 1, 2, 3, 4]  
arr[1, 3] = 7 #=\> 7  
arr #=\> [0, 7, 4]  
So, yes, the sort of thing in my post should almost always be avoided.

That said, there may be occasions when it might be useful,  
suitably documented of course!

> First of all, I don’t think that will work.

Well, things like that worked a year or so ago,  
when I was looking closely into how Ruby assignment  
worked with []= methods, and they still seem to work!  
I think the following shows how Ruby deals with  
a mix of arguments on the LHS and RHS  
of an assignment method which uses []=

class QQ  
def []=( \*args )  
puts "#args== " + args.inspect  
# you can put some complicated code here  
# which relies on the structure of args  
end  
end  
q = QQ.new #=\> #QQ:0x2746040

q[] = 100 #args== [100] #=\> 100  
q[0] = 100 #args== [0, 100] #=\> 100  
q[0, 1] = 100 #args== [0, 1, 100] #=\> 100  
q[0, 1, 2] = 100 #args== [0, 1, 2, 100] #=\> 100

q[] = 100, 101 #args== [[100, 101]] #=\> [100, 101]  
q[0] = 100, 101 #args== [0, [100, 101]] #=\> [100, 101]  
q[0, 1] = 100, 101 #args== [0, 1, [100, 101]] #=\> [100, 101]  
q[0, 1, 2] = 100, 101 #args== [0, 1, 2, [100, 101]] #=\> [100, 101]

You can even do things like:  
q[0, [10, 11], 2] = 100, 101 #args== [0, [10, 11], 2, [100, 101]]  
#=\> [100, 101]

But I’ll end by repeating my endorsement of your admonishment!

---

<div class="post-metadata">

**Author:** ![hagbard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/d26b3c/32.png) [@hagbard](https://www.ruby-forum.com/u/hagbard)\
**Post date:** [January 24, 2010, 12:53pm UTC](https://www.ruby-forum.com/t/re-how-to-define/182149/7 "2010-01-24T12:53:25Z")

</div>

On 01/24/2010 05:03 AM, Colin B. wrote:

> That said, there may be occasions when it might be useful,  
> suitably documented of course!

Adding to that: there is a significant drawback to doing [][]: you need  
to return an object from the first [] in order to be able to invoke the  
second []. Depending on the internal implementation of the class this  
might be easy (i.e. if you have that object, say a nested Array, anyway)  
or it might impose some overhead (i.e. if the internal structure is  
different and you need to return a proxy object for the sole purpose of  
receiving the second [].

> > First of all, I don’t think that will work.
> 
> Well, things like that worked a year or so ago,

It will certainly work as Colin demonstrated. Since the advent of 1.9  
we have extended pattern matching for block and method arguments, so we  
can do things like this:

irb(main):001:0\> class X  
irb(main):002:1\> def []=(\*a,b)  
irb(main):003:2\> printf “a=%p b=%p\n”,a,b  
irb(main):004:2\> end  
irb(main):005:1\> end  
=\> nil  
irb(main):006:0\> o = X.new  
=\> #\<X:0x8d77aec\>  
irb(main):007:0\> o[1,2,3]=567  
a=[1, 2, 3] b=567  
=\> 567  
irb(main):008:0\> o[1,2,3]=567,234  
a=[1, 2, 3] b=[567, 234]  
=\> [567, 234]  
irb(main):009:0\> o[1]=2  
a=[1] b=2  
=\> 2  
irb(main):010:0\> o[1,2]=3  
a=[1, 2] b=3  
=\> 3  
irb(main):011:0\>

In other words: it’s easier to analyze argument lists.

Kind regards

robert
