如何减少 Ruby 代码的 nex 行?
How do I reduce the nex lines of Ruby code?
def route_action(action)
case action
when 1 then @meals_controller.add
when 2 then @meals_controller.list
when 3 then @meals_controller.edit
when 4 then @meals_controller.delete
when 5 then @customers_controller.add
when 6 then @customers_controller.list
when 7 then @customers_controller.edit
when 8 then @customers_controller.delete
when 0 then stop
else
puts "Please press 1, 2, 3, 4, 5, 6, 7, 8 or 0"
end
end
所以我想减少这种情况,有没有其他实现方法?
一种可能性是根据用作索引的 action
输入发送一组消息名称,并通过除以 5
来确定发送到哪个控制器.从 1
到 4
的输入将产生 0
,而 5
到 8
将产生 1
.
def route_action
actions = [:add, :list, :edit, :delete]
case action
when 1..8
controller = action / 5 < 1 ? @meals_controller : @customers_controller
msg = actions[(action - 1) % 4]
controller.send(msg)
when 0
stop
else
puts "Please press 1, 2, 3, 4, 5, 6, 7, 8 or 0"
end
end
怎么样:
CASES = [@meals_controller, @customers_controller].product([:add, :list, :edit, :delete])
def route_action(action)
if action > 0
selected = CASES[action-1] # something like [:@meals_controller, :add]
if selected
selected.first.send(*selected.last)
else
puts "action number too large"
end
elsif action == 0
stop
else # Do we have to catch this?
puts "action number negative" # programming error?
end
end
注意,这只是关于如何使用一点 Ruby meta-programming 来摆脱必须声明一个充满案例业务逻辑的长方法的纠结的一般建议。它不会完全适合并且需要额外的工作来完成,例如,“退出”逻辑。
还有。我将重申在对 post 的直接回答之一中所说的话。您的 case
解决方案非常明确。这是很好的代码,我们不应该仅仅为了遵守 all-mighty 样式表指南中的 all-mighty 神灵而跳入更混乱的事情。仅仅因为一个方法少于 10 行,它并不会自动使它比 11(或......地狱 40)行更好。
现在...
这里有一个 meta-programming 建议...
您可以在常量上定义一个散列来保存业务逻辑所需的变量:
ROUTES = [
{ action: :add, controller: :meals, description: "Add a meal" },
{ action: :list, controller: :meals, description: "List all meals" },
{ action: :add, controller: :customers, description: "Add a customers" },
{ action: :list, controller: :customers, description: "List all customers" },
]
然后您可以创建一个方法,使用哈希信息将用户分派到正确的控制器操作:
def dispatch(action_index)
route_action = ROUTES[action_index][:action]
route_controller = ROUTES[action_index][:controller]
instance_variable_get("@#{route_controller}_controller").send(route_action)
end
使用散列迭代它以显示路线描述非常容易:
def display_options
ROUTES.each_with_index do |route, index|
puts "#{index + 1}. #{route[:description]}"
end
end
您可以在代码中的某个时刻使用 dispatch(gets.chomp.to_i - 1)
将用户分派到相关的控制器操作。
散列的妙处在于,您始终可以通过添加一行来为其添加更多路由。
def route_action(action)
case action
when 1 then @meals_controller.add
when 2 then @meals_controller.list
when 3 then @meals_controller.edit
when 4 then @meals_controller.delete
when 5 then @customers_controller.add
when 6 then @customers_controller.list
when 7 then @customers_controller.edit
when 8 then @customers_controller.delete
when 0 then stop
else
puts "Please press 1, 2, 3, 4, 5, 6, 7, 8 or 0"
end
end
所以我想减少这种情况,有没有其他实现方法?
一种可能性是根据用作索引的 action
输入发送一组消息名称,并通过除以 5
来确定发送到哪个控制器.从 1
到 4
的输入将产生 0
,而 5
到 8
将产生 1
.
def route_action
actions = [:add, :list, :edit, :delete]
case action
when 1..8
controller = action / 5 < 1 ? @meals_controller : @customers_controller
msg = actions[(action - 1) % 4]
controller.send(msg)
when 0
stop
else
puts "Please press 1, 2, 3, 4, 5, 6, 7, 8 or 0"
end
end
怎么样:
CASES = [@meals_controller, @customers_controller].product([:add, :list, :edit, :delete])
def route_action(action)
if action > 0
selected = CASES[action-1] # something like [:@meals_controller, :add]
if selected
selected.first.send(*selected.last)
else
puts "action number too large"
end
elsif action == 0
stop
else # Do we have to catch this?
puts "action number negative" # programming error?
end
end
注意,这只是关于如何使用一点 Ruby meta-programming 来摆脱必须声明一个充满案例业务逻辑的长方法的纠结的一般建议。它不会完全适合并且需要额外的工作来完成,例如,“退出”逻辑。
还有。我将重申在对 post 的直接回答之一中所说的话。您的 case
解决方案非常明确。这是很好的代码,我们不应该仅仅为了遵守 all-mighty 样式表指南中的 all-mighty 神灵而跳入更混乱的事情。仅仅因为一个方法少于 10 行,它并不会自动使它比 11(或......地狱 40)行更好。
现在...
这里有一个 meta-programming 建议...
您可以在常量上定义一个散列来保存业务逻辑所需的变量:
ROUTES = [
{ action: :add, controller: :meals, description: "Add a meal" },
{ action: :list, controller: :meals, description: "List all meals" },
{ action: :add, controller: :customers, description: "Add a customers" },
{ action: :list, controller: :customers, description: "List all customers" },
]
然后您可以创建一个方法,使用哈希信息将用户分派到正确的控制器操作:
def dispatch(action_index)
route_action = ROUTES[action_index][:action]
route_controller = ROUTES[action_index][:controller]
instance_variable_get("@#{route_controller}_controller").send(route_action)
end
使用散列迭代它以显示路线描述非常容易:
def display_options
ROUTES.each_with_index do |route, index|
puts "#{index + 1}. #{route[:description]}"
end
end
您可以在代码中的某个时刻使用 dispatch(gets.chomp.to_i - 1)
将用户分派到相关的控制器操作。
散列的妙处在于,您始终可以通过添加一行来为其添加更多路由。