Ruby on Rails:无需 goto 处理重复错误检查的最佳方法?

发布于 2024-11-10 11:15:30 字数 603 浏览 5 评论 0原文

在具有 goto 的语言中,我喜欢在函数末尾(返回后)创建一个错误块,然后当我在函数内进行错误检查时,我可以简洁地在每次检查中转到错误处理程序。据我了解,这是 goto 的一种有效用法,不被认为是不好的做法。

伪代码示例:

 def example
   if (x) goto error
   do something
   if (y) goto error
   do something
   If (z) goto error
   do something
   return
  label 'error'
   log "error occurred"
   begin
     redirect_to :back
   rescue
     redirect_to root_url
   end
   return;
 end

如您所见,在这种情况下,我的错误块与函数本身一样长,重复 3 次会使我的代码大小加倍,而且不是很 DRY。然而,Ruby 似乎不支持 goto,或者至少如果它支持,据我在 Google 上的搜索可以看出,它可能是某种标记为邪恶的笑话库。

因此,人们在 Ruby 中做什么来处理重复的错误检查,每个错误中应该出现相同的结果?

In languages that have goto, I like to create an error block at the end of a function (after return) and then when I do error checking within the function, I can just be concise and goto the error handler within each check. As I understand it, this is the one valid use of goto that isn't considered bad practice.

Example in pseudocode:

 def example
   if (x) goto error
   do something
   if (y) goto error
   do something
   If (z) goto error
   do something
   return
  label 'error'
   log "error occurred"
   begin
     redirect_to :back
   rescue
     redirect_to root_url
   end
   return;
 end

As you can see, in this case, my error block is as long as the function itself, and repeating it 3 times would double the size of my code, and not be very DRY. However, it seems that Ruby doesn't support goto, or at least if it does, as best as I can tell from looking on Google, it's some sort of possibly joke library labeled evil.

Therefore, what are people doing in Ruby in order to handle repeated error checking where the same result should occur in each error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

断肠人 2024-11-17 11:15:30

回调

您应该使用 回调 将许多此类错误转移到您的模型中。这些适用于与涉及数据库中记录的操作相关的错误,即检查数据输入是否合适。

过滤器

使用 before_filters 和 after_filters 检查错误,特别是当您需要对多个控制器操作执行这些检查时。示例:

before_filter :check_errors

def example
   regular code...
end

private
  def check_errors
    error checking...
  end

Case 语句

使用 Case 语句 改进您的 if语句,特别是当您涉及多项检查时。

优先考虑上述内容

只要有可能,并且在涉及数据保存/更新/验证时一定要在模型中使用回调。

每当要在多个操作中重用代码时,请使用 before_filters (在我看来,每当您涉及这样的错误检查时,总是如此)。

如果您需要这些检查仅在该控制器操作中发生一次,并且不涉及更改记录,只需在有效的 case 语句中重写您的代码(但我的建议仍然是转移到 before_filter )。

Callbacks

You should transfer many of these errors into your models, using Callbacks. These apply to errors that are relevant to actions that involve records in your database, i.e. checking whether a data input is appropriate.

Filters

Use before_filters and after_filters to check for errors, especially when you need to perform these checks on multiple controller actions. An example:

before_filter :check_errors

def example
   regular code...
end

private
  def check_errors
    error checking...
  end

Case statements

Use Case statements to improve your if statements, particularly when you have multiple checks involved.

Prioritizing the above

Use callbacks in your models whenever you can and definitely whenever data saving/updating/validation is involved.

Use before_filters whenever the code is to be reused across multiple actions (and in my opinion, always whenever you have involved error checking like this).

If you need these checks to occur only once, in this controller action alone, that do not involve records being changed, simply rewrite your code in a valid case statement (but my recommendation would still be to transfer to a before_filter).

纸短情长 2024-11-17 11:15:30

这里有一个小秘密:异常基本上是美化的 goto。另外,Ruby 有 catch/throw 语法,请参阅: http://www .ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html

对于您的情况,请询问,这确实是一个错误还是只是一个不良情况。对我来说,一个错误是当 own_to 引用不存在的记录时,但有一个空的 own_to 则不存在。这会因情况而异。

看看上面的评论,我想我更倾向于添加一些设置实例变量并返回 true 或 false 的私有方法,并将它们链接在一起:

if load_model1 && load_model2 && load_model3
  ... do regular page view
else
  #render error page, use  @load_error
end

private
  def load_model1
     @model1 = ....
     if @model1.blank?  # or nil? or whatever error condition
        @load_error="model 1 failed
        return false
     else
        return true
     end
  end

  def load_model2
    ...
  end

  def load_model3
     ...
  end

Here's a little secret: Exceptions are basically glorified gotos. Also, ruby has a catch/throw syntax, see: http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html

In your case, ask, is it really an error or just an undesirable condition. An error to me is when a belongs_to references a record that doesn't exist, but having an empty belongs_to isn't. This changes from situation to situation.

Looking at your comment above, I think I would be more inclined to add some private methods that set the instance variables and return true of false, and chain them together:

if load_model1 && load_model2 && load_model3
  ... do regular page view
else
  #render error page, use  @load_error
end

private
  def load_model1
     @model1 = ....
     if @model1.blank?  # or nil? or whatever error condition
        @load_error="model 1 failed
        return false
     else
        return true
     end
  end

  def load_model2
    ...
  end

  def load_model3
     ...
  end

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文