EnhanceModule
This gem adds a typed, sorbet-friendly way of extending object instances with modules.
Installation
Install the gem and add to the application's Gemfile by executing:
$ bundle add enhance_module
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install enhance_module
Motivation
Ruby supports extending objects with methods from modules.
It's one of the most unique and cool features of Ruby.
module Foo
def foo = "foo!"
end
obj = Object.new
obj.extend(Foo)
obj.foo
Unfortunately sorbet does not support this feature.
Its type system in unable to fathom what is going on when an object is extended.
module Foo
extend T::Sig
sig { void }
def foo = "foo!"
end
obj = Object.new
obj.extend(Foo)
obj.foo
Usage
This gem adds a new sorbet-friendly way of extending objects.
require 'enhance_module'
module Foo
extend T::Sig
class << self
include EnhanceModule
has_attached_class! { { fixed: Foo } }
end
sig { void }
def foo = "foo!"
end
obj = Object.new
extended_obj = Foo.enhance(obj)
extended_obj.foo
T.reveal_type(extended_obj)
The new Foo.enhance
method works like extend
and
returns an intersection type that consists of the argument's class
and the module that is being extended.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/Verseth/enhance_module.
License
The gem is available as open source under the terms of the MIT License.