Exceptions vs assert 之前在这里被问过:Design by contract using assertions or exceptions? , Assertion VS Runtime exception , C++ error-codes vs ASSERTS vs Exceptions choices choices :( , Design by contract using assertions or exceptions?等 (*) 也有书籍,如 Herb Sutter 的编码标准,讨论了这一点。普遍的共识似乎是这样的:
Use assertions for internal errors, in the sense that the user of the module and the developer are one and the same person/team. Use exceptions for everything else. (**)
这条规则对我来说很有意义,除了一件事。我是一名科学家,使用 C++ 进行科学模拟。在我的特定上下文中,这意味着我是大部分代码的唯一用户。如果我应用此规则,是否意味着我永远不必使用异常(exception)?我猜不是,例如,仍然存在 I/O 错误,或者内存分配问题,仍然需要异常。但是除了我的程序与“外部世界”的那些交互之外,还有其他我应该使用异常的场景吗?
根据我的经验,许多好的编程实践对我非常有用,尽管这些实践主要是为大型复杂系统或大型团队设计的,而我的程序大多是小型科学模拟,主要由我一个人编写.因此这个问题。哪些异常(exception)使用的良好做法适用于我的情况?或者我应该只使用断言(以及 I/O 异常、内存分配和与“外部世界”的其他交互)?
(*) 我希望在阅读完整的问题后,您同意这不是重复问题。 exceptions 与 assert 的主题之前已经大体上处理过,但是,正如我在这里试图解释的那样,我认为这些问题中的任何一个都没有解决我的特定情况。
(**) 我用自己的话写了这篇文章,试图恢复我读过的内容。如果您认为此声明没有反射(reflect)大多数人的共识,请随时批评它。
最佳答案
assert() 是防止程序员错误的保护措施,而异常是防止其余存在的保护措施。
让我们用一个例子来解释:
double divide(double a, double b) {
return a / b;
}
这个函数的明显问题是如果 b == 0,你会得到一个错误。
现在,让我们假设调用此函数时带有参数,这些参数的值由您且只有您决定。您可以通过将函数更改为以下内容来检测问题:
double divide(double a, double b) {
ASSERT(b != 0);
return a / b;
}
如果你不小心在你的代码中犯了一个错误,以至于 b 可以取一个 0 值,你就被覆盖了,并且可以通过明确测试 0 或者确保这种情况永远不会发生来修复调用代码首先。
只要此断言就位,您将作为代码开发人员获得一定程度的保护。 它是一种契约(Contract),可以让您轻松查看函数中可能出现的问题类型,尤其是在您测试代码时。
现在,如果您无法控制传递给函数的值会怎样? 断言只会在没有任何保护的情况下中断程序的流程。
明智的做法是:
double divide(double a, double b) {
ASSERT(b != 0);
if (b == 0)
throw DivideByZeroException();
return a / b;
}
try {
result = divide(num, user_val);
} catch (DivideByZeroException & e) {
display_informative_message_to_user(e);
}
请注意,断言仍然存在,因为它是可能出错的最可读的指示。 但是,添加异常可以让您更轻松地从问题中恢复过来。
可以说这种方法是多余的,但在发布版本中,断言通常是没有生成代码的 NOOP,因此异常仍然是唯一的保护。
而且,这个函数非常简单,所以断言和异常抛出是立即可见的,但是加上几十行代码,就不是这样了。
现在,当您正在开发并且可能会犯错时,断言失败将在它发生的确切行可见,而异常可能会冒泡到一个不相关的 try/catch block 中会使准确定位问题变得更加困难,特别是如果 catch block 不记录堆栈跟踪。
因此,如果您想在开发和正常执行期间确保安全并降低出错的风险,那么您就不能太小心,并且可能希望以互补的方式提供这两种机制。
关于c++ - 科学计算人员的异常与断言(我是我的代码的唯一用户)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32075263/
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题: