But let's assume you have to call a method that expects a boolean parameter like:
class Human def go backward=false puts "#{self.class} is going " + (backward ? "backward" : "forward") end endA human can go forward and backward.
We want a human to go backward. If you would code it this way:
human = Human.new # human goes backward human.go trueplease go on reading, because there is something to improve. At first the output is as expected:
Human is going backwardThe code works but you have to agree, that "human.go true" is not readable (that's why there is a line of documentation). But we can improve the readability:
human = Human.new human.go :backwardalso results in:
Human is going backwardIn Ruby a Symbol and all objects except instances of Nil and False class are true. Besides using an expressive Symbol can save the line of documentation, because the code documents itself. Awesome! Going forward could be default or explicit:
human = Human.new human.go # default forward human.go not(:backward) # explicitThe "not" before the Symbol inverts the assigned parameter. You also could use a bang ("human.go !:backward"). The result:
Human is going forward Human is going forwardThough I'd prefer having a well designed API method ;-)
Supported by Ruby 1.9.3
not(:backward) is a bit awkward. Instead I would suggest:
AntwortenLöschenclass Human
DIRECTIONS = [ :forward, :backward ]
def go (direction = :forward)
# in the real world, one could also convert strings to
# symbols, and construct instructions from valid-value list.
raise "Invalid direction; must use :forward or :backward." unless DIRECTIONS.include?(direction)
puts "is going #{direction}"
end
end
(Forgive the lack of indentation; I put it in, but the preview shows it being stripped out.)
That code still seems a bit clumsy to me, though; maybe there's a better way, without all the overhead of declaring a new class specifically to hold directions or something like that. (In C, I would just make it an enum type.)
Hi Dave,
AntwortenLöschenit looks like I didn't make clear enough the intention of the post. The post was not intended to design a method without having a boolean parameter. At the beginning I also pointed out that a boolean parameter should be avoided. The post was about how to deal with an already existing method (say an API receiver like RubyOnRails or others) having a boolean parameter in a clean way.
If you suggest a cleaner way, how to deal with boolean parameters, please let me know.