contracts.ruby icon indicating copy to clipboard operation
contracts.ruby copied to clipboard

Contracts off by default instead of on by default?

Open vdbijl opened this issue 8 years ago • 2 comments

Because of performance requirements we want our contract checks to only run in development/testing. The default is that contracts are always on. Is it possible to reverse that? Off by default, on with a switch?

The reason I ask is that it is difficult to automatically guarantee that contracts are not running in production, ie the env variable is set and used correctly. The reverse is easy.

Or to rephrase my question/request. Is there an easy way make sure contracts are off in production. Or maybe we can configure it ourselves?

vdbijl avatar Jan 13 '17 09:01 vdbijl

Are you referring to the NO_CONTRACTS env var? That is the easiest way to make sure that contracts aren't running. But you can also specify your own override callback instead of using the default one with override_failure_callback. Here's a simple example:

require "contracts"
include Contracts

Contract.override_failure_callback do |data|
  p data
  false # don't run the function since the contract failed
end

Contract Num => Num
def incr a
  a + 1
end

incr("Asdas") # will just print a hash instead of throwing an error

egonSchiele avatar Jan 17 '17 21:01 egonSchiele

Thanks for the feedback (sorry for the delay because holiday ;). Yes I am referring to the NO_CONTRACTS env var. The problem is that I am (for now only) using the contracts in a gem that is used in another gem. Having the coupling via an ENV var means, that the gem that is using my gem with contracts needs to know about contracts and needs to set the ENV var (AFAIK). So I was looking for a way to locally disable the contract checking in production from the gem that is using contracts. Performance is critical to our app that's why I am disabling the checking.

I guess the only way to do that is by monkey_patching the following methods (the ones that use NO_CONTRACTS):

  • InvariantExtension#invariant to return nil
  • MethodHandler#ignore_decorators to return true

But then I have to check this every time contracts.gem updates.

Another way might be to make contracts a development dependency and complety monkey patch the Contract method to do nothing...?

Am I making sense? :) Maybe I want to solve this in the wrong way...

vdbijl avatar Feb 11 '17 09:02 vdbijl