我希望简化在多个条件适用时执行单个操作的代码。这是一个简化的例子:
case button
when 'up', 'upper-right', 'right', 'lower-right', 'down', 'lower-left', 'left', 'upper-left'
move_direction(button)
else
do_something_else
end
如果我可以将这些选项封装成类或常量之类的东西,那将会有所帮助,但我不知道该怎么做或者甚至可能。我怎样才能封装这些条件?
答案 0 :(得分:7)
你可以使用数组splat。
VALID_DIRECTION = %w( upper-left up upper-right left right
lower-right down lower-left )
case button
when *VALID_DIRECTION
move_direction(button)
else
do_something_else
end
答案 1 :(得分:4)
不太确定你在寻找什么,但也许是这样的?
class CaseMatchingArray < Array
def ===(element)
self.include?(element)
end
end
direction = CaseMatchingArray.new([
'up', 'upper-right', 'right', 'lower-right',
'down', 'lower-left', 'left', 'upper-left'])
case 'up'
when direction
puts "Yup, it's a direction"
end
请记住,Ruby case
语句应用===
运算符,您可以通过匹配实现它的内容来执行您希望的任何测试。如果您还记得Proc
也实施了===
作为通话,您可以这样做:
direction = lambda { |x|
[
'up', 'upper-right', 'right', 'lower-right',
'down', 'lower-left', 'left', 'upper-left'
].include?(x)
}
并且在没有定义类的情况下具有相同的结果。或者你甚至可以用单身人士来做这件事:
direction = [
'up', 'upper-right', 'right', 'lower-right',
'down', 'lower-left', 'left', 'upper-left'
]
def direction.===(other)
self.include?(other)
end
编辑:或者Chuck说的:)虽然实现定义===
的对象更为通用,但不仅限于数组的成员资格。
答案 2 :(得分:3)
下面的解决方案并不是特别复杂,但它可以说比原始案例陈述更具可读性。
def is_navigatable?(button)
['up',
'upper-right',
'right',
'lower-right',
'down',
'lower-left',
'left',
'upper-left'
].member? button
end
def main_method
if is_navigatable? button
move_direction button
else
do_something_else
end
end
答案 3 :(得分:1)
如果我可以将这些选项封装成类或常量之类的东西,那将会有所帮助,但我不知道该怎么做或者甚至可能。我怎样才能封装这些条件?
为什么不简单地重构该代码以放弃case-while
条件而只使用if-else
代替(因为您似乎没有使用其他选项):
OPTIONS = 'up', 'upper-right', 'right', 'lower-right', 'down', 'lower-left', 'left', 'upper-left'
if OPTIONS.include? button
move_direction(button)
else
do_something_else
end
答案 4 :(得分:0)
最快的方法是使用套装
require 'set'
def direction?(button)
directions = Set[:up,
:'upper-right',
:right,
:'lower-right',
:down,
:'lower-left',
:left,
:'upper-left']
directions.include?(button)
end
button = 'up'
puts direction?(button.to_sym) #true
答案 5 :(得分:0)
在您的特定情况下,您也可以这样做:
case button
when "up", "down", /\A(?:upper-|lower-|)(?:right|left)\z/
move_direction(button)
else
do_something_else
end