./lib/common/class_callbacks.rb in lux-fw-0.2.3 vs ./lib/common/class_callbacks.rb in lux-fw-0.5.32
- old
+ new
@@ -1,64 +1,47 @@
-# frozen_string_literal: true
+# Rails style callbacks
-# in some class
-# ClassCallbacks.define self, :before, :after
-#
-# then to execute
-# instance_object = SomeClass.new
-# ClassCallbacks.execute(instance_object, :before)
-#
+# for controllers, execute from AppController to MainController
+# class_callback :before
# before do
-# ...
+# ...
# end
-#
-# logic is very simple, keep all pointers to all blocks in one class, resolve and execute as needed
-# we keep methods and ponters in different hashes to allow hot reload while development
+# before :method_name
+# instance = new
+# instance.class_callback :before,
+# instance.class_callback :before, arg
-module ClassCallbacks
- extend self
-
- @@methods = {}
- @@pointers = {}
-
- def add klass, unique_id, action, method
- klass = klass.to_s
- key = Crypt.sha1(unique_id)
-
- @@pointers[key] = method
-
- @@methods[klass] ||= {}
- @@methods[klass][action] ||= []
- @@methods[klass][action].tap { |it| it.push(key) unless it.include?(key) }
+class Object
+ def class_callback name, arg=nil
+ Object.class_callback name, self, arg
end
- def execute instance_object, action, object=nil
- object ? instance_object.send(action, object) : instance_object.send(action)
+ def self.class_callback name, context=nil, arg=nil
+ ivar = "@ccallbacks_#{name}"
- # execute for self and parents
- instance_object.class.ancestors.reverse.map(&:to_s).each do |name|
- next if name == 'Object'
- next unless actions = @@methods.dig(name, action)
+ unless context
+ define_singleton_method(name) do |method_name=nil, &block|
+ ref = caller[0].split(':in ').first
- for el in actions.map { |o| @@pointers[o] }
- if el.kind_of?(Symbol)
- object ? instance_object.send(el, object) : instance_object.send(el)
- else
- object ? instance_object.instance_exec(object, &el) : instance_object.instance_exec(&el)
- end
+ self.instance_variable_set(ivar, {}) unless instance_variable_defined?(ivar)
+ self.instance_variable_get(ivar)[ref] = method_name || block
end
- end
- end
- def define(klass, *args)
- args.each do |action|
- klass.class_eval %[
- def #{action}(duck=nil)
- end
+ else
+ list = context.respond_to?(:const_missing) ? context.ancestors : context.class.ancestors
+ list = list.slice 0, list.index(Object) if list.index(Object)
- def self.#{action}(proc=nil, &block)
- ClassCallbacks.add(self, caller[0], :#{action}, proc || block)
+ list.reverse.each do |klass|
+ if klass.instance_variable_defined?(ivar)
+ mlist = klass.instance_variable_get(ivar).values
+ mlist.each do |m|
+ if m.is_a?(Symbol)
+ context.send m
+ else
+ context.instance_exec arg, &m
+ end
+ end
end
- ]
+ end
end
end
end