The command pattern (ish) in Ruby, using a DSL
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
bin
lib
spec
.gitignore
.rspec
.travis.yml
Gemfile
Gemfile.lock
LICENSE.txt
README.org
Rakefile
insane_hook.gemspec

README.org

InsaneHook

Enjoy the enforcing-DSL of this command-patterny gem.

Should you use this?

No, you shouldn’t. You should write code like this:

class MyClassThatDoesSomething
  def initialize(foo:, bar:)
    @foo = foo
    @bar = bar
  end
  
  def call
    # do stuff
  end
end

This code is plain Ruby, everyone can understand it, it doesn’t depend on anything. It’s way better. You do not need this gem. YOU. DO. NOT. NEED. THIS. GEM.

Current version

0.5.0

Installation

Add this line to your application’s Gemfile:

gem 'insane_hook'

And then execute:

$ bundle

Or install it yourself as:

$ gem install insane_hook

Usage

class YeOldeTaske < InsaneHook
  required :arg1, :arg2
  required :arg0
  optional :arg3, arg4: 3
  optional :arg9
  call do
    # Do some work here
    # If you really need to return something, even though you shouldn't, leak it:
    leak "meaningful value"
  end
end

Is equivalent to:

class YeOldeTaske

  def self.call(**args)
    new(**args).call
  end

  attr_reader :arg0, :arg1, :arg2, :arg3, :arg4, :arg9

  def initialize(arg0:, arg1:, arg2:, arg3: nil, arg9: nil, arg4: 3)
    @arg0 = arg0
    @arg1 = arg1
    @arg2 = arg2
    @arg3 = arg3
    @arg4 = arg4
    @arg9 = arg9
  end

  def call
    leak "meaningful value"
    self
  end

  def leak(arg)
    @_result = arg
  end

  def result
    if instance_variable_defined?(:@_result)
      @_result
    else
      raise InsaneHook::CommandNotRunError
    end
  end
end

Design decisions

  1. Usage of `call` is idiomatic Ruby. Procs and method objects respond to `call`, so we are extending an existing Ruby pattern.
  2. Commands should not return anything (they are not queries), but if you are forced to check a result, then set the result to a single object and work off of that object (“leak” that data out of the command).
  3. Composition is usually better than Inheritance, especially in a language that doesn’t support multiple inheritance. Here we need to use inheritance because we are completely taking over both the `.new` and the `#initialize` methods, meaning the object does not truly belong to the person writing the code: the programmer is limited by the provided framework.

Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` 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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/trevoke/insane_hook.

License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).