Trying to do something weird that might turn into something more useful, I tried to define my own []= operator on a custom class, which you can do, and have it return something different than the value argument, which apparently you can’t do. []= operator’s return value is always value; even when you override this operator, you don’t get to control the return value.
class Weird
def []=(key, value)
puts "#{key}:#{value}"
return 42
end
end
x = Weird.new
x[:a] = "a"
output "a:a"
return value => "a" # why not 42?
Does anyone have an explanation for this? Any way around it?
ruby MRI 1.8.7. Is this the same in all rubys; Is it part of the language?
Note that this behavior also applies to all assignment expressions (i.e. also attribute assignment methods:
def a=(value); 42; end).My guess is that it is designed this way to make it easy to accurately understand assignment expressions used as parts of other expressions.
For example, it is reasonable to expect
x = y.a = z[4] = 2to:z.[]=(4,2), theny.a=(2), then2to the local variablex, then finally2to any “surrounding” (or lower precedence) expression.This follows the principle of least surprise; it would be rather surprising if, instead, it ended up being equivalent to
x = y.a=(z.[]=(4,2))(with the final value being influenced by both method calls).While not exactly authoritative, here is what Programming Ruby has to say:
Programming Ruby (1.8), in the Expressions section:
Programming Ruby 1.9 (3rd ed) in section 22.6 Expressions, Conditionals, and Loops:
(right after describing
[]=method calls)