Skip to content

Instantly share code, notes, and snippets.

@dobbs
Last active August 29, 2015 14:12
Show Gist options
  • Save dobbs/8f09606ec13f8433ba79 to your computer and use it in GitHub Desktop.
Save dobbs/8f09606ec13f8433ba79 to your computer and use it in GitHub Desktop.
Simple Abstraction for Builder objects in Ruby
class Builder < Struct
def self.with(spec, &block)
struct = new(*(spec.keys)) do
def initialize(options={})
super
options.each { |opt, value| self[opt] = value }
freeze
end
def with(options, &block)
new_struct = dup
options.each { |opt, value| new_struct[opt] = value }
if block_given?
new_struct.class.class_eval do
define_method :build, &block
end
end
new_struct.freeze
end
members.each do |opt|
define_method "with_#{opt}" do |value, &block|
with(opt => value, &block)
end
end
define_method :build, &block
end
struct.new spec
end
end
person = Builder.with first: nil, last: nil, registered: false do
"#{first} #{last} is#{registered ? '' : ' not'} registered"
end
person.build
# => " is not registered"
mcfly = person.with_last "McFly"
mcfly.build
# => " McFly is not registered"
george = mcfly.with_first "George" do
"I'm #{first}. #{first} #{last}. I'm your density. I mean your destiny."
end
george.build
# => "I'm George. George McFly. I'm your density. I mean your destiny."
george.registered
# => false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment