上下文是我正在构建的一个CLI国际象棋游戏项目,它处理诸如用户输入格式错误之类的条件,并根据各种游戏和棋子规则验证国际象棋的移动。我正在寻求最合适的技术来处理这类情况/条件/错误的指导-使用Exception类,编写自己的救援方法和/或任何其他方法。
例如,在下面的方法中,我写了一个自定义的'case/condition handler'类型的方法,它只是向用户发送一条关于问题的消息,然后再次尝试代码,有效地循环,直到用户输入正确的格式,就像这样:
游戏#get_move & #rescue_invalid_format_error:
def get_move
...
return rescue_invalid_format_error(move) unless chess_format?(move)
...
end
def rescue_invalid_format_error(move)
puts "your move; '#{move}' was not formatted correctly, it should be formatted like; 'a1,a2', try again..."
get_move
end
然后在其他代码中,我最终构建了自定义的Exception类,如下所示:
input_errors.rb:
class InputError < StandardError
def initialize(message = 'Input error')
super(message)
end
end
并且在'错误'情况下引发Exception对象,例如:
def add_move(indexed_move)
if index_format?(indexed_move)
true_move?(indexed_move) ? @moves << indexed_move : (raise InputError.new("Input; #{indexed_move} does not represent an actual move"))
else
raise InputError.new("Indexed_move; #{indexed_move} should be formatted like 'iiii'")
end
end
- (尽管我没有用
begin rescue
块 Package 任何调用上述#add_move
的代码,因为我认为InputError
已经在处理异常了,在它的祖先代码中的某个地方(尽管我不确定))。
所以,我的问题的实质是;在Ruby中,用什么样的错误处理方法/策略来处理什么样的条件,正确的方法是什么?
先谢谢你了。
1条答案
按热度按时间xvw2m8pv1#
在软件设计中没有使用异常的“正确方法”。例如,即使是流行的Ruby style guide也基本上忽略了这个问题。它最强烈的建议是不要在控制流中使用异常,这在所有现代编程语言中都被广泛接受。
话虽如此,这里是我使用的准则(Ruby以及其他语言)。
对库中的复杂错误使用异常
如果您正在开发一个希望在多个应用程序中重用的gem,那么异常可能是从库中返回信息丰富的错误的好方法。例如,这种风格在Ruby的几个标准部分中使用,例如
File
类。但要小心:你的库应该假设这些异常可能会被捕获,所以当这种情况发生时,它应该让自己处于某种合理的状态。你不想抛出一个漂亮的自定义异常,只是为了让它被捕获,现在你的库处于某种意想不到的状态,调用者在任何时候试图做任何事情时都会得到一个不漂亮的
RuntimeError
。使用异常的一个例外:如果库错误状态非常简单,则抛出自定义异常没有多大好处。主要的好处是在自定义类型和消息中传递的信息。因此,如果您不需要它,可以考虑简单地返回
nil
来指示错误。在应用中使用异常来处理 * 真正的异常 * 情况
如果你正在构建一个面向用户的应用程序(包括CLI),在代码中为那些不应该发生的情况保留异常,但从技术上讲,它可能会例如,你有一个数组索引,它应该总是有效的,但不知何故数组太小,一个变量应该已经初始化,但不知何故它仍然是
nil
,诸如此类的东西。换个说法:只在你不想捕捉的情况下使用异常,异常更多的是一种向你展示你的假设是错误的方式,这样你就可以修复错误。这种用法的一个好处是,你通常可以在Ruby中免费获得它,而不需要任何自定义代码,例如,你得到
NoMethodError
,它会告诉你到底出了什么问题。通常,您唯一希望捕获此类异常的地方是整个应用程序周围的一些高级begin rescue
,用于用“Sorry,something went wrong”消息来修饰它。特别是,从用户处获得输入并且该输入是无效的是完全不例外的。用户总是这样做。通常在我的CLI应用程序中,我会添加一个helper函数,它为用户提供提示,解释输入应该是什么样子,它在内部循环,直到他们输入正确的东西。这样的方法不需要任何方式来表示错误,因为它要么返回有效输入,要么根本不返回。
一般情况下,优先选择已有的异常类型
在声明自定义异常类之前,请仔细检查existing exception types是否适合您的情况。