Skip to content

Instantly share code, notes, and snippets.

@yelvert
Last active September 26, 2018 01:36
Show Gist options
  • Save yelvert/cc0295a7827eae559b2c1d9f9e66b6ff to your computer and use it in GitHub Desktop.
Save yelvert/cc0295a7827eae559b2c1d9f9e66b6ff to your computer and use it in GitHub Desktop.
DSL Example
#! /usr/bin/env ruby
module SomeMod
module DSL
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def some_dsl(**opts, &block)
Context.new(self, **opts, &block)
end
end
def some_dsl(**opts, &block)
Context.new(self, **opts, &block)
end
end
class Context
attr_reader :target, :options
def initialize(target, **opts, &block)
@target = target
@options = opts
instance_exec &block
end
end
class Action
attr_reader :context, :run_block
def initialize(context, &block)
@context = context
@run_block = block
end
def call
run_block!
end
private
def target ; context.target ; end
def run_block!
instance_exec &run_block if run_block.is_a?(Proc)
end
end
def register_action(name, klass)
raise 'Can only register a descendant of Action' unless klass < Action
Context.send(:define_method, name) do |*args, &block|
action = klass.new(self, &block)
action.send(:call, *args)
action
end
end
module_function :register_action
end
class LogAction < SomeMod::Action
def call(msg)
puts '='*50
puts "context: #{context.inspect}"
puts "message: #{msg}"
puts '='*50
end
end
SomeMod.register_action :log, LogAction
class SomeBlockAction < SomeMod::Action
def foo
puts "foo"
end
end
SomeMod.register_action :some_block, SomeBlockAction
class SubDSLAction < SomeMod::Action
include SomeMod::DSL
def call
some_dsl &run_block
end
end
SomeMod.register_action :sub_dsl, SubDSLAction
class MyClass
include SomeMod::DSL
foo = 'test'
some_dsl do
log foo
end
def do_dsl_stuff(bar)
some_dsl a: 1, b: 2 do
log bar
main_context_options = options
sub_dsl do
log main_context_options.inspect
sub_dsl do
log 'nested 1'
sub_dsl do
some_block do
foo
end
end
end
end
end
end
end
MyClass.new.do_dsl_stuff('FOO')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment