Description
When using a setter method in Ruby, it always returns its assigned value, regardless of the value returned by the method. Maybe this is intentional, but is inconsistent with Ruby and can cause unexpected problems (which lead me to report this).
For instance:
class Foo
@value = 0
def value=(new_value)
@value = new_value
"Not a number"
end
end
foo1 = Foo.new
puts foo1.value = 42 # Works
foo2 = Foo.new
foo2.value = foo1.value = 42 # Breaks, trying to assign string to Int32
https://play.crystal-lang.org/#/r/6ryq
The last line is something logical users may want to do. But because the return method of value=
is used instead of new_value
, it causes an unexpected compiler error. It tries to assign the string "Not a number" to foo2.value
instead of 42.
With the exact code in Ruby:
class Foo
@value = 0
def value=(new_value)
@value = new_value
"Not a number"
end
end
foo1 = Foo.new
puts foo1.value = 42 # Works
foo2 = Foo.new
foo2.value = foo1.value = 42 # Works (42) assigned to both
https://repl.it/repls/FixedJuniorFinance
I ran into this when I wanted to return an assigned value, but the setter method does some extra computation after setting the value, and that computation result was returned unexpectedly.
Crystal v0.28.0