potrubi 0.0.3 → 0.0.4
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.
- data/lib/potrubi.rb +1 -1
- data/lib/potrubi/bootstrap.rb +1 -1
- data/lib/potrubi/core.rb +3 -3
- data/lib/potrubi/dsl.rb +86 -0
- data/lib/potrubi/dsl/accessor.rb +76 -0
- data/lib/potrubi/dsl/cache_2d.rb +811 -0
- data/lib/potrubi/dsl/contract.rb +731 -0
- data/lib/potrubi/dsl/super.rb +517 -0
- data/lib/potrubi/klass/syntax/alias.rb +150 -0
- data/lib/potrubi/klass/syntax/braket.rb +115 -25
- data/lib/potrubi/klass/syntax/builder.rb +45 -0
- data/lib/potrubi/klass/syntax/method.rb +436 -0
- data/lib/potrubi/klass/syntax/mixin/name_generation.rb +85 -0
- data/lib/potrubi/klass/syntax/mixin/new_aliases.rb +76 -0
- data/lib/potrubi/klass/syntax/mixin/new_brakets.rb +89 -0
- data/lib/potrubi/klass/syntax/mixin/new_methods.rb +158 -0
- data/lib/potrubi/klass/syntax/mixin/new_snippets.rb +74 -0
- data/lib/potrubi/klass/syntax/mixin/new_statements.rb +0 -0
- data/lib/potrubi/klass/syntax/mixin/statement_management.rb +69 -0
- data/lib/potrubi/klass/syntax/mixin/synel_management.rb +168 -0
- data/lib/potrubi/klass/syntax/snippet.rb +386 -0
- data/lib/potrubi/klass/syntax/statement.rb +91 -0
- data/lib/potrubi/klass/syntax/super.rb +88 -0
- data/lib/potrubi/mixin/bootstrap_common.rb +38 -12
- data/lib/potrubi/mixin/configuration.rb +31 -3
- data/lib/potrubi/mixin/contract.rb +5 -14
- data/lib/potrubi/mixin/contract/recipes.rb +307 -0
- data/lib/potrubi/mixin/dynamic-recipes.rb +1 -11
- data/lib/potrubi/mixin/dynamic.rb +223 -115
- data/lib/potrubi/mixin/exception.rb +3 -22
- data/lib/potrubi/mixin/filesys.rb +5 -21
- data/lib/potrubi/mixin/initialize.rb +11 -6
- data/lib/potrubi/mixin/konstant.rb +14 -118
- data/lib/potrubi/mixin/logger.rb +28 -41
- data/lib/potrubi/mixin/pathandnames.rb +4 -34
- data/lib/potrubi/mixin/persistence.rb +115 -10
- data/lib/potrubi/mixin/script.rb +0 -5
- data/lib/potrubi/mixin/{text-snippets → snippet-dictionaries}/methods-text-snippets.rb +138 -49
- data/lib/potrubi/mixin/{text-snippets.rb → snippet-manager.rb} +51 -39
- data/lib/potrubi/mixin/util.rb +66 -20
- data/lib/potrubi/version.rb +1 -1
- data/test/potrubi/mixin/bootstrap_common.rb +205 -0
- data/test/potrubi/mixin/konstant.rb +216 -0
- data/test/potrubi/mixin/logger.rb +124 -0
- data/test/ts_bootstrap_mixins.rb +16 -0
- data/test/ts_core_mixins.rb +7 -0
- metadata +31 -6
- data/lib/potrubi/mixin/contract-recipes.rb +0 -226
@@ -0,0 +1,91 @@
|
|
1
|
+
|
2
|
+
# potrubi contract dsl
|
3
|
+
|
4
|
+
# syntax methods
|
5
|
+
|
6
|
+
# to ease the creation of new statements using text snippets
|
7
|
+
|
8
|
+
#require_relative '../../bootstrap'
|
9
|
+
|
10
|
+
requireList = %w(super)
|
11
|
+
requireList.each {|r| require_relative "#{r}"}
|
12
|
+
###require "potrubi/klass/syntax/braket"
|
13
|
+
|
14
|
+
instanceMethods = Module.new do
|
15
|
+
|
16
|
+
###include Potrubi::Bootstrap
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
syntax
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
###potrubi_bootstrap_logger_fmt(potrubi_bootstrap_logger_instance_telltale('DSLSynMth'), potrubi_bootstrap_logger_fmt(n: name))
|
24
|
+
@to_inspect ||= potrubi_bootstrap_logger_fmt(potrubi_bootstrap_logger_instance_telltale('DSLSynStm'))
|
25
|
+
end
|
26
|
+
|
27
|
+
def elements
|
28
|
+
@elements ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_elements_or_croak(*newElements)
|
32
|
+
eye = :'PotKlsSynStm::a_eles'
|
33
|
+
|
34
|
+
#newElementsNrm = newElements.flatten.compact.map {|s| mustbe_braket_element_or_croak(s) }
|
35
|
+
newElementsNrm = newElements.flatten.compact
|
36
|
+
|
37
|
+
elements.concat(newElementsNrm)
|
38
|
+
|
39
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ca(eye, potrubi_bootstrap_logger_fmt_who(newEles: newElementsNrm))
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
alias_method :add_elements, :add_elements_or_croak
|
44
|
+
|
45
|
+
def syntax
|
46
|
+
eye = :'PotKlsSynStm::syn'
|
47
|
+
|
48
|
+
braketStatement = new_braket_statement.push(elements)
|
49
|
+
|
50
|
+
syntaxStatement = braketStatement.to_s
|
51
|
+
|
52
|
+
###puts("#{eye} STM SYN #{syntaxStatement}")
|
53
|
+
|
54
|
+
#$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ca(eye, potrubi_bootstrap_logger_fmt_who_only(self: self, size: elements.size, synStm: syntaxStatement))
|
55
|
+
|
56
|
+
syntaxStatement
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
module Potrubi
|
65
|
+
class Klass
|
66
|
+
module Syntax
|
67
|
+
class Statement < Super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Potrubi::Klass::Syntax::Statement.__send__(:include, instanceMethods) # Instance Methods
|
74
|
+
|
75
|
+
__END__
|
76
|
+
|
77
|
+
|
78
|
+
classMethods = Module.new do
|
79
|
+
|
80
|
+
include Potrubi::Bootstrap
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
Potrubi::Klass::Syntax::Statement.extend(classMethods) # Class Methods
|
85
|
+
|
86
|
+
__END__
|
87
|
+
|
88
|
+
m = Potrubi::DSL::Syntax::Method.new_method
|
89
|
+
|
90
|
+
__END__
|
91
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
|
2
|
+
# potrubi contract dsl
|
3
|
+
|
4
|
+
# syntax method
|
5
|
+
|
6
|
+
# to ease the creation of new methods using text manipulation
|
7
|
+
|
8
|
+
#require_relative '../../bootstrap'
|
9
|
+
|
10
|
+
requireList = %w(./mixin/new_brakets ../../mixin/initialize)
|
11
|
+
requireList.each {|r| require_relative "#{r}"}
|
12
|
+
###require "potrubi/klass/syntax/braket"
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
instanceMethods = Module.new do
|
17
|
+
|
18
|
+
include Potrubi::Bootstrap
|
19
|
+
include Potrubi::Mixin::Initialize
|
20
|
+
###include Potrubi::Klass::Syntax::Mixin::Base
|
21
|
+
include Potrubi::Klass::Syntax::Mixin::NewBrakets
|
22
|
+
|
23
|
+
##include Potrubi::Mixin::Util
|
24
|
+
|
25
|
+
###attr_accessor :name, :eye, :signature, :result
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
@to_s ||= potrubi_bootstrap_logger_fmt(potrubi_bootstrap_logger_instance_telltale('DSLSynSpr'), potrubi_bootstrap_logger_fmt(n: name))
|
29
|
+
end
|
30
|
+
|
31
|
+
def mustbe_statement_or_croak(statementValue)
|
32
|
+
statementValue.is_a?(statement_klass) ? statementValue : potrubi_bootstrap_surprise_exception(statementValue, :mustbe_stm, "statementValue not a statement")
|
33
|
+
end
|
34
|
+
|
35
|
+
def mustbe_method_or_croak(methodValue)
|
36
|
+
methodValue.is_a?(method_klass) ? methodValue : potrubi_bootstrap_surprise_exception(methodValue, :mustbe_stm, "methodValue not a statetment")
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
module Potrubi
|
45
|
+
class Klass
|
46
|
+
module Syntax
|
47
|
+
class Super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Potrubi::Klass::Syntax::Super.__send__(:include, instanceMethods) # Instance Methods
|
54
|
+
|
55
|
+
__END__
|
56
|
+
|
57
|
+
|
58
|
+
classMethods = Module.new do
|
59
|
+
|
60
|
+
include Potrubi::Bootstrap
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
Potrubi::Klass::Syntax::Super.extend(classMethods) # Class Methods
|
65
|
+
|
66
|
+
__END__
|
67
|
+
|
68
|
+
m = Potrubi::DSL::Syntax::Super.new
|
69
|
+
|
70
|
+
__END__
|
71
|
+
|
72
|
+
classMethods = Module.new do
|
73
|
+
|
74
|
+
def new_contract(dslArgs=nil, &dslBlok) # class method
|
75
|
+
eye = :'DSLAcc::KLS new_cxt'
|
76
|
+
#potrubi_bootstrap_mustbe_symbol_or_croak(dslAttr, eye, "dslAttr is what?")
|
77
|
+
newContract = self.new(dslArgs, &dslBlok)
|
78
|
+
#$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_ca(eye, potrubi_bootstrap_logger_fmt_who(newContract: newContract), potrubi_bootstrap_logger_fmt_who(dslAttr: dslAttr, dslArgs: dslArgsNrm, dslBlok: dslBlok))
|
79
|
+
newContract
|
80
|
+
###STOPHERENEWCONTRACTEXIT
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Potrubi::Mixin::Contract::DSL.extend(classMethods) # CLass Methods
|
85
|
+
|
86
|
+
__END__
|
87
|
+
|
88
|
+
|
@@ -6,6 +6,7 @@
|
|
6
6
|
|
7
7
|
defined?($DEBUG_POTRUBI_BOOTSTRAP) || ($DEBUG_POTRUBI_BOOTSTRAP = nil)
|
8
8
|
|
9
|
+
#$DEBUG_POTRUBI_BOOTSTRAP = true
|
9
10
|
#$DEBUG = true # TESTING
|
10
11
|
|
11
12
|
require_relative('logger')
|
@@ -14,33 +15,32 @@ module Potrubi
|
|
14
15
|
module Mixin
|
15
16
|
module BootstrapCommon
|
16
17
|
|
17
|
-
#=begin
|
18
18
|
bootstrapLoggerMethods = {
|
19
19
|
logger: :logger_message,
|
20
|
+
logger_instance_telltale: :logger_instance_telltale,
|
20
21
|
logger_me: :logger_me,
|
21
22
|
logger_mx: :logger_mx,
|
22
23
|
logger_ms: :logger_ms,
|
23
24
|
logger_ca: :logger_ca,
|
24
|
-
|
25
|
+
logger_beg: :logger_beg,
|
26
|
+
logger_fin: :logger_fin,
|
27
|
+
logger_fmt: :logger_fmt,
|
28
|
+
logger_fmt_kls: :logger_fmt00,
|
29
|
+
logger_fmt_kls_size: :logger_fmt0000,
|
25
30
|
logger_fmt_who: :logger_fmt0,
|
26
|
-
logger_fmt_who_only: :
|
31
|
+
logger_fmt_who_only: :logger_fmt000,
|
27
32
|
}
|
28
33
|
|
29
34
|
bootstrapLoggerText = bootstrapLoggerMethods.map do | bootMethod, loggerMethod |
|
30
|
-
|
35
|
+
text = <<-"ENDOFHERE"
|
31
36
|
def potrubi_bootstrap_#{bootMethod}(*a, &b)
|
32
|
-
#puts("BOOTLOGR POTRUBI DEBUG >#{$DEBUG_POTRUBI_BOOTSTRAP.class}< >#{$DEBUG_POTRUBI_BOOTSTRAP}<")
|
33
|
-
#puts("BOOTLOGR DEBUG >#{$DEBUG.class}< >#{$DEBUG}<")
|
34
37
|
$DEBUG_POTRUBI_BOOTSTRAP && #{loggerMethod}(*a, &b)
|
35
38
|
end;
|
36
39
|
ENDOFHERE
|
37
40
|
text
|
38
41
|
end.compact.flatten.join("\n")
|
39
42
|
|
40
|
-
###puts("bootstrapLoggerText >\n#{bootstrapLoggerText}")
|
41
|
-
|
42
43
|
self.module_eval(bootstrapLoggerText)
|
43
|
-
#=end
|
44
44
|
|
45
45
|
def potrubi_bootstrap_raise_exception(exception, value, *tellTales)
|
46
46
|
#tellTale = potrubi_bootstrap_logger_format_telltales(*tellTales)
|
@@ -49,7 +49,7 @@ module Potrubi
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def potrubi_bootstrap_surprise_exception(value, *tellTales)
|
52
|
-
potrubi_bootstrap_raise_exception(ArgumentError, value, "value was a
|
52
|
+
potrubi_bootstrap_raise_exception(ArgumentError, value, "value was a surprise", *tellTales)
|
53
53
|
end
|
54
54
|
|
55
55
|
def potrubi_bootstrap_unsupported_exception(value, *tellTales)
|
@@ -59,6 +59,10 @@ module Potrubi
|
|
59
59
|
def potrubi_bootstrap_missing_exception(value, *tellTales)
|
60
60
|
potrubi_bootstrap_raise_exception(ArgumentError, value, "value missing", *tellTales)
|
61
61
|
end
|
62
|
+
|
63
|
+
def potrubi_bootstrap_duplicate_exception(value, *tellTales)
|
64
|
+
potrubi_bootstrap_raise_exception(ArgumentError, value, "duplicate value", *tellTales)
|
65
|
+
end
|
62
66
|
|
63
67
|
def potrubi_bootstrap_mustbe_hash_or_croak(testValue, *tellTales)
|
64
68
|
testValue.is_a?(Hash) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not hash", tellTales)
|
@@ -84,12 +88,24 @@ module Potrubi
|
|
84
88
|
testValue.is_a?(String) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not string", tellTales)
|
85
89
|
end
|
86
90
|
|
91
|
+
def potrubi_bootstrap_mustbe_symbol_or_croak(testValue, *tellTales)
|
92
|
+
testValue.is_a?(Symbol) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not symbol", tellTales)
|
93
|
+
end
|
94
|
+
|
95
|
+
def potrubi_bootstrap_mustbe_fixnum_or_croak(testValue, *tellTales)
|
96
|
+
testValue.is_a?(Fixnum) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not fixnum", tellTales)
|
97
|
+
end
|
98
|
+
|
99
|
+
def potrubi_bootstrap_mustbe_float_or_croak(testValue, *tellTales)
|
100
|
+
testValue.is_a?(Float) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not float", tellTales)
|
101
|
+
end
|
102
|
+
|
87
103
|
def potrubi_bootstrap_mustbe_file_or_croak(testValue, *tellTales)
|
88
|
-
File.file?(testValue) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not file", tellTales)
|
104
|
+
File.file?(testValue.to_s) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not file", tellTales)
|
89
105
|
end
|
90
106
|
|
91
107
|
def potrubi_bootstrap_mustbe_directory_or_croak(testValue, *tellTales)
|
92
|
-
File.directory?(testValue) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not directory", tellTales)
|
108
|
+
File.directory?(testValue.to_s) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "value not directory", tellTales)
|
93
109
|
end
|
94
110
|
|
95
111
|
def potrubi_bootstrap_mustbe_key_or_croak(testValue, keyName, *tellTales)
|
@@ -103,6 +119,10 @@ module Potrubi
|
|
103
119
|
def potrubi_bootstrap_mustbe_not_empty_or_croak(testValue, *tellTales)
|
104
120
|
(testValue.respond_to?(:empty?) && (! testValue.empty?)) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "testValue >#{testValue}< failed not empty", tellTales)
|
105
121
|
end
|
122
|
+
|
123
|
+
def potrubi_bootstrap_mustbe_empty_or_croak(testValue, *tellTales)
|
124
|
+
(testValue.respond_to?(:empty?) && testValue.empty?) ? testValue : potrubi_bootstrap_raise_exception(ArgumentError, testValue, "testValue >#{testValue}< failed empty", tellTales)
|
125
|
+
end
|
106
126
|
|
107
127
|
def bootstrap_find_module_constant(*a)
|
108
128
|
bootstrap_find_module_constant_or_croak(*a) rescue nil
|
@@ -124,3 +144,9 @@ module Potrubi
|
|
124
144
|
end
|
125
145
|
end
|
126
146
|
end
|
147
|
+
|
148
|
+
__END__
|
149
|
+
|
150
|
+
Potrubi::Mixin::BootstrapCommon.instance_methods.each {|m| puts("Potrubi::Mixin::BootstrapCommon Inst Mth >#{m}<")}
|
151
|
+
|
152
|
+
__END__
|
@@ -16,7 +16,6 @@ mixinContent = Module.new do
|
|
16
16
|
include Potrubi::Mixin::Persistence
|
17
17
|
|
18
18
|
# so common
|
19
|
-
|
20
19
|
def set_attributes_or_croak(attrArgsNom, &attrBlok)
|
21
20
|
eye = :'s_attrs'
|
22
21
|
mustbe_hash_or_croak(attrArgsNom, eye)
|
@@ -38,7 +37,6 @@ mixinContent = Module.new do
|
|
38
37
|
self
|
39
38
|
end
|
40
39
|
|
41
|
-
|
42
40
|
# If has key value is external source e.g. yaml
|
43
41
|
# read it and set_attributes with it
|
44
42
|
# Else raise exception unless blok is given
|
@@ -65,7 +63,6 @@ mixinContent = Module.new do
|
|
65
63
|
end
|
66
64
|
alias_method :set_attributes_from_configuration_files_or_croak, :set_attributes_from_configuration_sources_or_croak
|
67
65
|
|
68
|
-
|
69
66
|
def set_attributes_using_specification_or_croak(attrSpec, attrData, &attrBlok)
|
70
67
|
eye = :'s_attrs_using_spec'
|
71
68
|
|
@@ -73,6 +70,9 @@ mixinContent = Module.new do
|
|
73
70
|
|
74
71
|
mustbe_hash_or_croak(attrSpec, eye, "attrSpec failed contract")
|
75
72
|
mustbe_hash_or_croak(attrData, eye, "attrData failed contract")
|
73
|
+
|
74
|
+
attrSpec.each {|k,v| puts("#{eye} ATTR SPEC k >#{k}< v >#{v.class}< >#{v}<") }
|
75
|
+
attrData.each {|k,v| puts("\n\n\n#{eye} ATTR DATA k >#{k}< v >#{v.class}< >#{v}<") }
|
76
76
|
|
77
77
|
attrData.each do | attrName, attrValue |
|
78
78
|
|
@@ -99,6 +99,34 @@ mixinContent = Module.new do
|
|
99
99
|
self
|
100
100
|
|
101
101
|
end
|
102
|
+
|
103
|
+
def resolve_ruby_exe_path_or_croak(rubyArgs)
|
104
|
+
eye = :rsv_ruby_exe_path
|
105
|
+
|
106
|
+
mustbe_hash_or_croak(rubyArgs, eye)
|
107
|
+
|
108
|
+
rubyVersion = rubyArgs[:ruby] || :ruby # default is MRI
|
109
|
+
|
110
|
+
rubyPath = case rubyVersion
|
111
|
+
when String then rubyVersion
|
112
|
+
when Symbol
|
113
|
+
case rubyVersion
|
114
|
+
when :ruby then '/usr/bin/ruby'
|
115
|
+
when :jruby then '/usr/bin/jruby'
|
116
|
+
else
|
117
|
+
surprise_exception(rubyVersion, eye, "rubyVersion is what?")
|
118
|
+
end
|
119
|
+
else
|
120
|
+
surprise_exception(rubyVersion, eye, "rubyVersion is what?")
|
121
|
+
end
|
122
|
+
|
123
|
+
mustbe_file_or_croak(rubyPath, eye, "ruby path does not exist")
|
124
|
+
|
125
|
+
$DEBUG && logger_ca(eye, logger_fmt_kls(rubyPath: rubyPath, rubyVersion: rubyVersion))
|
126
|
+
|
127
|
+
rubyPath
|
128
|
+
|
129
|
+
end
|
102
130
|
|
103
131
|
end
|
104
132
|
|
@@ -4,12 +4,6 @@
|
|
4
4
|
require_relative '../bootstrap'
|
5
5
|
require_relative "dynamic"
|
6
6
|
|
7
|
-
#requireList = %w(dynamic)
|
8
|
-
#requireList.each {|r| require_relative "#{r}"}
|
9
|
-
|
10
|
-
#$DEBUG = true
|
11
|
-
#$DEBUG_POTRUBI_BOOTSTRAP = true
|
12
|
-
|
13
7
|
mixinContent = Module.new do
|
14
8
|
|
15
9
|
# mustbe contracts
|
@@ -21,11 +15,11 @@ mixinContent = Module.new do
|
|
21
15
|
|
22
16
|
mustbeMethods = {
|
23
17
|
:hash => [:package_mustbe, :method_mustbe_hash_with_proc, :method_mustbe_one_arg_or_nil_with_proc].flatten,
|
24
|
-
#=begin
|
25
18
|
:array => [:package_mustbe, :method_mustbe_array_with_proc, :method_mustbe_one_arg_or_nil_with_proc, :method_mustbe_subset].flatten,
|
26
19
|
:string => nil,
|
27
20
|
:symbol => nil,
|
28
21
|
:fixnum => nil,
|
22
|
+
:float => nil,
|
29
23
|
:range => nil,
|
30
24
|
:proc => nil,
|
31
25
|
:class => nil,
|
@@ -34,28 +28,28 @@ mixinContent = Module.new do
|
|
34
28
|
:enumerator => nil,
|
35
29
|
:regexp => nil,
|
36
30
|
:struct => nil,
|
31
|
+
:exception => nil,
|
37
32
|
:empty => [{:name => :'is_value_empty?', :spec => ->(c) {(c.respond_to?(:empty?) && c.empty?) ? c : nil }}, mustbeLimited1OneArgSpec].flatten,
|
38
33
|
:not_empty => [{:name => :'is_value_not_empty?', :spec => ->(c) {(c.respond_to?(:empty?) && (! c.empty?)) ? c : nil }}, mustbeLimited1OneArgSpec].flatten,
|
39
34
|
:not_nil => [{:name => :'is_value_not_nil?', :spec => ->(c) { c }}, mustbeLimited1OneArgSpec].flatten,
|
40
35
|
: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) {(
|
36
|
+
:directory => [{:name => :'is_value_directory?', :spec => ->(d) {(d.is_a?(String) && File.directory?(d)) ? d : nil}}, mustbeLimited2OneArgSpec].flatten,
|
42
37
|
: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
38
|
:key => [{:name => :'is_value_key?', :spec => ->(h,k) {(h.respond_to?(:has_key?) && h.has_key?(k)) ? h[k] : nil}}, mustbeLimited1TwoArgSpec].flatten,
|
44
39
|
:not_key => [{:name => :'is_value_not_key?', :spec => ->(h,k) {is_value_key?(h,k) ? nil : k}}, mustbeLimited1TwoArgSpec].flatten,
|
45
40
|
:any => [{:name => :'is_value_any?', :spec => ->(v) {v} }].flatten,
|
46
41
|
:same_class => [{:name => :'is_value_same_class?', :spec => ->(p,q) {((r = p.class) == q.class) ? r : nil}}, mustbeLimited1TwoArgSpec].flatten,
|
47
42
|
:instance_of => [{:name => :'is_value_instance_of?', :spec => ->(p,q) {p.instance_of?(q) ? p : nil}}, mustbeLimited1TwoArgSpec].flatten,
|
48
|
-
|
43
|
+
|
44
|
+
:is_a => [{:name => :'is_value_is_a?', :spec => ->(p,q) {p.is_a?(q) ? p : nil}}, mustbeLimited1TwoArgSpec].flatten,
|
49
45
|
}
|
50
46
|
|
51
47
|
mustbeSpecs = mustbeMethods.each_with_object({}) { | (mustbeName, mustbeSpec), h | h[mustbeName] = mustbeSpec || mustbeDefaultSpec }
|
52
48
|
|
53
49
|
Potrubi::Mixin::Dynamic::dynamic_define_methods(self, mustbeSpecs) do |k, v|
|
54
50
|
edits = {
|
55
|
-
###:MUSTBE_TEST => k.to_s.capitalize,
|
56
51
|
IS_VALUE_TEST: "testValue.is_a?(#{k.to_s.capitalize})",
|
57
52
|
MUSTBE_NAME: k,
|
58
|
-
###MUSTBE_SPEC: v,
|
59
53
|
}
|
60
54
|
case v
|
61
55
|
when Hash then v.merge({:edit => [edits, v[:edit]]})
|
@@ -63,10 +57,8 @@ mixinContent = Module.new do
|
|
63
57
|
{:edit => edits, :spec => v}
|
64
58
|
end
|
65
59
|
end
|
66
|
-
|
67
60
|
|
68
61
|
# Compare Contracts
|
69
|
-
|
70
62
|
compareMethods = {
|
71
63
|
:eq => '==',
|
72
64
|
:equal => '==',
|
@@ -87,7 +79,6 @@ mixinContent = Module.new do
|
|
87
79
|
}
|
88
80
|
|
89
81
|
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
82
|
{edit: {MUSTBE_NAME: mN, MUSTBE_SPEC: mO}, spec: :method_mustbe_compare}
|
92
83
|
end
|
93
84
|
|
@@ -0,0 +1,307 @@
|
|
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(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, MUSTBE_NAME: k, MUSTBE_SPEC: k, MUSTBE_KEY_NAME: k}
|
22
|
+
end
|
23
|
+
|
24
|
+
def standard_mustbe_edit(k, v)
|
25
|
+
{MUSTBE_NAME: k, MUSTBE_SPEC: k, MUSTBE_KEY_NAME: k}
|
26
|
+
end
|
27
|
+
|
28
|
+
def keyname_mustbe_edit(k, v, n)
|
29
|
+
{MUSTBE_NAME: k, MUSTBE_SPEC: k, MUSTBE_KEY_NAME: n}
|
30
|
+
end
|
31
|
+
|
32
|
+
# convenience methods
|
33
|
+
|
34
|
+
def merge_edits(*edits)
|
35
|
+
Potrubi::Mixin::Dynamic.dynamic_merge_edits(*edits)
|
36
|
+
end
|
37
|
+
|
38
|
+
def merge_specs(*specs)
|
39
|
+
specs.flatten.compact
|
40
|
+
end
|
41
|
+
|
42
|
+
def merge_spec_and_edit(spec, edit)
|
43
|
+
{edit: edit, spec: spec}
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def standard_syntax_value_test(v, t='testValue')
|
48
|
+
eye = :'standard_syntax_value_test'
|
49
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, 'PRE', 'VALUE', 'TEST', potrubi_bootstrap_logger_fmt_who(v: v, t: t))
|
50
|
+
r = case v
|
51
|
+
when Symbol then "is_value_#{v}?(#{t})"
|
52
|
+
when Class, String then "#{t}.is_a?(#{v})"
|
53
|
+
when NilClass then "#{t}"
|
54
|
+
when Proc then value.call
|
55
|
+
else
|
56
|
+
potrubi_bootstrap_surprise_exception(v, eye, "v >#{v}< spec not expected")
|
57
|
+
end
|
58
|
+
|
59
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, 'POST', 'VALUE', 'TEST', potrubi_bootstrap_logger_fmt_who(v: v, r: r))
|
60
|
+
|
61
|
+
r
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# This method is peculiar to accessors & mustbes
|
67
|
+
# not general purpose as e.g. hash treatment makes assumptions
|
68
|
+
|
69
|
+
def standard_case_statement(k, v, s, edit, spec)
|
70
|
+
eye = :'rcp_std_case'
|
71
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(k: k, v: v, edit: edit))
|
72
|
+
r = case v
|
73
|
+
##when Symbol then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: "testValue.is_a?(#{v.to_s.capitalize})"}))
|
74
|
+
when Symbol then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: "is_value_#{v}?(testValue)"}))
|
75
|
+
when Class, String then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: "testValue.is_a?(#{v})"}))
|
76
|
+
when NilClass then merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: 'testValue'}))
|
77
|
+
when Array then v # dynamic_define_methods will parse
|
78
|
+
when Proc then
|
79
|
+
[ merge_spec_and_edit(spec, merge_edits(edit, {IS_VALUE_TEST: 'false'})), # error on default isValueText
|
80
|
+
{name: "is_value_#{k}?", spec: v}, # ... but override is_value method
|
81
|
+
]
|
82
|
+
when Hash then v.merge(merge_spec_and_edit(merge_specs([spec, v[:spec]]), merge_edits(edit, {IS_VALUE_TEST: 'false'}, v[:edit])))
|
83
|
+
else
|
84
|
+
potrubi_bootstrap_surprise_exception(v, eye, "accessor name >#{k}< spec not expected")
|
85
|
+
end
|
86
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(k: k, v: v, edit: edit), potrubi_bootstrap_logger_fmt_who(spec: spec), potrubi_bootstrap_logger_fmt_who(RRRRRRRRRRRRRRRRRRRRRRRRRr: r))
|
87
|
+
r
|
88
|
+
end
|
89
|
+
|
90
|
+
def standard_accessor_recipe_block(s) # returns a lambda
|
91
|
+
->(k, v) do
|
92
|
+
edit = standard_accessor_edit(k, v)
|
93
|
+
spec = s
|
94
|
+
r = standard_case_statement(k, v, s, edit, spec)
|
95
|
+
r
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def standard_derived_edits_assign(s, srcKey, tgtKey, tgtText)
|
100
|
+
eye = :'standard_derived_edits_assign'
|
101
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(srcKey: srcKey, tgtKey: tgtKey, tgtText: tgtText, s: s))
|
102
|
+
# does the target key already exist?
|
103
|
+
potrubi_bootstrap_mustbe_hash_or_croak(s)
|
104
|
+
r = if s.has_key?(tgtKey) then
|
105
|
+
# yes; nothing to do
|
106
|
+
s
|
107
|
+
else
|
108
|
+
# no; does the source key exist?. if use use to set target key
|
109
|
+
if s.has_key?(srcKey) then
|
110
|
+
s[tgtKey] = standard_syntax_value_test(s[srcKey], tgtText)
|
111
|
+
s
|
112
|
+
else
|
113
|
+
s
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(srcKey: srcKey, tgtKey: tgtKey, r: r))
|
118
|
+
potrubi_bootstrap_mustbe_hash_or_croak(r, eye, 'POST', 'EDITS', 'ASSIGN')
|
119
|
+
#r
|
120
|
+
end
|
121
|
+
|
122
|
+
def standard_derived_edits(edits={})
|
123
|
+
eye = :'standard_derived_edits'
|
124
|
+
|
125
|
+
derivedMap =
|
126
|
+
{
|
127
|
+
IS_COLLECTION_VALUE_TEST: {key: :VALUE_TYPE, target: 'v'},
|
128
|
+
IS_COLLECTION_KEY_TEST: {key: :KEY_TYPE, target: 'k'},
|
129
|
+
}
|
130
|
+
|
131
|
+
editsDerived =
|
132
|
+
if edits then
|
133
|
+
potrubi_bootstrap_mustbe_hash_or_croak(edits)
|
134
|
+
derivedMap.reduce(edits) do | s, (tgtKey, srcSpec) |
|
135
|
+
srcKey = srcSpec[:key]
|
136
|
+
tgtText = srcSpec[:target]
|
137
|
+
standard_derived_edits_assign(s, srcKey, tgtKey, tgtText)
|
138
|
+
end
|
139
|
+
else
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
|
143
|
+
editsDerived && potrubi_bootstrap_mustbe_hash_or_croak(editsDerived)
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
def standard_mustbe_recipe_block(s) # returns a lambda
|
148
|
+
->(k, v) {
|
149
|
+
|
150
|
+
spec = s
|
151
|
+
|
152
|
+
r = case v
|
153
|
+
when Hash then
|
154
|
+
|
155
|
+
o = v[:other] || {}
|
156
|
+
|
157
|
+
# any key name?
|
158
|
+
key_name = o[:key_name]
|
159
|
+
|
160
|
+
eKeyName = keyname_mustbe_edit(k, v, key_name || k)
|
161
|
+
|
162
|
+
eDerived = standard_derived_edits(v[:edit])
|
163
|
+
|
164
|
+
e = merge_edits(eKeyName, eDerived)
|
165
|
+
|
166
|
+
# any type?
|
167
|
+
t = o[:type]
|
168
|
+
|
169
|
+
r = standard_case_statement(k, t || v, s, e, spec)
|
170
|
+
|
171
|
+
|
172
|
+
else
|
173
|
+
e = keyname_mustbe_edit(k, v, k)
|
174
|
+
###spec = {spec: s}
|
175
|
+
|
176
|
+
r = standard_case_statement(k, v, s, e, spec)
|
177
|
+
end
|
178
|
+
|
179
|
+
r
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
def resolve_recipe_texts(*recipeTexts)
|
184
|
+
recipeTexts.flatten
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
def recipe_accessors(attrTarget, attrDefs, *attrTexts, &attrBlok)
|
189
|
+
eye = :'rcp_accessors'
|
190
|
+
|
191
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
192
|
+
|
193
|
+
textDefs = resolve_recipe_texts(attrTexts.empty? ? :package_accessor_with_contract : attrTexts) # default is contract accessor
|
194
|
+
|
195
|
+
procBlok = Kernel.block_given? ? attrBlok : standard_accessor_recipe_block(textDefs)
|
196
|
+
|
197
|
+
Potrubi::Mixin::Dynamic.dynamic_define_methods(attrTarget, attrDefs, &procBlok)
|
198
|
+
|
199
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
200
|
+
|
201
|
+
self
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
def recipe_mustbes(attrTarget, attrDefs, *attrTexts, &attrBlok)
|
206
|
+
eye = :'rcp_mustbes'
|
207
|
+
|
208
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
209
|
+
|
210
|
+
textDefs = resolve_recipe_texts(attrTexts.empty? ? :package_mustbe : attrTexts) # default is standard mustbe
|
211
|
+
|
212
|
+
procBlok = Kernel.block_given? ? attrBlok : standard_mustbe_recipe_block(textDefs)
|
213
|
+
|
214
|
+
Potrubi::Mixin::Dynamic.dynamic_define_methods(attrTarget, attrDefs, &procBlok)
|
215
|
+
|
216
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
217
|
+
|
218
|
+
self
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
def recipe_variant_accessor(attrTarget, attrDefs, *attrTexts, &attrBlok)
|
225
|
+
eye = :'rcp_var_acc'
|
226
|
+
|
227
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
228
|
+
|
229
|
+
textDefs = resolve_recipe_texts(attrTexts)
|
230
|
+
|
231
|
+
procBlok = Kernel.block_given? ? attrBlok : standard_accessor_recipe_block(textDefs)
|
232
|
+
|
233
|
+
Potrubi::Mixin::Dynamic.dynamic_define_methods(attrTarget, attrDefs, &procBlok)
|
234
|
+
|
235
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
236
|
+
|
237
|
+
self
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
def recipe_variant_mustbe(attrTarget, attrDefs, *attrTexts, &attrBlok)
|
244
|
+
eye = :'rcp_var_mustbe'
|
245
|
+
|
246
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_me(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
247
|
+
|
248
|
+
textDefs = resolve_recipe_texts(attrTexts.compact.empty? ? :package_mustbe : attrTexts) # default is contract accessor
|
249
|
+
|
250
|
+
procBlok = Kernel.block_given? ? attrBlok : standard_mustbe_recipe_block(textDefs)
|
251
|
+
|
252
|
+
Potrubi::Mixin::Dynamic.dynamic_define_methods(attrTarget, attrDefs, &procBlok)
|
253
|
+
|
254
|
+
$DEBUG_POTRUBI_BOOTSTRAP && potrubi_bootstrap_logger_mx(eye, potrubi_bootstrap_logger_fmt_who(attrTarget: attrTarget, attrDefs: attrDefs, attrTexts: attrTexts))
|
255
|
+
|
256
|
+
self
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
end
|
262
|
+
|
263
|
+
module Potrubi
|
264
|
+
module Mixin
|
265
|
+
module Contract
|
266
|
+
module Recipes
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
Potrubi::Mixin::Contract::Recipes.extend(mixinContent) # Make mixin methods
|
273
|
+
|
274
|
+
__END__
|
275
|
+
|
276
|
+
# quick tests
|
277
|
+
|
278
|
+
$LOAD_PATH.unshift('../../../.') # ensure get code not gem
|
279
|
+
|
280
|
+
$LOAD_PATH.each {|p| puts("LOAD PATH >#{p}<")}
|
281
|
+
#STOPHERELOADPATH
|
282
|
+
require '../../core'
|
283
|
+
require "potrubi/klass/syntax/braket"
|
284
|
+
|
285
|
+
$DEBUG = true
|
286
|
+
$DEBUG_POTRUBI_BOOTSTRAP = true
|
287
|
+
|
288
|
+
testClass2 = Class.new do
|
289
|
+
|
290
|
+
Potrubi::Mixin::Contract::Recipes.recipe_dsl(self) do
|
291
|
+
|
292
|
+
#accessor :x1, default: 10
|
293
|
+
#accessor :x2, default: 'default-for-x2'
|
294
|
+
#accessor :x3, default: :x3_def_is_a_symbol
|
295
|
+
|
296
|
+
# accessor :riemann_host, :string
|
297
|
+
accessor :riemann_port, type: :fixnum, default: 5555
|
298
|
+
#accessor :riemann_interval, type: :fixnum, default: 10
|
299
|
+
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
__END__
|
307
|
+
|