开发者

Using asserts in Ruby production... yes or no?

开发者 https://www.devze.com 2023-02-23 12:06 出处:网络
So, here\'s the deal. I\'m currently working in a Ruby on Rails environment and have been for ~1 year now. Before that I was in C++/Java land for almost a decade. I\'m (still) trying to figure out wha

So, here's the deal. I'm currently working in a Ruby on Rails environment and have been for ~1 year now. Before that I was in C++/Java land for almost a decade. I'm (still) trying to figure out what the Ruby way is when it comes to asserts.

I'm not worried about the technical detail. I know TestUnit has asserts which can be used in the testing environment and I know I can add my own assert methods to my Ruby project and use them in production Rails to lock down known conditions. The question is: What is the Ruby way for ensuring something in code that I know should/not happen?

For the record, I've been asserting in开发者_高级运维 tests and raising in production. I still can't help but miss my production asserts...


Asserts really shouldn't be used in production code for two reasons.

  1. assert x is very functional, and as such hard to read. Using a raise/if combo adds readability.

  2. assert doesn't make it clear what error will be raised if the condition fails. While,

    raise ObscureButInformitiveError if condition

    lets the application layers further up do something relveant. Such as emailing an admin, or writing to a perticular log.


Let the error happen, then check the logs for what went wrong, then fix it.
Rails catches all uncaught exceptions automatically, it will only mess up the single request the error happened in.


There's no official non-test assertions in Ruby, but there are gems.

For instance Jim Weirich's Given looks promising. Although its main focus is testing environments (rspec / minitest), but it also:

... provides three assertions meant to be used in non-test/non-spec code. For example, here is a square root function decked out with pre and post-condition assertions.

require 'given/assertions' 
require 'given/fuzzy_number'

include Given::Assertions 
include Given::Fuzzy

def sqrt(n)   
  Precondition { n >= 0 }   
  result = Math.sqrt(n)
  Postcondition { result ** 2 == about(n) }   
  result 
end 

To use the non-testing assertions, you need to require the 'given/assertions' file and then include the Given::Assertions module into what ever class is using the Precondition / Postcondition / Assert methods. The code block for these assertions should always be a regular Ruby true/false value (the should and expect methods from RSpec are not available).

Note that this example also uses the fuzzy number matching, but that is not required for the assertions themselves.

0

精彩评论

暂无评论...
验证码 换一张
取 消