Skip to content

Instantly share code, notes, and snippets.

@Thermatix
Created August 4, 2016 15:03
Show Gist options
  • Save Thermatix/20df3a6ad6e1efde3fe0fd49af2f6eb0 to your computer and use it in GitHub Desktop.
Save Thermatix/20df3a6ad6e1efde3fe0fd49af2f6eb0 to your computer and use it in GitHub Desktop.
class Views_Base
def self.inherited(base)
base.extend Singleton_Methods
end
module Singleton_Methods
attr_accessor :views
def define_view view, *schema, &block
@views ||={}
@views[view] = {
:block => block,
:schema => schema
}
end
def method_missing(m,*args)
if (view = contains(m)) && check_against_schema(args.first,@views[view][:schema])
raise ArgumentError, 'Expected Object to be passed as second arg' unless args.last.is_a? Object
provide_data_methods_for(args.last,@views[view][:schema],args.first) do |obj|
obj.instance_exec(&@views[view][:block])
end
else
super
end
end
def respond_to?(m,include_private=false)
contains m
end
private
def provide_data_methods_for binding,schema,values
view_class = self
@views.each do |view_meth,data|
binding.class.send(:define_method, view_meth) do |*data|
view_class.send(:"render_#{view_meth}",data,binding)
end
end
schema.each do |item|
meth_name = item.is_a?(Hash) ? item.keys.first : item
binding.class.send :define_method, meth_name do
values[meth_name]
end
end
res = yield(binding)
schema.each do |item|
meth_name = item.is_a?(Hash) ? item.keys.first : item
binding.method(meth_name).unbind
end
@views.keys.each do |view_meth|
binding.method(view_meth).unbind
end
res
end
def check_against_schema(data,schema)
schema.each do |item|
if item.is_a? Hash
next
end
check_schema_item(data,item)
end
true
end
def check_schema_item(hash,key)
msg = "Schema expects key#{key} to exists"
case true
when hash.respond_to?(:include?)
if hash.keys.include?(key)
true
else
puts msg
raise ArgumentError, msg
end
when hash.respond_to?(:[])
if hash[key]
true
else
puts msg
raise ArgumentError, msg
end
else
raise TypeError,"given data Object is not a hash or hashlike, located at :#{key} potentialy missing key in data object that schema requires"
end
end
def contains(m)
rgx = /render_(.*)/
t = m.to_s
if t =~ rgx && @views.has_key?(k = rgx.match(t).captures.first.to_sym)
k
else
false
end
end
end
end
@Thermatix
Copy link
Author

What the hell was I smoking when I made this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment