Skip to content

Instantly share code, notes, and snippets.

@shuhei
Created February 18, 2015 05:08
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 shuhei/e48d64ed9daa3d9c6316 to your computer and use it in GitHub Desktop.
Save shuhei/e48d64ed9daa3d9c6316 to your computer and use it in GitHub Desktop.
Configuration builder with meta programming
module Api
class PublicApi
PANEL_KEYS = [
:priority,
:template_type,
:title,
link: [
:id,
:title,
:url,
image: [
:width,
:height,
:url
]
]
]
KEYS = [
:id,
:title,
:url,
left_panel: PANEL_KEYS,
right_panel: PANEL_KEYS
]
attr_reader :params
def initialize
@params = {}
end
def self.build(&block)
instance = new
Configuration.new(instance.params, KEYS).configure(&block)
instance
end
class Configuration
def initialize(params, keys)
@params = params
keys.each do |key|
if key.is_a?(Hash)
key.each do |k, v|
define_container_setter(k, v)
end
else
define_value_setter(key)
end
end
end
def configure(&block)
instance_exec(&block)
@params
end
private
def define_container_setter(name, keys)
define_singleton_method(name) do |&block|
@params[name] = {}
Configuration.new(@params[name], keys).configure(&block)
end
end
def define_value_setter(name)
define_singleton_method(name) do |value|
@params[name] = value
end
end
end
end
end
api = Api::PublicApi.build do
id '999'
title 'サンプルタイトル'
url '//www.example.com/'
left_panel do
priority 'normal'
template_type 'template'
title 'サンプルタイトル'
link do
id 'left-sample1'
title 'left-title-sample1'
url '//www.example.com/'
image do
width 200
height 300
url 'imageurl'
end
end
end
right_panel do
priority 'normal'
template_type 'template'
title 'サンプルタイトル'
link do
id 'right-sample1'
title 'right-title-sample1'
url '//www.example.com/'
image do
width 200
height 300
url 'imageurl'
end
end
end
end
puts api.params.inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment