Womb wraps around an object to present a chainable interface for defining
objects. It also provides short aliases for longer method names and helpers to
reduce boiler plate.
Once wrapped around an object, Womb stores all messages via method_missing
and then sends them to the object when the birth method is called, returning
the defined object.
require 'womb'
pi = 3.14
Circle = Womb[Class.new]
.attr_reader(:radius)
.define_method(:initialize) { |radius| @radius = radius }
.define_method(:circumference) { 2 * pi * radius }
.define_method(:area) { pi * radius ** 2 }
.birth
Circle.new(3).area # 28.26For shorthand, def and assign can be used as aliases for define_method
and define_singleton_method respectively, and init can be used to create
an initialize method that simply sets instance variables from it's arguments.
require 'git'
Repo = Womb[Class.new]
.assign(:open) { |path| new(Git.open(path)) }
.assign(:clone) { |url, path| new(Git.clone(url, path)) }
.init(:git)
.def(:checkout) { |branch| git.checkout(branch); self }
.def(:branch) { |branch| git.branch(branch).checkout; self }
.def(:add) { git.add(all: true); self }
.def(:commit) { |message| git.commit(message); self }
.def(:push) { git.push('origin', git.current_branch, force: true); self }
.def(:ls) { add; git.ls_files.keys }
.private
.attr_reader(:git)
.birth
Repo.open('../my_local_repo').add.commit('Updating with changes').pushAn additional helper, send_to_singleton, can be used to send messages to the
object's singleton class.
Matrix = Womb[Class.new]
.init(:v1, :v2)
.attr_reader(:v1, :v2)
.send_to_singleton(:alias_method, :[], :new)
.def(:determinant) { v1[0] * v2[1] - v2[0] * v1[1] }
.birth
Matrix[[2, 2], [1, 3]].determinant # 4If you prefer not to define a method with a block directly, it can defined as
a lambda and passed in using the to_proc operator, &. The objects private
state can still be accessed with instance variables.
move = ->(dist, angle) do
angle = angle * Math::PI / 180
@x += dist * Math.cos(angle)
@y += dist * Math.sin(angle)
puts self
self
end
Turtle = Womb[Class.new]
.init(:x, :y)
.def(:move, &move)
.def(:to_s) { "Turtle (#{@x.round}, #{@y.round})" }
.birth
Turtle.new(0, 0).move(1, 0).move(2, 90)
# Turtle (1, 0)
# Turtle (1, 2)Add your Gemfile:
gem 'womb'- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request