Forum: Ruby Question about op. overloading

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
6a5b5ed39eb9b91797e9e7b6f6362519?d=identicon&s=25 Maarten Mortier (maartenm)
on 2008-12-03 09:55
I have:

class Sudoku
  def[](r,c)
    @rows[r][c]
  end

  def set(r,c,a)
    @rows[r][c]=a
  end
end

Now, how can I define a []= operator instead of the awkward set(r,c,a) ?
I want to be able to do
sudoku[2,3]=candidate

or even
sudoku[2][3] = candidate
and
sudoku[3] = row

Are these things possible? How, I could not find the information.

(I'm just learning, for educational reasons I don't want to extend the
Matrix class)
E088bb5c80fd3c4fd02c2020cdacbaf0?d=identicon&s=25 Jesús Gabriel y Galán (Guest)
on 2008-12-03 10:07
(Received via mailing list)
On Wed, Dec 3, 2008 at 9:49 AM, Maarten Mortier
<maarten.mortier@gmail.com> wrote:
> end
> Are these things possible? How, I could not find the information.
A []= operator is possible. It's syntactic sugar for a method named
"[]="
and at least two parameters: what's inside the brackets and the
"assigned" value.

An example:


irb(main):001:0> class A
irb(main):002:1> def []= (a,b)
irb(main):003:2> @x[a] = b
irb(main):004:2> end
irb(main):005:1> attr_reader :x
irb(main):006:1> def initialize
irb(main):007:2> @x = {}
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> a = A.new
=> #<A:0xb7b2bfa8 @x={}>
irb(main):011:0> a[:a] = :b
=> :b
irb(main):012:0> a
=> #<A:0xb7b2bfa8 @x={:a=>:b}>

If you add more parameters to the method, you can use more "keys"
inside the brackets:

irb(main):013:0> class A
irb(main):014:1> def []= (a,b,c)
irb(main):015:2> puts a,b,c
irb(main):016:2> end
irb(main):017:1> end
=> nil
irb(main):018:0> a = A.new
=> #<A:0xb7b070f4 @x={}>
irb(main):019:0> a[:a,:b] = :c
a
b
c
=> :c

Hope this helps,

Jesus.
6a5b5ed39eb9b91797e9e7b6f6362519?d=identicon&s=25 Maarten Mortier (maartenm)
on 2008-12-03 10:10
Jesús Gabriel y Galán wrote:

> Hope this helps,
>
> Jesus.


So simple, I should have known. :-)

Thank you!

--
Maarten
6a5b5ed39eb9b91797e9e7b6f6362519?d=identicon&s=25 Maarten Mortier (maartenm)
on 2008-12-03 10:20
What about
sudoku[r][c]= a
though?

Is that possible? I thought I'd be able to fluke it by overloading [] to
return an array. But how do I pass parameters inside the bracket?

And how woudl I get

puts sudoku[][3]

to return the third column?
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-12-03 11:26
(Received via mailing list)
2008/12/3 Maarten Mortier <maarten.mortier@gmail.com>:
> What about
> sudoku[r][c]= a
> though?
>
> Is that possible? I thought I'd be able to fluke it by overloading [] to
> return an array. But how do I pass parameters inside the bracket?

You do not need an array but rather a proxy:

class X
  ColProxy = Struct.new :owner, :column do
    def [](row)
      owner.matrix[[column, row]]
    end

    def []=(row,val)
      owner.matrix[[column, row]] = val
    end
  end

  attr_reader :matrix

  def initialize
    @matrix = {}
  end

  def [](column)
    ColProxy.new(self, column)
  end
end

irb(main):026:0> x = X.new
=> #<X:0x7ff5443c @matrix={}>
irb(main):027:0> x[1][2] = 3
=> 3
irb(main):028:0> x[1][2]
=> 3
irb(main):029:0> x
=> #<X:0x7ff5443c @matrix={[1, 2]=>3}>

> And how woudl I get
>
> puts sudoku[][3]
>
> to return the third column?

You can do it similarly.  Just make the argument for X#[] optional and
return another proxy.

I would really rather go with the other approach to stuff all
coordinates in a single pair of brackets and or provide additional
methods.

Kind regards

robert
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-12-03 12:20
Maarten Mortier wrote:
> What about
> sudoku[r][c]= a
> though?
>
> Is that possible?

Simpler would be if you use sudoku[r,c] = a

Just define your []= method to take 3 arguments.

> And how woudl I get
>
> puts sudoku[][3]
>
> to return the third column?

Again, your [] method can take 2 arguments. sudoku[nil,c] could be used
to give the column.

But I think a separate method for this makes more sense: sudoku.col(c)
6a5b5ed39eb9b91797e9e7b6f6362519?d=identicon&s=25 Maarten Mortier (maartenm)
on 2008-12-03 12:22
Brian Candler wrote:

>
> But I think a separate method for this makes more sense: sudoku.col(c)

Yeah that's what I did eventually.

To be honest I could've found all this stuff myself, I was confused by
the output ruby gave me and didn't realize I just needed an extra
parameter.
Sorry and thanks to everyone.
This topic is locked and can not be replied to.