# Re: how to define []=

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

Just define it.

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

On Sat, Jan 23, 2010 at 2:29 PM, hagbard [email protected]
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], , [20, 21, 22] ]
q = QQ.new( a )
puts q[2, 1]
q[2, 1] = 2211
puts q[2, 1]

hagbard wrote:

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

Just define it.

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

Thanks! Colin B. wrote:

On Sat, Jan 23, 2010 at 2:29 PM, hagbard [email protected]
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!

Colin B. wrote:

On Sat, Jan 23, 2010 at 2:29 PM, hagbard [email protected]
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], , [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
[email protected]

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
q = 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 = 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!

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=2
a= 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