在Ruby中冻结您的常量

AgustínLautaroUnsplash拍摄的照片

几年前,我正在开发一个非常大的Ruby on Rails代码库,该代码库使用常量保存信用卡交易状态列表。 例如:

# example 1 class Txn ACTIONABLE_STATES = [:authenticated, :to_settle] DONE_STATES = [:settled, :declined] # ... end

但是,我们有一个错误,其中已结算的交易可以通过txn.state.in? ACTIONABLE_STATES检查。 经过数小时的搜索,我们在代码库的完全不同的部分中找到了令人反感的代码。

# example 2 all_states = ACTIONABLE_STATES.concat(DONE_STATES) all_states.each do |state| # ... end

如果您已经了解Ruby Array类,那么您可能已经发现了违规行。 #concat会改变原始列表,即使它不是以惯用的!结尾,并且由于ACTIONABLE_STATES静态保存在内存中,因此当执行此代码时,它将更改ACTIONABLE_STATES状态,直至该Ruby虚拟机的剩余寿命。

换句话说,在执行示例2之后,ACTIONABLE_STATES变为[:au​​thenticated,:to_settle,:settled,:declined],直到重新启动服务器为止。

如果您在负载均衡器后面运行着多个Ruby框(就像我们所做的那样),则这可能会进一步混淆问题。 因为示例2可能只在某些特定的盒子上运行,所以您可能会遇到这样的情况:一个请求不会显示错误,而另一个请求会显示错误。

解决方案? 冻结您的常数。

# example 3 ACTIONABLE_STATES = [:authenticated, :to_settle].freeze DONE_STATES = [:settled, :declined].freeze

这将导致示例2产生无法修改的冻结数组(RuntimeError),并且如果您已经对示例2进行了单元测试,那么您甚至有可能在部署之前就抓住了它。

From: https://hackernoon.com/freeze-your-constants-in-ruby-49e3238c19ef

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值