-1

Consider the following code:

class Cattr
  attr_accessor :attr
  alias_method :a_attr, :attr
  alias_method :a_attr=, :attr=
  def attr ; a_attr ; end
  def attr= value ; a_attr= value ; end
end
ca = Cattr.new
#⇒ #<Cattr:0x000000018974b0>
ca.attr
#⇒ nil
ca.attr = 42
#⇒ 42
ca.attr
#⇒ nil

What? The problem is not with aliasing method, defined by attr_accessor, aliasing getter works pretty fine:

class Cattr
  attr_accessor :attr
  # alias_method :a_attr=, :attr=
  alias_method :a_attr, :attr # still aliased
  # def attr= value ; a_attr= value ; end
  def attr ; a_attr ; end     # still aliased
end

ca = Cattr.new
#⇒ #<Cattr:0x000000018974b0>
ca.attr
#⇒ nil
ca.attr = 42
#⇒ 42
ca.attr
#⇒ 42   # sic!

Sidenote: aliasing attr? method works pretty fine too.

My question would be: is it a known ruby behaviour (aliasing setters is prohibited,) or I am missing something obvious?

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • @jörg-w-mittag Well, great now. How this question is a dup of the linked one? Please point to the answer there, that is applicable as an answer to this question. – Aleksei Matiushkin Mar 22 '16 at 10:49

1 Answers1

2

Setter methods need explicit receivers. Your code:

def attr= value ; a_attr= value ; end

is not calling the setter a_attr=; it is assigning a value to a local variable a_attr.

To do what you want, you need to do:

def attr= value; self.a_attr= value; end
sawa
  • 165,429
  • 45
  • 277
  • 381
  • Thanks. Another thing I just discovered is that setter expects the only parameter. Being wrapped as “generic” `*args`, it results in `[val]` passed to setter instead of `val`. – Aleksei Matiushkin Mar 22 '16 at 10:46