Entiendo que x |= y básicamente significa x = x|y . El operador | se define para la clase Set como el cálculo de la unión de dos conjuntos. Efectivamente podemos ver:
require 'set' r = Set.new(%w(ab)); s = Set.new(%w(cd)); r |= s; # r => #<Set: {"a", "b", "c", "d"}>Pero vea, por ejemplo, la siguiente definición de clase:
class Demo; def initialize(s); @x = s.dup; end; attr_accessor :x; def m!(t); x |= tx; ' <--- HERE TROUBLE! end;fin
Estoy usando esta clase así:
u = Demo.new(Set.new(%w(ab))) v = Demo.new(Set.new(%w(cd))) um!(v) Si ahora observo ux, veo que aún contiene el conjunto a,b y no a,b,c,d . Mi sensación es que esto proviene del hecho de que estoy usando el atributo de acceso, en particular el método setter. Si escribiera @x |= tx , funcionaría. ¿Podría ser que el lado izquierdo de x |= tx use el getter x y no el setter x= , creando así la unión en un objeto Set temporal?
Por cierto, estoy usando una versión bastante antigua de Ruby (JRuby 1.7.x, que corresponde aproximadamente a la versión de idioma de Ruby 1.9.3).
La razón de esto es que en
x = 3 x siempre se interpreta como una variable local antes de que Ruby comience a buscar un método x= . Esto significa que su método se traduce en:
def m!(t) x = nil # local variable initialization x = x | tx end; Para resolver esto, debe usar self explícito para forzar la llamada al método:
def m!(t); self.x |= tx endOtra nota: no use punto y coma en Ruby. Solo hay situaciones muy raras que necesitaban, pero generalmente las evitamos.