Can't use Contracts with define_method in a module
I love the fact that Contracts works with define_method and define_singleton_method. It makes my life a lot easier. The problem is that the same pattern doesn't seem to work in modules.
require 'contracts'
# This works:
class ExampleClass
include Contracts
def self.define_typed_method(method_name)
# This works, and the contract is applied to the metaprogrammed method
Contract None => Fixnum
define_method(method_name) { 42 }
end
define_typed_method :foo
end
ExampleClass.new.foo
# => 42
# This is where things go wrong:
module ExampleModule
include Contracts
def define_typed_method(method_name)
Contract None => Fixnum
# ~> (eval):7:in `Contract': undefined method `Contract' for Class:Class (NoMethodError)
# ~> from -:22:in `define_typed_method'
# ~> from -:34:in `<class:HypotheticalClass>'
# ~> from -:31:in `<main>'
define_method(method_name) { 42 }
end
end
class HypotheticalClass
extend ExampleModule
# This is how I'd use it, if things were working correctly
define_typed_method :foo
end
This works for me after I add include Contracts in the HypotheticalClass class, though it should work without that too.
@actsasbuffoon read this comment: https://github.com/egonSchiele/contracts.ruby/issues/229#issuecomment-193544001
I bet this is what is happening here too. Unfortunately the fix won't fix your issue ... Ruby is trying to resolve Contract as a constant, and it doesn't work.
@egonSchiele Maybe we could provide an alias with lowercase? Like def_contract(...) ?
@waterlink I'm wondering if we should start moving away from Contract and towards contract. This conflict (constant vs function name resolution) will always be there.
@egonSchiele We can totally do that, I don't mind contract at all. It is not so pretty, but what can you do about it :)