Class: ArgumentMerger

Inherits:
Object show all
Defined in:
lib/quarter_system/argumentation/argument_merger.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(archetype, arguments, opts = {}) ⇒ ArgumentMerger

Returns a new instance of ArgumentMerger.



7
8
9
10
11
12
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 7

def initialize(archetype, arguments, opts={})
  @archetype  = archetype
  @arguments  = arguments.compact
  @opts       = opts.tap { |o| o[:else] ||= nil }
  self
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_sym, *arguments, &block) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 100

def method_missing(method_sym, *arguments, &block)
  return @opts[:else] if check_conditions?
  arguments = Array.wrap(arguments.last.is_a?(Proc) ? lambda { |*args| @arguments | arguments.pop.call(*args) } : @arguments) + arguments.compact
  
  catch(:argument_error) do
    archetype_respond_to?(method_sym)                   or raise ArchetypeMethodsError,   "Issue with #{method_sym}"
    provided_minimum_arguments?(method_sym, arguments)  or raise ArchetypeArgumentsError, "Issue with #{method_sym}"
    archetype_send(method_sym, *arguments, &block)
  end
rescue ArchetypeError => e
  logger.error "<errorClass>#{e.class}: <method>#{method_sym}: <msg>#{e.message}" if Rails.env.development?
  super
rescue
  logger.error "Giving up rescuing #{@archetype.name rescue nil}##{method_sym}. Arguments are #{arguments.inspect}" if Rails.env.development?
  @opts[:else]
end

Instance Attribute Details

#archetypeObject

Returns the value of attribute archetype.



6
7
8
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 6

def archetype
  @archetype
end

Instance Method Details

#archetype_method(method_sym) ⇒ Object



40
41
42
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 40

def archetype_method(method_sym)
  @archetype.method(method_sym)
end

#archetype_method_arity(method_sym) ⇒ Object



52
53
54
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 52

def archetype_method_arity(method_sym)
  archetype_method(method_sym).arity
end

#archetype_method_params(method_sym) ⇒ Object



44
45
46
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 44

def archetype_method_params(method_sym)
  archetype_method(method_sym).parameters
end

#archetype_method_params_size(method_sym) ⇒ Object



48
49
50
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 48

def archetype_method_params_size(method_sym)
  archetype_method_params(method_sym).size
end

#archetype_respond_to?(method_sym) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 26

def archetype_respond_to?(method_sym)
  archetype_respond_to_proc.call(method_sym)
rescue NameError => e
  throw(:argument_error, raise(ArchetypeMethodsError, "For #{@archetype}, calling #archetype_respond_to? using method_sym=#{method_sym} led to argument_error"))
end

#archetype_respond_to_procObject



18
19
20
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 18

def archetype_respond_to_proc
  proc { |method_sym| @archetype.__send__(:respond_to?, method_sym) }
end

#archetype_send(method_sym, *args, &b) ⇒ Object



32
33
34
35
36
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 32

def archetype_send(method_sym, *args, &b)
  archetype_send_proc.call(method_sym, *args, &b)
rescue NameError => e
  throw(:argument_error, raise(ArchetypeMethodsError, "For #{@archetype}, calling #archetype_send using method_sym=#{method_sym} and args=#{args} with &b=#{b} led to argument_error"))
end

#archetype_send_procObject



22
23
24
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 22

def archetype_send_proc
  proc { |method_sym, *args, &b| @archetype.__send__(method_sym, *constrained_args_for(method_sym, args)) }
end

#check_conditions?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 117

def check_conditions?
  @opts[:nonnil] && arguments.empty? or @opts[:present] && arguments.any?(:present?)
end

#constrained_args_for(method_sym, args) ⇒ Object

All those for these



91
92
93
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 91

def constrained_args_for(method_sym, args)
  args.take(maximum_args(method_sym).unless?(:finite?) { args.size })
end

#maximum_args(method_sym) ⇒ Object



85
86
87
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 85

def maximum_args(method_sym)
  Array.new(2, "maximum_args_from_").zip(%w(params arity)).map { |strs| self.__send__(strs.join, method_sym) }.max # from .min...
end

#maximum_args_from_arity(method_sym) ⇒ Object



81
82
83
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 81

def maximum_args_from_arity(method_sym)
  archetype_method_arity(method_sym).abs
end

#maximum_args_from_params(method_sym) ⇒ Object



76
77
78
79
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 76

def maximum_args_from_params(method_sym)
  return 1.0/0 if archetype_method_params(method_sym).detect { |type, meth| type == :rest }
  archetype_method_params(method_sym).inject(0) { |sum, (type, meth)| sum += maximums_for_param_types[type] }
end

#maximums_for_param_typesObject

Maximum number of args



72
73
74
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 72

def maximums_for_param_types
  { :req => 1, :opt => 1, :block => 1, :rest => 1.0/0 }
end

#minimum_args(method_sym) ⇒ Object



66
67
68
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 66

def minimum_args(method_sym)
  Array.new(2, "minimum_args_from_").zip(%w(params arity)).map { |strs| self.__send__(strs.join, method_sym) }.max
end

#minimum_args_from_arity(method_sym) ⇒ Object



62
63
64
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 62

def minimum_args_from_arity(method_sym)
  archetype_method_arity(method_sym).if?(:negative?).succ.abs # upto succ only happens to negatives.
end

#minimum_args_from_params(method_sym) ⇒ Object

Minimum number of args



58
59
60
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 58

def minimum_args_from_params(method_sym)
  archetype_method_params(method_sym).count { |type, meth| type == :req }
end

#provided_minimum_arguments?(method_sym, arguments) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
98
# File 'lib/quarter_system/argumentation/argument_merger.rb', line 95

def provided_minimum_arguments?(method_sym, arguments)
  minimum_args(method_sym) >  maximum_args(method_sym)  and raise ArchetypeError, "Range of argument arity is invalid!"
  minimum_args(method_sym) <= arguments.size
end