I’m wondering what’s the canonical way in Ruby to create custom setter and getter methods. Normally, I’d do this via attr_accessor but I’m in the context of creating a DSL. In a DSL, setters are called like this (using the = sign will create local variables):
work do
duration 15
priority 5
end
Therefore, they must be implemented like this:
def duration(dur)
@duration = dur
end
However this makes implementing a getter a bit tricky: creating a method with the same name but with no arguments will just overwrite the setter.
So I wrote custom methods that do both the setting and the getting:
def duration(dur=nil)
return @duration = dur if dur
return @duration if @duration
raise AttributeNotDefinedException, "Attribute '#{__method__}' hasn't been set"
end
Is this a good way to go about it? Here’s a gist with test cases:
Thanks!
The trickier case is if you want to set duration to nil. I can think of two ways of doing this
Allow people to pass any number of args and decide what to do based on the number. You could also raise an exception if more than one argument is passed.
Another way is
This exploits default arguments a little: they can be pretty much any expression.
When called with no arguments
getteris set to true, but when an argument is supplied (even if it is nil) the default value is not evaluated. Because of how local variable scope worksgetterends up nil.Possibly a little too clever, but the method body itself is cleaner.