Skip to content

Instantly share code, notes, and snippets.

@chrisnicola
Last active September 3, 2016 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisnicola/b1bee3be941402ff699e53e960363837 to your computer and use it in GitHub Desktop.
Save chrisnicola/b1bee3be941402ff699e53e960363837 to your computer and use it in GitHub Desktop.
A Useful Object Support Module
# Provides a default implementation of the singleton methods of buildable and
# callable classes based on the Useful Object's concept.
#
module UsefulObject
def self.included(base)
base.extend(Builder)
end
module Builder
def build(*args, **kargs, &block)
instance = new(*args)
@builder_block.call(instance, **kargs) if @builder_block.respond_to(:call)
yield(instance) if block_given?
instance
end
def call(*args, **kargs, &block)
build(*args, **kargs, &block).call
end
def builder(&block)
@builder_block = block
end
end
module Examples
class WithoutBuilder
include UsefulObject
attr_reader :arg1, :arg2, :called
def initialize(arg1, arg2)
@arg1 = arg1
@arg2 = arg2
end
def call
@called = true
self
end
end
class WithBuilder < WithoutBuilder
include UsefulObject
attr_accessor :karg, :dependency
builder do |instance, karg:|
instance.karg = karg
instance.dependency = true
end
end
end
end
require 'test_helper'
require 'core'
class UsefulObjectTest < Minitest::Test
describe "WithoutBuilder" do
WithoutBuilder = UsefulObject::Examples::WithoutBuilder
describe "UsefulObject#build" do
before do
@example = WithoutBuilder.build('arg1', 'arg2')
end
it 'should return an instance of the class' do
assert @example.is_a? WithoutBuilder
end
it 'should forward args to initialize' do
assert @example.arg1 == 'arg1'
assert @example.arg2 == 'arg2'
end
it 'should allow a block to be passed that receives the instance' do
WithoutBuilder.build('arg1', 'arg2') do |instance|
assert instance.is_a? WithoutBuilder
end
end
end
describe "UsefulObject#call" do
before do
@example = WithoutBuilder.call('arg1', 'arg2', karg: 'karg')
end
it 'should return an instance of the class' do
assert @example.is_a? WithoutBuilder
end
it 'should forward args and kargs to initialize' do
assert @example.arg1 == 'arg1'
assert @example.arg2 == 'arg2'
end
it 'should execute #call' do
assert @example.called
end
end
end
describe "WithBuilder" do
WithBuilder = UsefulObject::Examples::WithBuilder
describe "UsefulObject#build" do
before do
@example = WithBuilder.build('arg1', 'arg2', karg: 'karg')
end
it 'should return an instance of the class' do
assert @example.is_a? WithBuilder
end
it 'should forward args to initialize' do
assert @example.arg1 == 'arg1'
assert @example.arg2 == 'arg2'
end
it 'should run the builder block' do
assert @example.dependency
assert @example.karg == 'karg'
end
it 'should allow a block to be passed that receives the instance' do
WithBuilder.build('arg1', 'arg2', karg: 'karg') do |instance|
assert instance.is_a? WithBuilder
end
end
end
describe "UsefulObject#call" do
before do
@example = WithBuilder.call('arg1', 'arg2', karg: 'karg')
end
it 'should return an instance of the class' do
assert @example.is_a? WithBuilder
end
it 'should forward args and kargs to initialize' do
assert @example.arg1 == 'arg1'
assert @example.arg2 == 'arg2'
assert @example.karg == 'karg'
end
it 'should run the builder block' do
assert @example.dependency
end
it 'should execute #call' do
assert @example.called
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment