Created
August 4, 2016 15:03
-
-
Save Thermatix/20df3a6ad6e1efde3fe0fd49af2f6eb0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What the hell was I smoking when I made this?