class DSeL::API::Generator
Attributes
last_call[R]
@return [Hash]
Data on the last call made.
Public Class Methods
new()
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 53 def initialize reset end
Private Class Methods
method_missing( sym, *args, &block )
click to toggle source
Calls superclass method
# File lib/dsel/api/generator.rb, line 264 def method_missing( sym, *args, &block ) if instance.respond_to?( sym ) instance.send( sym, *args, &block ) else super( sym, *args, &block ) end end
respond_to?( *args )
click to toggle source
Calls superclass method
# File lib/dsel/api/generator.rb, line 272 def respond_to?( *args ) super || instance.respond_to?( *args ) end
Public Instance Methods
call_handler_catch_all_name( type )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 152 def call_handler_catch_all_name( type ) "_#{type}_catch_all_#{token}".to_sym end
call_handler_name( type, *possible_object )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 140 def call_handler_name( type, *possible_object ) possible_object.empty? ? call_handler_catch_all_name( type ) : call_handler_with_object_name( type, possible_object.first ) end
call_handler_with_object_name( type, object )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 147 def call_handler_with_object_name( type, object ) "_#{type}_#{call_object_hash_for( object )}_#{token}".to_sym end
call_object_hasher=( hasher )
click to toggle source
@note Defaults to ‘Object#hash` and assumes case-insensitive strings.
Sets a way to calculate unique routing hashes for call objects.
@param [Symbol, call] hasher
* `Symbol`: Object method. * `#call`: To be passed each object and return an Integer hash.
# File lib/dsel/api/generator.rb, line 43 def call_object_hasher=( hasher ) if hasher && !(hasher.is_a?( Symbol ) || hasher.respond_to?( :call )) fail ArgumentError, "Expected Symbol or #call-able hasher, got: #{hasher.inspect}" end @call_object_hasher = hasher end
calling( node, type, handler, args, *possible_object, &block )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 101 def calling( node, type, handler, args, *possible_object, &block ) synchronize do @last_call = { node: node, type: type } if !possible_object.empty? @last_call.merge!( object: possible_object.first ) end @last_call.merge!( handler: handler, args: args ) if last_call_with_caller? @last_call[:caller] = caller end end t = Time.now r = block.call spent = Time.now - t synchronize do @last_call[:time] = spent call_on_call( @last_call ) end r end
define_call_handler( node, type, *possible_object, &block )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 80 def define_call_handler( node, type, *possible_object, &block ) node.instance_eval do handler = Generator.call_handler_name( type, *possible_object ) if method_defined?( handler ) fail ArgumentError, 'Call handler already exists: ' << Generator.handler_to_s( self, type, *possible_object ) end # We can get the options from here and do stuff...I don't know. push_call_handler( type, handler, *possible_object ) define_method handler, &block end define_call_router( node, type ) nil end
define_definers( node, *types )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 69 def define_definers( node, *types ) synchronize do types.each do |type| define_definer( node, type ) end end nil end
definer_name( type )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 135 def definer_name( type ) "def_#{type}".to_sym end
handler_to_s( node, type, *possible_object )
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 157 def handler_to_s( node, type, *possible_object ) r = "#{node} #{type}" if !possible_object.empty? object = possible_object.first r << ' ' r << (object.nil? ? 'nil' : object.to_s) end r end
last_call_with_caller!()
click to toggle source
# File lib/dsel/api/generator.rb, line 22 def last_call_with_caller! @last_call_with_caller = true end
last_call_with_caller?()
click to toggle source
# File lib/dsel/api/generator.rb, line 14 def last_call_with_caller? @last_call_with_caller end
last_call_without_caller!()
click to toggle source
# File lib/dsel/api/generator.rb, line 18 def last_call_without_caller! @last_call_with_caller = false end
on_call( &block )
click to toggle source
# File lib/dsel/api/generator.rb, line 26 def on_call( &block ) fail ArgumentError, 'Missing &block' if !block synchronize do @on_call << block end self end
reset()
click to toggle source
@private
# File lib/dsel/api/generator.rb, line 58 def reset @mutex = Monitor.new @on_call = [] @last_call_with_caller = false @call_object_hasher = false self end
Private Instance Methods
call_object_hash_for( object )
click to toggle source
# File lib/dsel/api/generator.rb, line 177 def call_object_hash_for( object ) if !@call_object_hasher default_call_object_hash_for( object ) elsif @call_object_hasher.is_a?( Symbol ) object.send( @call_object_hasher ) else @call_object_hasher.call( object ) end.tap do |h| next if h.is_a? Integer fail ArgumentError, "Hasher #{@call_object_hasher.inspect} returned non-Integer" << " hash #{h.inspect} for object #{object.inspect}." end end
call_on_call( *args )
click to toggle source
# File lib/dsel/api/generator.rb, line 171 def call_on_call( *args ) @on_call.each do |b| b.call *args end end
default_call_object_hash_for( object )
click to toggle source
# File lib/dsel/api/generator.rb, line 193 def default_call_object_hash_for( object ) object = object.downcase if object.is_a?( String ) object.hash end
define_call_router( node, type )
click to toggle source
# File lib/dsel/api/generator.rb, line 218 def define_call_router( node, type ) node.instance_eval do return if method_defined?( type ) # Basically a router, object-based and catch-all. define_method type do |*args, &block| if !args.empty? object = args.shift with_object = Generator.call_handler_with_object_name( __method__, object ) if respond_to?( with_object ) r = nil Generator.calling( self.class, type, with_object, args, object ) do r = send( with_object, *args, &block ) end return r.nil? ? self : (r == :nil ? nil :r) end args.unshift object end catch_all = Generator.call_handler_catch_all_name( __method__ ) if respond_to?( catch_all ) r = nil Generator.calling( self.class, type, catch_all, args ) do r = send( catch_all, *args, &block ) end return r.nil? ? self : r end fail NoMethodError, "No handler for: #{Generator.handler_to_s( self.class, type, *args )}" end end nil end
define_definer( node, type )
click to toggle source
# File lib/dsel/api/generator.rb, line 202 def define_definer( node, type ) definer = Generator.definer_name( type ) # We can get the options from here and do stuff...I don't know. node.push_definer( type, definer ) node.class_eval( "undef :#{definer} if defined? #{definer}" ) node.define_singleton_method definer do |*possible_object, &block| if possible_object.size > 1 fail ArgumentError, 'No more than 1 objects are allowed.' end Generator.define_call_handler( self, type, *possible_object, &block ) end end
synchronize( &block )
click to toggle source
# File lib/dsel/api/generator.rb, line 258 def synchronize( &block ) @mutex.synchronize( &block ) end
token()
click to toggle source
# File lib/dsel/api/generator.rb, line 198 def token @token ||= SecureRandom.hex end