我想用case
替换ruby中的Hash
语句。但是当我尝试在哈希中查找其他键时,Hash似乎首先调用默认值。
def perform_operation_one
puts 'Performing operation ONE'
end
def perform_operation_two
puts 'Performing operation TWO'
end
def exit_program
puts 'Program is exiting now'
exit(0)
end
def perform_operation(operation_code)
case operation_code
when 1
perform_operation_one
when 2
perform_operation_two
else
exit_program
end
end
我将上述case
语句替换为Hash
def perform_operation(operation_code)
operations = Hash.new exit_program #Default value if no operation is present in operations corresponding to operation_code key
operations[1] = perform_operation_one
operations[2] = perform_operation_two
operations[operation_code]
end
现在我执行以下操作:
perform_operation(2)
预期产出:
Performing operation TWO
当前输出:
Program is exiting now
答案 0 :(得分:3)
问题在于这一行:
operations = Hash.new exit_program
在达到该行代码时对exit_program
进行评估。
你在这里尝试做的是将一个方法作为一个值传递,你可以做,但它并不像Javascript那么简单,只需输入方法名就足够了。请记住,在Ruby括号中对于方法调用是可选的,因此您的默认值最终是exit_program
的返回值(在这种情况下,自程序退出以来未定义) )。
你可以对你的方法进行lambda-fy(让它们作为值传递),如下所示:
def perform_operation(operation_code)
operations = Hash.new(-> { exit_program })
operations[1] = -> { input_from_file }
operations[2] = -> { input_from_console }
operations[operation_code].call
end
我基本上在-> { }
(匿名函数/ lambda)中包装每个方法。 .call
就在那里,因为您指定了评估lambda的时间(调用方法)。
除了使用-> { }
之外,您还可以使用method(:exit_program)
,method(:input_from_file)
等。它会转换为proc,但它基本上是相同的,您仍然使用{{ 1}}。
答案 1 :(得分:1)
首先,我认为你的case
没问题。它具有可读性,并且可能比带有哈希的解决方案更容易出错。
使用哈希,你可以写:
def perform_operation(operation_code)
operations = { 1 => :perform_operation_one, 2 => :perform_operation_two }
operations.default = :exit_program
send(operations[operation_code])
end
由于send
不关心方法隐私,因此您可以将exit_program
,perform_operation_{one,two}
设置为私有。事实上,在main
中定义时,它们已经是私有的。