0

I am really confused about the assignment method in Ruby. In the documentation, it says:

Methods that end with an equals sign indicate an assignment method. For assignment methods, the return value is ignored and the arguments are returned instead.

I know this can be use as setter method in Class. However, I still feel confused about the concept. In the code below:

class Foo
  # setter method
  def foo=(x)
    puts "OK: x=#{x}"
  end
end
f = Foo.new
f.foo = 123 # OK: x=123

def a=(value)
  puts "value is #{value}"
end
a = 123     # why there is no output?
p a         # 123, why this only return the argument?
p a = 123   # 123, why this only return the argument?

Why the method with equal sign run differently in the Class and outside the class?

PJCHENder
  • 5,570
  • 3
  • 18
  • 35

2 Answers2

4

a = 123

In principle, there is ambiguity here. Is it a setter invocation or a local variable assignment? Ruby resolves this by choosing local variable assignment. If you want the method, be explicit.

self.a = 123

In the other case, there's no ambiguity.

sawa
  • 165,429
  • 45
  • 277
  • 381
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
4

Seeing something like a = 123, the interpreter assumes that this is always an assignment operation. However, you can call self.a = 123- as this cannot be a proper assignment (variable name cannot include a dot); it will invoke a method you defined.

Note that the same happens inside the class, so it is not a different behaviour:

class Foo
  def foo=(x)
    puts "OK: x=#{x}"
  end

  def bar
    foo = 1
  end

  def baz
    self.foo = 1
  end
end

Calling bar will not print your message, it will just perform an assignment. baz will execute your setter method.

sawa
  • 165,429
  • 45
  • 277
  • 381
katafrakt
  • 2,438
  • 15
  • 19