# Interaction of attr_accessor and |= operator

I understand that `x |= y`

basically means `x = x|y`

. The operator `|`

is defined for the class `Set`

as calculating the union of two sets. Indeed we can see:

require 'set' r = Set.new(%w(a b)); s = Set.new(%w(c d)); r |= s; # r => #<Set: {"a", "b", "c", "d"}>

But see for instance the following class definition:

class Demo; def initialize(s); @x = s.dup; end; attr_accessor :x; def m!(t); x |= t.x; ' <--- HERE TROUBLE! end;

end

I’m using this class like this:

u = Demo.new(Set.new(%w(a b))) v = Demo.new(Set.new(%w(c d))) u.m!(v)

If I now look at u.x, I see that it still holds the set *a,b* and not *a,b,c,d*. My feeling is that this comes from the fact I’m using the attribut accessor, in particular the setter method. If I would write `@x |= t.x`

, it would work. Could it be that the left hand side of `x |= t.x`

uses the *getter* `x`

and not the *setter* `x=`

, thereby creating the union in a temporary Set object?

BTW, I’m using a fairly old version of Ruby (JRuby 1.7.x, corresponding roughly to the language version of Ruby 1.9.3).

## Answer

The reason for this is that in

x = 3

`x`

is always interpreted as a local variable before ruby starts looking for a method `x=`

. This means, that your method translates to:

def m!(t) x = nil # local variable initialization x = x | t.x end;

To solve this, you need to use explicit `self`

to force method call:

def m!(t); self.x |= t.x end

Another note – please do not use semicolons in ruby. There are only a very rare situations they needed but we generally avoid them