2

I have this class definition:

class Test attr_accessor :state def multiple_state=(times) @state *= times end end obj = Test.new obj.state = 2 puts #{obj.multiple_state=4} 

I thought the output is 8, coz that is the value of the last expression evaluated in multiple_state. (?)

But the output is 4.

Is my understanding of last expression evaluated wrong?

Thanks.

1 Answer 1

4

Ruby's syntactic sugar for setter methods always returns the right side of the assignment, even if you do something else in your method. The Well-Grounded Rubyist puts it better than I could:

Setter methods don’t return what you might think. When you use the syntactic sugar that lets you make calls to = methods that look like assignments, Ruby takes the assignment semantics seriously. Assignments (like x = 1) evaluate to whatever’s on their right-hand side. Methods usually return the value of the last expression evaluated during execution. But = method calls behave like assignments: the value of the expression ticket.price = 63.00 is 63.00, even if the ticket= method returns the string "Ha ha!". The idea is to keep the semantics consistent. Under the hood, it’s a method call; but it looks like an assignment and behaves like an assignment with respect to its value as an expression.

The Well-Grounded Rubyist - Chapter 3.3.3

Sign up to request clarification or add additional context in comments.

2 Comments

So even if you have a return statement explicitly in = method, the value is still the right-hand side? like is always 63.0? what if i want to return something? or that is something meaningless in = method?
The return value of the method is not meaningless. It will be returned from the method. But assignments always evaluate to the value that is being assigned. So, you can't use assignment syntax to call the method. But you can use public_send, send or __send__.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.