Ruby开关式习惯用法
我最近在RubyonRails上启动了一个项目。我以前用Python做过所有的项目,但我决定尝试一下Ruby 在我用Python编写的项目中,我使用了一种很好的小技巧,这篇文章给出了正确的答案: 我之所以使用这种技术,是因为Python没有本机开关函数,而且它还消除了较大的if-else块 我一直在尝试用Ruby重新创建上述方法,但似乎无法完全实现Ruby开关式习惯用法,ruby,switch-statement,idioms,Ruby,Switch Statement,Idioms,我最近在RubyonRails上启动了一个项目。我以前用Python做过所有的项目,但我决定尝试一下Ruby 在我用Python编写的项目中,我使用了一种很好的小技巧,这篇文章给出了正确的答案: 我之所以使用这种技术,是因为Python没有本机开关函数,而且它还消除了较大的if-else块 我一直在尝试用Ruby重新创建上述方法,但似乎无法完全实现 有人能帮我吗?虽然没有什么可以阻止您使用基于类的方法,但为什么要避免rubyscase语句呢 case thing when 'something
有人能帮我吗?虽然没有什么可以阻止您使用基于类的方法,但为什么要避免rubys
case
语句呢
case thing
when 'something'
do_something
when 'nothing'
do_nothing
else
do_fail
end
虽然没有什么可以阻止您使用基于类的方法,但为什么要避免rubys
case
语句呢
case thing
when 'something'
do_something
when 'nothing'
do_nothing
else
do_fail
end
如果只需要通过存储在字符串中的方法名调用方法,标准的Ruby方法是使用方法:
否则,您可以使用Ruby的语句,正如前面所建议的那样。如果您只需要使用存储在字符串中的方法名来调用方法,Ruby的标准方法是使用方法:
否则,您可以使用Ruby的语句,正如前面所建议的。正如其他人所说,在Ruby中有其他方法可以做到这一点,但是如果您只是好奇的话,那么Ruby中与Python方法等效的方法(一旦您确定了方法名,就使用)将是:
class MyHandler
def handle_test(arg)
puts "handle_test called with #{arg}"
end
def handle_other(arg)
puts "handle_other called with #{arg}"
end
def handle(type, *args)
method_name = "handle_#{type}"
if respond_to? method_name
send(method_name, args)
else
raise "No handler method for #{type}"
end
end
end
handle_test called with example
handle_other called with example
handle.rb:15:in `handle': No handler method for missing (RuntimeError)
from handle.rb:23
然后,您可以执行以下操作:
h = MyHandler.new
h.handle 'test', 'example'
h.handle 'other', 'example'
h.handle 'missing', 'example'
其结果是:
class MyHandler
def handle_test(arg)
puts "handle_test called with #{arg}"
end
def handle_other(arg)
puts "handle_other called with #{arg}"
end
def handle(type, *args)
method_name = "handle_#{type}"
if respond_to? method_name
send(method_name, args)
else
raise "No handler method for #{type}"
end
end
end
handle_test called with example
handle_other called with example
handle.rb:15:in `handle': No handler method for missing (RuntimeError)
from handle.rb:23
正如其他人所说,在Ruby中有其他方法可以做到这一点,但是如果您只是好奇的话,那么Ruby中的Python方法(一旦确定了方法名,就使用Python方法)的等效方法是:
class MyHandler
def handle_test(arg)
puts "handle_test called with #{arg}"
end
def handle_other(arg)
puts "handle_other called with #{arg}"
end
def handle(type, *args)
method_name = "handle_#{type}"
if respond_to? method_name
send(method_name, args)
else
raise "No handler method for #{type}"
end
end
end
handle_test called with example
handle_other called with example
handle.rb:15:in `handle': No handler method for missing (RuntimeError)
from handle.rb:23
然后,您可以执行以下操作:
h = MyHandler.new
h.handle 'test', 'example'
h.handle 'other', 'example'
h.handle 'missing', 'example'
其结果是:
class MyHandler
def handle_test(arg)
puts "handle_test called with #{arg}"
end
def handle_other(arg)
puts "handle_other called with #{arg}"
end
def handle(type, *args)
method_name = "handle_#{type}"
if respond_to? method_name
send(method_name, args)
else
raise "No handler method for #{type}"
end
end
end
handle_test called with example
handle_other called with example
handle.rb:15:in `handle': No handler method for missing (RuntimeError)
from handle.rb:23
Ruby有一个case表达式。为什么要这样做呢?这比其他任何事情都要有趣:)在将代码从一种语言转换为另一种语言时,最好按照新语言的习惯编写新代码。换句话说,利用它的构造,而不是粗暴地强迫其他语言的构造。在这种特殊情况下,Ruby的
对象#send
可以做到这一点,但我认为对于代码可读性和维护,您最好使用case/when
语句。它们让你更容易看到发生了什么,一年后当你不得不添加一些东西时,你会得到回报。为什么要这样做呢?这比其他任何事情都要有趣:)在将代码从一种语言转换为另一种语言时,最好按照新语言的习惯编写新代码。换句话说,利用它的构造,而不是粗暴地强迫其他语言的构造。在这种特殊情况下,Ruby的对象#send
可以做到这一点,但我认为对于代码可读性和维护,您最好使用case/when
语句。它们让你更容易看到发生了什么,一年后当你不得不添加一些东西时,你会得到回报。你不需要#to#sym调用(send接受字符串和符号),我只是不确定早期的Ruby版本。谢谢,我现在将更新答案。您不需要#to#sym调用(send接受字符串和符号),我只是不确定早期的Ruby版本。谢谢,我现在将更新答案。我是否遗漏了您的方法\u遗漏了
?当然,如果对象到达method\u missing,那么它永远不会响应调用!接得好。由于我一直在定义方法,method\u missing
只触发了一个异常。我将更新以删除冗余代码示例。我是否缺少您的方法的某些内容?当然,如果对象到达method\u missing,那么它永远不会响应调用!接得好。由于我一直在定义方法,method\u missing
只触发了一个异常。我将更新以删除冗余代码示例。