I want to do some checking in a writer accessor. My first idea was returning a boolean.
class MyClass
def var=(var)
@var = var
# some checking
return true
end
end
m = MyClass.new
retval = (m.var = 'foo')
=> "foo"
Can I set a return value in a writer accessor? If yes, how can I get this value?
I would use set_var(var) instead of what you are trying to do, an attribute writer is assumed to just work. What you are trying to do is nonstandard and non-obvious to the next poor person to use your code. (It may just be yourself) I would throw an exception if bad input is sent or something rather exceptional happens.
You want this behavior
Correct
>>temp = object.var = 7
=> 7
Wrong
>>temp = object.var = 7
=> false
The = operator should always return the value that was passed to it. Ruby uses implicit returns which is uncommon in programming languages. Double check the returns when you use method=()
.
class Test
def var=(var)
@var = var
return true
end
end
t1, t2 = Test.new, Test.new
t1.var = 123 # evaluates to 123
# Why is it impossible to return something else:
t1.var = t2.var = 456
As stated in the comment: I believe it's impossible to change the return value in order to allow chained assignments. Changing the return value would probably be unexpected by the majority of Ruby programmers anyway.
Disclaimer: I tested the code above but I've found no explicit references to verify my statement.
Update
class Test
def method_missing(method, *args)
if method == :var=
# check something
@var = args[0]
return true
else
super(method, *args)
end
end
def var
@var
end
end
t = Test.new
t.var = 123 # evaluates to 123
t.does_not_exists # NoMethodError
It really seems to impossible! The above sample suggests that the return value isn't related to the var=
method at all. You cannot change this behavior - it's the fundamental way how Ruby assignments work.
Update 2: Solution found
You could raise an exception!
class Test
def var=(var)
raise ArgumentError if var < 100 # or some other condition
@var = var
end
def var
@var
end
end
t = Test.new
t.var = 123 # 123
t.var = 1 # ArgumentError raised
t.var # 123
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With