Skip to content

Inconsistent setter method behavior with Ruby #7707

Open
@icy-arctic-fox

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

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions