以下是使用Ruby评估Excel公式的代码。此处仅显示SUM
功能。我用两种语言Ruby
和Python
实现了这个功能
Python 3.10.0
def SUM(a,b):
return a+b
for i in range(int(input())):
s=input()
if s[0]!="=":
print("INVALID")
else:
try:
print(eval(s.replace('=','')))
except:
print("INVALID")
Ruby 3.0.2
def SUM a,b
a+b
end
gets
puts $<.map{
if !_1[/^=/]
:INVALID
else
eval(_1.tr(?=,'')) rescue :INVALID
end
}
考虑以下输入
输入1
4
=SUM(8, 99)
=SUM(343, -b1)
=SUM(-8, -99)
=SUM(101 , -25) + 6
输入2
3
SUM(4, 1)
=SUM(5, 1
=SuM(2, 1)
对于Input 1,Ruby和Python代码都可以完美地工作。它们都捕捉到未定义的错误b1
,因此进入except
或rescue
但对于输入2,只有Python代码可以完美地工作,而Ruby未能捕捉到丢失的错误)
(第3行)。它不进入rescue
。我也试过使用begin
和resuce
。但什么都没有。如何挽救Ruby中的此类错误?
rescue
中的只拯救StandardError
的子类。这适用于大多数情况,因为您想要拯救的大多数东西都是该类的后代(NoMethodError
、RuntimeError
、ArgumentError
等),而您不想要拯救的大部分东西(NoMemoryError
、SyntaxError
、SystemExit
等)则不是。
在您的案例中,eval("SUM(5, 1")
缺少一个括号。这是一个语法错误,ruby引发SyntaxError
。您的rescue
正在查找StandardError
,而SyntaxError
不是。
您可以挽救所有标准错误+语法错误或挽救所有Exception
秒,但请注意,如果您挽救了所有Exception
秒,那么您的程序可能很难退出。
ctrl+c
是Interrupt
,它是Exception
的一个子类,可以被拯救。
进程上的kill
是一个SignalException
,它是Exception
的子类,可以被挽救。
begin
eval(_1.tr(?=,''))
rescue StandardError, SyntaxError
:INVALID
end
或
begin
eval(_1.tr(?=,''))
rescue Exception # I strongly advise against this
:INVALID
end