potrubi 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,226 @@
1
+
2
+ # potrubi contract recipes
3
+
4
+ # to ease the creation of contracts, accessors, etc in class bodies
5
+
6
+ # These are *mixin* ('class') methods; not instance ones
7
+
8
+ # Uses conventions for names etc dedined by (in) contract mixin
9
+
10
+ require_relative '../bootstrap'
11
+
12
+ requireList = %w(contract util)
13
+ requireList.each {|r| require_relative "#{r}"}
14
+
15
+ mixinContent = Module.new do
16
+
17
+ include Potrubi::Bootstrap
18
+ include Potrubi::Mixin::Util
19
+
20
+ def standard_accessor_edit(k, v)
21
+ {ACCESSOR_NAME: k, ACCESSOR_CONTRACT: k}
22
+ end
23
+
24
+ def standard_mustbe_edit(k, v)
25
+ {MUSTBE_NAME: k, MUSTBE_SPEC: k}
26
+ end
27
+
28
+ # convenience methods
29
+
30
+ def merge_edits(*edits)
31
+ Potrubi::Mixin::Dynamic.dynamic_merge_edits(*edits)
32
+ end
33
+
34
+ def merge_specs(*specs)
35
+ specs.flatten
36
+ end
37
+
38
+ def merge_spec_and_edit(spec, edit)
39
+ { edit: edit, spec: spec}
40
+ end
41
+
42
+ # This method is peculair to accessors & mustbes
43
+ # not general purpose as e.g. hash treatment makes assumptions
44
+
45
+ def standard_case_statement(k, v, s, edit, spec)
46
+ eye = :'rcp_std_case'
47
+ r = case v
48
+ when Symbol then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: "testValue.is_a?(#{v.to_s.capitalize})"}))
49
+ when Class, String then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: "testValue.is_a?(#{v})"}))
50
+ when NilClass then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: 'testValue'}))
51
+ when Array then v # dynamic_define_methods will parse
52
+ when Proc then
53
+ [ merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: 'false'})), # error on default isValueText
54
+ {name: "is_value_#{k}?", spec: v}, # ... but override is_value method
55
+ ]
56
+ when Hash then merge_spec_and_edit(merge_specs([spec, v[:spec]]), merge_edits(edit, {IS_VALUE_TEST: 'false'}, v[:edit]))
57
+ else
58
+ potrubi_bootstrap_surprise_exception(v, eye, "accessor name >#{k}< spec not expected")
59
+ end
60
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ca(eye, potrubi_bootstrap_logger_fmt_who(k: k, v: v, edit: edit), potrubi_bootstrap_logger_fmt_who(spec: spec), potrubi_bootstrap_logger_fmt_who(r: r))
61
+ r
62
+ #STOPCASEEXIT
63
+ end
64
+
65
+ def standard_accessor_recipe_block(s) # returns a lambda
66
+ ->(k, v) {
67
+ edit = standard_accessor_edit(k, v)
68
+ ###spec = {spec: s}
69
+ spec = s
70
+ r = standard_case_statement(k, v, s, edit, spec)
71
+ #puts("\n\n\nACCE RCP BLOK r >#{r}<\n\n\n")
72
+ r
73
+ #STOPACCEBLOK
74
+ }
75
+ end
76
+
77
+ def standard_mustbe_recipe_block(s) # returns a lambda
78
+ ->(k, v) {
79
+ edit = standard_mustbe_edit(k, v)
80
+ ###spec = {spec: s}
81
+ spec = s
82
+ r = standard_case_statement(k, v, s, edit, spec)
83
+ #puts("\n\n\nMUSTBE RCP BLOK r >#{r}<")
84
+ r
85
+ }
86
+ end
87
+
88
+
89
+ def resolve_recipe_texts(*recipeTexts)
90
+ eye = :'rslv_rcp_texts'
91
+
92
+ utilityText = Potrubi::Mixin::Contract::CONTRACT_TEXTS
93
+
94
+ resolvedTexts = recipeTexts.flatten.map do | recipeText |
95
+ puts("recipeText >#{recipeText.class}< >#{recipeText}<")
96
+ case recipeText
97
+ when Symbol then utilityText[recipeText]
98
+ when Proc then recipeText
99
+ else
100
+ potrubi_bootstrap_surprise_exception(recipeText, eye, "recipeText is what?")
101
+ ###recipeText
102
+ end
103
+ end
104
+
105
+ resolvedTexts
106
+
107
+ end
108
+ def resolve_recipe_texts(*recipeTexts)
109
+ recipeTexts.flatten
110
+ end
111
+
112
+
113
+ def recipe_accessors(attrTarget, attrDefs, *attrTexts, &attrBlok)
114
+ eye = :'rcp_accessors'
115
+
116
+ ###STOPHEREACCS
117
+
118
+ #puts("K0")
119
+
120
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
121
+
122
+ #puts("K1")
123
+
124
+ #textDefs = resolve_recipe_texts(attrTexts)
125
+ textDefs = resolve_recipe_texts(attrTexts.empty? ? :package_accessor_with_contract : attrTexts) # default is contract accessor
126
+
127
+ #puts("TEXT DEFS >#{textDefs.class}< >#{textDefs}<")
128
+
129
+ procBlok = Kernel.block_given? ? attrBlok : standard_accessor_recipe_block(textDefs)
130
+
131
+ Potrubi::Mixin::Dynamic.dynamic_define_methods(attrTarget, attrDefs, &procBlok)
132
+
133
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
134
+
135
+ self
136
+
137
+ ##STOPHEREACCSEXIT
138
+ end
139
+
140
+ def recipe_mustbes(attrTarget, attrDefs, *attrTexts, &attrBlok)
141
+ eye = :'rcp_mustbes'
142
+
143
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
144
+
145
+ textDefs = resolve_recipe_texts(attrTexts.empty? ? :package_mustbe : attrTexts) # default is standard mustbe
146
+
147
+ procBlok = Kernel.block_given? ? attrBlok : standard_mustbe_recipe_block(textDefs)
148
+
149
+ Potrubi::Mixin::Dynamic.dynamic_define_methods(attrTarget, attrDefs, &procBlok)
150
+
151
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
152
+
153
+ self
154
+
155
+ end
156
+
157
+ end
158
+
159
+ module Potrubi
160
+ module Mixin
161
+ module ContractRecipes
162
+ end
163
+ end
164
+ end
165
+
166
+ Potrubi::Mixin::ContractRecipes.extend(mixinContent) # Make mixin methods
167
+
168
+ __END__
169
+
170
+ # quick tests
171
+
172
+ require '../core'
173
+
174
+ $DEBUG = true
175
+ $DEBUG_POTRUBI_BOOTSTRAP = true
176
+
177
+ testClass = Class.new do
178
+
179
+ include Potrubi::Core
180
+
181
+ attrAccessors = {
182
+ #jmx_user: :string,
183
+ #jmx_pass: :string,
184
+ #jmx_host: :string,
185
+ ###jmx_port: :string,
186
+ #jmx_port: :fixnum,
187
+ #jmx_connection: nil,
188
+ #jmx_connection: 'JMX::MBeanServerConnectionProxy',
189
+ #beans_attributes: :hash,
190
+ #beans_specifications: :hash,
191
+ #jmx_host: ->(h) {h.is_a?(String)},
192
+
193
+ #jmx_orts: {spec: 'def is_value_jmx_orts?(v); v.is_a?(String); end'},
194
+
195
+ #jmx_keys: {edit: {ACCESSOR_KEYS: 'self.class.accessor_keys'},
196
+ #spec: :method_accessor_is_value_and_keys}
197
+
198
+ jmx_users1: {edit: {KEY_TYPE: :string, VALUE_TYPE: :jmx_user}, spec: :method_accessor_is_value_typed_collection},
199
+ jmx_users2: {edit: {KEY_TYPE: :string, VALUE_TYPE: :jmx_user, VALUE_IS_NIL_RESULT: 'true', KEY_NAMES: [:a, :b, :c]}, spec: :method_accessor_is_value_typed_collection_with_keys}
200
+
201
+
202
+ }
203
+
204
+ attraccessorTexts = [:package_accessor_with_contract]
205
+
206
+ Potrubi::Mixin::ContractRecipes.recipe_accessors(self, attrAccessors, attraccessorTexts)
207
+
208
+
209
+ mustbeContracts = {
210
+ what1: :string,
211
+ what2: :hash,
212
+ what3: 'Riemann::Feed::Feeder'
213
+ }
214
+
215
+ #Potrubi::Mixin::ContractRecipes.recipe_mustbes(self, mustbeContracts)
216
+
217
+ end
218
+
219
+ testInst = testClass.new
220
+
221
+ #testInst.mustbe_jmx_host_or_croak('A string')
222
+ #testInst.mustbe_jmx_host_or_croak(:symbol)
223
+ #testInst.mustbe_jmx_orts_or_croak('A string')
224
+ #testInst.mustbe_jmx_orts_or_croak(:symbol)
225
+ __END__
226
+
@@ -0,0 +1,105 @@
1
+
2
+ # potrubi contract methods
3
+
4
+ require_relative '../bootstrap'
5
+ require_relative "dynamic"
6
+
7
+ #requireList = %w(dynamic)
8
+ #requireList.each {|r| require_relative "#{r}"}
9
+
10
+ #$DEBUG = true
11
+ #$DEBUG_POTRUBI_BOOTSTRAP = true
12
+
13
+ mixinContent = Module.new do
14
+
15
+ # mustbe contracts
16
+
17
+ mustbeDefaultSpec = [:package_mustbe]
18
+ mustbeLimited1OneArgSpec = [:method_mustbe_one_arg, :alias_is_value_value_is]
19
+ mustbeLimited2OneArgSpec = [mustbeLimited1OneArgSpec, :method_mustbe_key, :method_mustbe_one_arg_or_nil, :method_mustbe_collections].flatten
20
+ mustbeLimited1TwoArgSpec = [:method_mustbe_two_arg, :alias_is_value_value_is]
21
+
22
+ mustbeMethods = {
23
+ :hash => [:package_mustbe, :method_mustbe_hash_with_proc, :method_mustbe_one_arg_or_nil_with_proc].flatten,
24
+ #=begin
25
+ :array => [:package_mustbe, :method_mustbe_array_with_proc, :method_mustbe_one_arg_or_nil_with_proc, :method_mustbe_subset].flatten,
26
+ :string => nil,
27
+ :symbol => nil,
28
+ :fixnum => nil,
29
+ :range => nil,
30
+ :proc => nil,
31
+ :class => nil,
32
+ :module => nil,
33
+ :time => nil,
34
+ :enumerator => nil,
35
+ :regexp => nil,
36
+ :struct => nil,
37
+ :empty => [{:name => :'is_value_empty?', :spec => ->(c) {(c.respond_to?(:empty?) && c.empty?) ? c : nil }}, mustbeLimited1OneArgSpec].flatten,
38
+ :not_empty => [{:name => :'is_value_not_empty?', :spec => ->(c) {(c.respond_to?(:empty?) && (! c.empty?)) ? c : nil }}, mustbeLimited1OneArgSpec].flatten,
39
+ :not_nil => [{:name => :'is_value_not_nil?', :spec => ->(c) { c }}, mustbeLimited1OneArgSpec].flatten,
40
+ :file => [{:name => :'is_value_file?', :spec => ->(f) {(f.is_a?(String) && File.file?(f)) ? f : nil}}, mustbeLimited2OneArgSpec].flatten,
41
+ :directory => [{:name => :'is_value_directory?', :spec => ->(d) {(f.is_a?(String) && File.directory?(d)) ? d : nil}}, mustbeLimited2OneArgSpec].flatten,
42
+ :file_or_directory => [{:name => :'is_value_file_or_directory?', :spec => ->(e) {(e.is_a?(String) && (File.file?(e) || File.directory?(e))) ? e : nil}}, mustbeLimited2OneArgSpec].flatten,
43
+ :key => [{:name => :'is_value_key?', :spec => ->(h,k) {(h.respond_to?(:has_key?) && h.has_key?(k)) ? h[k] : nil}}, mustbeLimited1TwoArgSpec].flatten,
44
+ :not_key => [{:name => :'is_value_not_key?', :spec => ->(h,k) {is_value_key?(h,k) ? nil : k}}, mustbeLimited1TwoArgSpec].flatten,
45
+ :any => [{:name => :'is_value_any?', :spec => ->(v) {v} }].flatten,
46
+ :same_class => [{:name => :'is_value_same_class?', :spec => ->(p,q) {((r = p.class) == q.class) ? r : nil}}, mustbeLimited1TwoArgSpec].flatten,
47
+ :instance_of => [{:name => :'is_value_instance_of?', :spec => ->(p,q) {p.instance_of?(q) ? p : nil}}, mustbeLimited1TwoArgSpec].flatten,
48
+ #=end
49
+ }
50
+
51
+ mustbeSpecs = mustbeMethods.each_with_object({}) { | (mustbeName, mustbeSpec), h | h[mustbeName] = mustbeSpec || mustbeDefaultSpec }
52
+
53
+ Potrubi::Mixin::Dynamic::dynamic_define_methods(self, mustbeSpecs) do |k, v|
54
+ edits = {
55
+ ###:MUSTBE_TEST => k.to_s.capitalize,
56
+ IS_VALUE_TEST: "testValue.is_a?(#{k.to_s.capitalize})",
57
+ MUSTBE_NAME: k,
58
+ ###MUSTBE_SPEC: v,
59
+ }
60
+ case v
61
+ when Hash then v.merge({:edit => [edits, v[:edit]]})
62
+ else
63
+ {:edit => edits, :spec => v}
64
+ end
65
+ end
66
+
67
+
68
+ # Compare Contracts
69
+
70
+ compareMethods = {
71
+ :eq => '==',
72
+ :equal => '==',
73
+ :lt => '<',
74
+ :le => '<=',
75
+ :less_or_equal => '<=',
76
+ # :less_than_or_equal => '<=',
77
+ # :lessthan_or_equal => '<=',
78
+ :gt => '>',
79
+ :ge => '>=',
80
+ :greater_or_equal => '>=',
81
+ # :greater_than_or_equal => '>=',
82
+ # :greaterthan_or_equal => '>=',
83
+ :identical => '===',
84
+ :ne => '!=',
85
+ :not_equal => '!=',
86
+ # :lessequal => '<=',
87
+ }
88
+
89
+ Potrubi::Mixin::Dynamic::dynamic_define_methods(self, compareMethods) do | mN, mO |
90
+ # puts "<=> #{eye} mN >#{mN.class}< >#{mN}< mO >#{mO.class}< >#{mO}< textValue >#{textValue.class}< >\n#{textValue}\n<"
91
+ {edit: {MUSTBE_NAME: mN, MUSTBE_SPEC: mO}, spec: :method_mustbe_compare}
92
+ end
93
+
94
+ end
95
+
96
+ module Potrubi
97
+ module Mixin
98
+ module Contract
99
+ end
100
+ end
101
+ end
102
+
103
+ Potrubi::Mixin::Contract.__send__(:include, mixinContent) # Instance Methods
104
+
105
+ __END__
@@ -0,0 +1,100 @@
1
+
2
+ # potrubi mixin dynamic
3
+
4
+ # dynamic method, etc generation
5
+
6
+ require_relative '../bootstrap'
7
+ require_relative 'dynamic'
8
+
9
+ metaclassMethods = Module.new do
10
+
11
+ include Potrubi::Bootstrap
12
+ include Potrubi::Mixin::Dynamic
13
+
14
+ #=begin
15
+ def recipe_new(tgtMod, newSpecs, &block)
16
+ dynamic_define_methods(tgtMod, newSpecs) do | newName, newKlass |
17
+
18
+ edits = {
19
+ :et_new_name => newName.to_s.downcase,
20
+ :et_new_class => newKlass.to_s,
21
+ :et_new_eyecatcher => "new_#{newName}".downcase,
22
+ }
23
+
24
+ newText = <<-'ENDOFMETHOD'
25
+ def new_et_new_name_or_croak(*a, &b)
26
+ r = et_new_class.new(*a, &b)
27
+ logger_ca(:et_new_eyecatcher, logger_fmt_who(:'et_new_name' => r))
28
+ r
29
+ end
30
+ ENDOFMETHOD
31
+
32
+ {:edit => edits, :spec => newText}
33
+
34
+ end
35
+ end
36
+ #=end
37
+ #=begin
38
+ def recipe_rescue_croak(tgtMod, croakSpecs, &block)
39
+ dynamic_define_methods(tgtMod, croakSpecs) { | rescueName, rescueValue | "def #{rescueName}(*a, &b); #{rescueName}_or_croak(*a, &b) rescue #{rescueValue || 'nil'}; end\n" }
40
+ end
41
+ #=end
42
+
43
+ #=begin
44
+ def recipe_aliases(tgtMod, aliasSpecs, &block)
45
+ dynamic_define_methods(tgtMod, aliasSpecs) { | aliasName, realName | "alias_method :'#{aliasName}', :'#{realName}';\n" }
46
+ end
47
+ #=end
48
+
49
+ #=begin
50
+ def recipe_croak_rescue(targetModule, croakArgs={}, &croakBlok)
51
+ eye = :rcp_crk_rsc
52
+
53
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, "targetModule >#{targetModule.class}< >#{targetModule}< croakArgs >#{croakArgs}<")
54
+
55
+ potrubi_bootstrap_mustbe_module_or_croak(targetModule, eye)
56
+
57
+ knownMethods = targetModule.instance_methods.map(&:to_s)
58
+
59
+ includeMethods = (r = croakArgs[:include]) ? [r].flatten.compact.uniq.map(&:to_s) : knownMethods
60
+ excludeMethods = (r = croakArgs[:exclude]) ? [r].flatten.compact.uniq.map(&:to_s) : []
61
+
62
+ wantedMethods = includeMethods - excludeMethods
63
+
64
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "wantedMethods >#{wantedMethods}< knownMethods >#{knownMethods}< includeMethods >#{includeMethods}< excludeMethods >#{excludeMethods}<")
65
+
66
+ croakRegexp = Regexp.new(/(.*)_or_croak\?*/)
67
+ croakMethods = wantedMethods.map {|m| (mD = m.match(croakRegexp)) ? mD[1] : nil }.compact
68
+
69
+ croakUndefinedMethods = croakMethods.reject {|m| knownMethods.include?(m) } # method already defined?
70
+
71
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "croakUndefinedMethods >#{croakUndefinedMethods.class}< >#{croakUndefinedMethods}< croakMethods >#{croakMethods}<")
72
+
73
+ croakUndefinedMethodsHash = Hash[*croakUndefinedMethods.map {|m| [m, nil]}.flatten]
74
+
75
+ recipe_rescue_croak(targetModule, croakUndefinedMethodsHash)
76
+
77
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, "targetModule >#{targetModule.class}< >#{targetModule}< croakUndefinedMethods >#{croakUndefinedMethodsHash}<")
78
+
79
+ self
80
+ end
81
+ #=end
82
+
83
+
84
+
85
+ end
86
+ #=end
87
+
88
+ module Potrubi
89
+ module Mixin
90
+ module DynamicRecipes
91
+ end
92
+ end
93
+ end
94
+
95
+ Potrubi::Mixin::DynamicRecipes.extend(metaclassMethods)
96
+ Potrubi::Mixin::DynamicRecipes.__send__(:include, metaclassMethods) # Instance Methods
97
+
98
+
99
+ __END__
100
+
@@ -0,0 +1,315 @@
1
+
2
+ # potrubi mixin dynamic
3
+
4
+ # dynamic method, etc generation
5
+
6
+ require_relative '../bootstrap'
7
+
8
+ metaclassMethods = Module.new do
9
+
10
+ include Potrubi::Bootstrap
11
+
12
+ #=begin
13
+ def dynamic_apply_edits(editSpecInput, *textValues, &block)
14
+ eye = :dyn_apy_edts
15
+ eyeTale = '"TEXT EDITS'
16
+
17
+ #editSpec.is_a?(Hash) || editSpec.is_a?(Enumerator) || (raise ArgumentError,"editSpec >#{editSpec.class}< >#{editSpec}< not hash")
18
+ editSpec = case editSpecInput
19
+ when Hash then editSpecInput
20
+ when Array then dynamic_merge_edits(editSpecInput)
21
+ when NilClass then nil
22
+ else
23
+ potrubi_bootstrap_surpise_exception(editSpecInput, eye, "editSpecInput not has, array or nil")
24
+ ###nil # will error
25
+ end
26
+
27
+ editSpec && potrubi_bootstrap_mustbe_hash_or_croak(editSpec, "editSpec not hash")
28
+
29
+ #potrubi_bootstrap_logger_me(eye, eyeTale, "editSpec", editSpec, "textValues >\n#{textValues}")
30
+
31
+ textValue = textValues.flatten.compact.join("\n")
32
+
33
+ textFinal = case editSpec
34
+ when NilClass then textValue
35
+ else
36
+
37
+ newtextValue = nil
38
+
39
+ recurseMax = 16
40
+ recurseCnt = 0
41
+ until (textValue == newtextValue)
42
+
43
+ ((recurseCnt +=1) <= recurseMax) || potrubi_bootstrap_surprise_exception(recurseCnt, eye, "recurseMax >#{recurseMax}< exceeded")
44
+
45
+ textValue = newtextValue || textValue
46
+ newtextValue = editSpec.inject(textValue) { |txt, (key, val)| txt.gsub(/#{key}/,"#{val}") }
47
+ ###puts("APY EDTS recurseCnt >#{recurseCnt}< newtestValue >#{newtextValue}<")
48
+ end
49
+
50
+ newtextValue
51
+
52
+ end
53
+
54
+ # support for uniquenesses needed?
55
+
56
+ #while (textFinal =~ /METHOD_UNIQUENESS/)
57
+ # textFinal = textFinal.sub(/METHOD_UNIQUENESS/, rand(1000000000000).to_s) # Each UNQIUENESS is unique!
58
+ #end
59
+
60
+ #potrubi_bootstrap_logger_mx(eye, eyeTale, "textFinal >#{textFinal.class}< >\n#{textFinal}\n<")
61
+
62
+ textFinal
63
+
64
+ end
65
+ #=end
66
+
67
+ #=begin
68
+ def dynamic_merge_edits(*edits)
69
+ r = edits.flatten.compact.inject({}) {|s, h| s.merge(potrubi_bootstrap_mustbe_hash_or_croak(h))}
70
+ r.empty? ? nil : r
71
+ end
72
+ #=end
73
+
74
+ #=begin
75
+ def dynamic_define_methods(targetModule, methodDefs, dynArgs=nil, &dynBlok)
76
+ eye = :dyn_def_mtds
77
+
78
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, "targetModule >#{targetModule.class}< >#{targetModule}< specs >#{methodDefs.class}< >#{methodDefs}< dynArgs >#{dynArgs.class}< >#{dynArgs}< dynBlok >#{dynBlok}<")
79
+
80
+ potrubi_bootstrap_mustbe_module_or_croak(targetModule, eye, "targetModule not module")
81
+
82
+ potrubi_bootstrap_mustbe_hash_or_croak(methodDefs, eye, "methodDefs not hash")
83
+
84
+ dynArgs && potrubi_bootstrap_mustbe_hash_or_croak(dynArgs, eye, "dynArgs not hash")
85
+
86
+ editArgs = dynArgs && dynArgs[:edit]
87
+
88
+ #methodTexts = nil # will hold texts for methods, if any (could be all define_methods)
89
+
90
+ dynSpecsAll = methodDefs.map do | mtdKey, mtdVal |
91
+
92
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, "BEG MTH mtdKey >#{mtdKey.class}< >#{mtdKey}< mtdVal >#{mtdVal.class}< >#{mtdVal.class}< editArgs >#{editArgs .class}< >#{editArgs}<")
93
+
94
+ mtdValCollection = case mtdVal
95
+ when Array then mtdVal
96
+ when Hash, String, Symbol, Proc then [mtdVal]
97
+ when NilClass then [mtdKey]
98
+ else
99
+ potrubi_bootstrap_surprise_exception(mtdVal, eye, "mtdVal is what?")
100
+ end
101
+
102
+ dynResultsBlok = Kernel.block_given? ? mtdValCollection.map {|v| dynBlok.call(mtdKey, v) } : mtdValCollection
103
+
104
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, "CASE GEN mtdKey >#{mtdKey.class}< >#{mtdKey}< mtdVal >#{mtdVal.class}< >#{mtdVal}< dynResultsBlok >#{dynResultsBlok.class}< >#{dynResultsBlok}<")
105
+
106
+ editMtd = nil # no default edits
107
+
108
+ dynResultsNorm = [dynResultsBlok].flatten(1).map do | dynResult |
109
+ case dynResult
110
+ when NilClass then nil
111
+ when Array then
112
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "CASE ARRAY mtdKey >#{mtdKey.class}< >#{mtdKey}< dynResult >#{dynResult.class}< >#{dynResult}<")
113
+ dynResult # expected to have got is all right
114
+ when String, Symbol then
115
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "CASE STRING, SYMBOL mtdKey >#{mtdKey.class}< >#{mtdKey}< dynResult >#{dynResult.class}< >#{dynResult}<")
116
+ #{:edit => [editMtd, editArgs], :spec => dynResult}
117
+ {spec: dynResult}
118
+ when Proc then
119
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "CASE PROC mtdKey >#{mtdKey.class}< >#{mtdKey}< dynResult >#{dynResult.class}< >#{dynResult}<")
120
+ {name: mtdKey, spec: dynResult}
121
+ when Hash then
122
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "CASE HASH mtdVal >#{mtdKey.class}< >#{mtdKey}< dynResult >#{dynResult.class}< >#{dynResult}<")
123
+ dynResult # expected to have gotten it right
124
+ else
125
+ potrubi_bootstrap_surprise_exception(dynResult, eye, "dynResult is what?")
126
+ end
127
+
128
+ end.flatten.compact
129
+
130
+
131
+ dynSpecs = [*dynResultsNorm].map do | dynResult |
132
+
133
+ potrubi_bootstrap_mustbe_hash_or_croak(dynResult, eye, "dynResult not hash")
134
+
135
+ editAll = case
136
+ when dynResult.has_key?(:edit) then # edit key set?
137
+ editLocal = dynResult[:edit]
138
+ # if edit key is nil => NO EDITS AT ALL
139
+ editLocal ? [editMtd, editArgs, editLocal] : nil
140
+ else
141
+ # wants defaults; there was no point returning hash
142
+ [editMtd, editArgs]
143
+ end
144
+
145
+ editAll ? dynResult.merge({:edit => editAll}) : dynResult
146
+
147
+ end
148
+
149
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, "FIN MTH mtdKey >#{mtdKey.class}< >#{mtdKey}< dynSpecs >#{dynSpecs.class}< >#{dynSpecs}<")
150
+
151
+
152
+ #dynamic_define_methods_apply(targetModule, dynSpecs)
153
+ dynSpecs
154
+ end
155
+
156
+ dynamic_define_methods_apply(targetModule, dynSpecsAll)
157
+
158
+
159
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, "targetModule >#{targetModule.class}< >#{targetModule}< specs >#{methodDefs.class}< >#{methodDefs.class}< dynArgs >#{dynArgs.class}< >#{dynArgs}<")
160
+ self
161
+
162
+ end
163
+ #=end
164
+
165
+ #=begin
166
+ def dynamic_define_methods_apply(targetModule, *methodSpecs, &dynBlok)
167
+ eye = :ddm_apl
168
+ eyeTale = 'DDM APL'
169
+
170
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, eyeTale, "targetModule >#{targetModule.class}< >#{targetModule}< specs >#{methodSpecs.class}< >#{methodSpecs.size}< >#{methodSpecs.class}< dynBlok >#{dynBlok}<")
171
+
172
+ # try to merge all the text methods together
173
+
174
+ textMethods = []
175
+
176
+ methodSpecs.flatten.compact.each_with_index do | methodSpec, methodNdx |
177
+
178
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ms(eye, eyeTale, "methodNdx >#{methodNdx}< methodSpec >#{methodSpec.class}< >#{methodSpec}<")
179
+
180
+ potrubi_bootstrap_mustbe_hash_or_croak(methodSpec)
181
+
182
+ case (specType = methodSpec[:spec])
183
+ when Proc then
184
+
185
+ specName = potrubi_bootstrap_mustbe_string_or_croak((r = methodSpec[:name]) ? r.to_s : nil)
186
+ specProc = specType # potrubi_bootstrap_mustbe_proc_or_croak(mustbe_key_or_croak(methodSpec, :proc))
187
+
188
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "PROC BEG specName >#{specName.class}< >#{specName}< specProc >#{specProc.class}< >#{specProc}<")
189
+
190
+ textMethods.empty? || begin # any text methods "waiting"; must be serial defined before proc
191
+ dynamic_define_methods_apply_texts(targetModule, *textMethods)
192
+ textMethods.clear # none wating now
193
+ end
194
+
195
+ targetModule.__send__(:define_method, specName.to_sym, &specProc)
196
+
197
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "PROC FIN specName >#{specName.class}< >#{specName}< specProc >#{specProc.class}< >#{specProc}<")
198
+
199
+ when String, Symbol then textMethods << methodSpec
200
+ when Array then textMethods << methodSpec
201
+ else
202
+ potrubi_bootstrap_surprise_exception(specType, "methodSpec >#{methodSpec.class}< >#{methodSpec.class}< specType >#{specType.class}< is what?")
203
+ end
204
+
205
+ end
206
+
207
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "TXTS textMethods >#{textMethods.class}< >#{textMethods}<")
208
+
209
+ textMethods.empty? || dynamic_define_methods_apply_texts(targetModule, *textMethods)
210
+
211
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, eyeTale, "targetModule >#{targetModule.class}< >#{targetModule}< specs >#{methodSpecs.class}< >#{methodSpecs.size}<")
212
+
213
+ self
214
+
215
+ end
216
+ #=end
217
+
218
+ def dynamic_define_methods_apply_texts(targetModule, *methodSpecs, &dynBlok)
219
+ eye = :ddm_apl_txt
220
+ eyeTale = 'DDM APL TXTS'
221
+
222
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, eyeTale, "targetModule >#{targetModule.class}< >#{targetModule}< specs >#{methodSpecs.class}< >#{methodSpecs}<")
223
+
224
+ #STOPAPPLYTEXTS
225
+
226
+ begin
227
+
228
+ methodTexts = methodSpecs.flatten.compact.map do | methodSpec |
229
+
230
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "BEG methodSpec >#{methodSpec.class}< >#{methodSpec}<\n\n\n")
231
+
232
+ potrubi_bootstrap_mustbe_hash_or_croak(methodSpec)
233
+
234
+ ###methodTextNom = potrubi_bootstrap_mustbe_string_or_croak([methodSpec[:spec]].flatten.compact.join)
235
+
236
+ methodEdit = methodSpec[:edit]
237
+ methodText = methodSpec[:spec]
238
+
239
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "EDIT & SPEC methodEdit >#{methodEdit}< methodText >#{methodText.class}< >#{methodText}<")
240
+
241
+ #STOPEDITANDTEXT
242
+
243
+ # Resolve any snippets
244
+
245
+ #methodSnipNom = potrubi_bootstrap_mustbe_string_or_croak(Potrubi::Mixin::TextSnippets.map_snippets_or_croak(:dynamic_methods, *methodText).flatten.compact.join)
246
+ methodSnippets = Potrubi::Mixin::TextSnippets.map_snippets_or_croak(:dynamic_methods, *methodText)
247
+
248
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "SNIP methodSnippets >#{methodSnippets.class}< >#{methodSnippets}<")
249
+
250
+ #STOPMETHODSNIPNOM
251
+
252
+ snipEdits = []
253
+
254
+ snipTexts = methodSnippets.inject([]) do | textList, snipItem |
255
+
256
+ ###puts("\nSNIP ITEM >#{snipItem.class}< >#{snipItem}<")
257
+
258
+ textList << case snipItem
259
+ when Hash
260
+ snipEdits << snipItem[:edit] # collect any edits e.g. defaults
261
+ ###potrubi_bootstrap_mustbe_string_or_croak(snipItem[:spec]) # return the text
262
+ snipItem[:spec]
263
+ when String then snipItem
264
+ else
265
+ potrubi_bootstrap_surprise_exception(methodTextNom, eye, "methodTextNom unexpected")
266
+ end
267
+
268
+ end
269
+
270
+ methodText = dynamic_apply_edits([snipEdits, methodEdit], snipTexts) # note order of edits
271
+
272
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "FIN methodEdit >#{methodEdit}< snipEdits >#{snipEdits}< methodText >#{methodText}<\n\n\n")
273
+
274
+ #STOPMETHODFIN
275
+
276
+ methodText
277
+
278
+ end.flatten.compact.join("\n")
279
+ rescue Exception => e
280
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye,"exception >#{e}<")
281
+ stopINDYNAPP3RESCUE
282
+ end
283
+
284
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "METHODS targetModule >#{targetModule.class}< >#{targetModule}< methodTexts >#{methodTexts.class}< >\n#{methodTexts}\n<")
285
+
286
+ methodTexts && targetModule.module_eval(methodTexts)
287
+
288
+ $DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger(eye, eyeTale, "targetModule >#{targetModule.class}< >#{targetModule}< specs >#{methodSpecs.class}< >#{methodSpecs.size}<")
289
+
290
+ self
291
+
292
+ end
293
+ #=end
294
+
295
+ end
296
+ #=end
297
+
298
+ module Potrubi
299
+ module Mixin
300
+ module Dynamic
301
+ end
302
+ end
303
+ end
304
+
305
+ Potrubi::Mixin::Dynamic.extend(metaclassMethods) # Module methods
306
+ Potrubi::Mixin::Dynamic.__send__(:include, metaclassMethods) # Instance Methods
307
+
308
+ # must be after dynamic is up
309
+
310
+ requireList = %w(text-snippets)
311
+ requireList.each {|r| require_relative "#{r}"}
312
+
313
+ __END__
314
+
315
+