Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible ideal use case for refinements? #292

Open
lazyatom opened this issue Jul 30, 2020 · 2 comments
Open

Possible ideal use case for refinements? #292

lazyatom opened this issue Jul 30, 2020 · 2 comments

Comments

@lazyatom
Copy link

We found this library as a dependency of another library (snowplow/snowplow-ruby-tracker) that we use in our application. Unfortunately, we also have our own top-level class called Contract, which basically means we have to fork our dependency to remove this gem in order to get things working again. Not great!

If I was in control of everything (the world!), I'd probably consider reworking this gem to use method calls rather than global constants to do its work, so that the external surface area of the API is as small as possible e.g.

class Something
  include Contracts::Behaviour

  contract Double => Double # contract is a method from `Contracts::Behaviour`, not a constant
  def wem(x); x * 2; end

  contract array_of(Hash) => nil # array_of is a method from `Contracts::Behaviour`, not a constant
  def wibble(args); ...; end
end

... however, that's obviously a massive change and I'm not familiar enough with this gem to spot any obvious gotchas, of which there might be many.

However, one way to keep the usage of the gem the same, but not prevent dependencies at any level from defining a Contract class, might be to make these available as refinements that can be explicitly opted-in for classes that want to use verification.

class Something
  using Contracts::Behaviour

  Contract Double => Double # same API
  def wem(x); x * 2; end

  Contract ArrayOf[Hash] => nil # same API
  def wibble(args); ...; end
end

class OtherThing
  def foo; Contract.first; end # uses existing app-specific `Contract` constant 
end

Is this something you'd be interested in?

@gsinclair
Copy link
Contributor

I have no power to say yes or no to this, and I have no major project that requires such use of refinements, but I just want to say that this is a very cool idea.

@egonSchiele
Copy link
Owner

Hey there,
Sorry for the late response. I think this is a cool idea as well. I'm largely not maintaining this project -- life has gotten in the way. But if you can open a PR and the tests pass, I'd be happy to merge in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants