Skip to content

Instantly share code, notes, and snippets.

@reyesyang
Created November 27, 2015 04:02
Show Gist options
  • Save reyesyang/a956c9af3f34615eea42 to your computer and use it in GitHub Desktop.
Save reyesyang/a956c9af3f34615eea42 to your computer and use it in GitHub Desktop.
# https://robots.thoughtbot.com/writing-a-domain-specific-language-in-ruby
module Smokestack
@registry = {}
def self.registry
@registry
end
def self.define(&block)
definition_proxy = DefinitionProxy.new
definition_proxy.instance_eval &block
end
def self.build(factory_name, overrides = {})
factory_class = const_get factory_name.capitalize
instance = factory_class.new
factory = registry[factory_name]
attributes = factory.attributes.merge overrides
attributes.each do |attribute_name, value|
instance.send "#{attribute_name}=", value
end
end
end
class DefinitionProxy
def factory(factory_name, &block)
factory = Factory.new
factory.instance_eval &block
Smokestack.registry[factory_name] = factory
end
end
class Factory < BasicObject
def initialize
@attributes = {}
end
attr_reader :attributes
def method_missing(name, *args, &block)
attributes[name] = args[0]
end
end
class User
attr_accessor :name, :pet_name
end
class Post
end
Smokestack.define do
factory :user do
name "Gabe B-W"
pet_name "Toto"
end
end
puts Smokestack.build(:user).inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment