Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby开关式习惯用法_Ruby_Switch Statement_Idioms - Fatal编程技术网

Ruby开关式习惯用法

Ruby开关式习惯用法,ruby,switch-statement,idioms,Ruby,Switch Statement,Idioms,我最近在RubyonRails上启动了一个项目。我以前用Python做过所有的项目,但我决定尝试一下Ruby 在我用Python编写的项目中,我使用了一种很好的小技巧,这篇文章给出了正确的答案: 我之所以使用这种技术,是因为Python没有本机开关函数,而且它还消除了较大的if-else块 我一直在尝试用Ruby重新创建上述方法,但似乎无法完全实现 有人能帮我吗?虽然没有什么可以阻止您使用基于类的方法,但为什么要避免rubyscase语句呢 case thing when 'something

我最近在RubyonRails上启动了一个项目。我以前用Python做过所有的项目,但我决定尝试一下Ruby

在我用Python编写的项目中,我使用了一种很好的小技巧,这篇文章给出了正确的答案:

我之所以使用这种技术,是因为Python没有本机开关函数,而且它还消除了较大的if-else块

我一直在尝试用Ruby重新创建上述方法,但似乎无法完全实现


有人能帮我吗?

虽然没有什么可以阻止您使用基于类的方法,但为什么要避免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
只触发了一个异常。我将更新以删除冗余代码示例。