safestruct 1.2.0 → 1.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 04e5c95875cd6c4fbdd2865525ed7853d5c549e3
4
- data.tar.gz: c2f2eab9840be5183219caec2132c08b5a6d9297
3
+ metadata.gz: f085259a240f99941fe60eef6a271a6066e649d3
4
+ data.tar.gz: a289d416c0ade1aa76eae8e0c897fac7b63e6700
5
5
  SHA512:
6
- metadata.gz: 552e6f386d52b6b4bbd312b2c80f9f09073eb187fbb899e0de0d4e0070477da7e8f9bd520bc56c0bdee6fef8462af634c42045ebc87d8c307ff5cd1c4b0003d3
7
- data.tar.gz: 82725de07669291702ce15b805f24073abe8dce0131f89d98e346c9e19f309d60e1b083c58a04e455a1c950f2674602b8c3e06a1c505463ac9ca68eb7e952bcb
6
+ metadata.gz: 7a71c903f7ecddfe2a42c48465f7a76969db5566e7d0cdf18bf53878f5bad067c7b7e86029a1516e5515124547a6ce5a2c9badc36f84e1a1ca05cb6fcd049e65
7
+ data.tar.gz: aade5b05f5666e89204cd5b95a4561829d7f70bae9380a7d204013527bdd03e21757c9f30f379c74f5ced2b558e25b702ccf1cbcaa13cd2d4e9df71c833688fb
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require './lib/safestruct/version.rb'
3
3
 
4
4
  Hoe.spec 'safestruct' do
5
5
 
6
- self.version = Safe::VERSION
6
+ self.version = SaferStruct::VERSION
7
7
 
8
8
  self.summary = "safestruct - safe data structures (array, hash, struct) - say goodbye to null / nil (and maybe) - say hello to zero"
9
9
  self.description = summary
@@ -19,19 +19,31 @@ require 'safestruct/safe_struct'
19
19
  ####################################
20
20
  ## add zero/zero_new machinery for builin classes
21
21
 
22
- #### value semantics
22
+ #########################
23
+ #### with value semantics
23
24
  class Integer
24
25
  def self.zero() 0; end ## note: 0.frozen? == true by default
26
+ def zero?() self == self.class.zero; end
25
27
  end
26
28
 
27
29
  class Bool
28
30
  def self.zero() false; end ## note: false.frozen? == true by default
29
31
  end
30
32
 
31
- #### reference semantics (new copy ALWAYS needed)
33
+ class TrueClass # note: ruby has no builtin/default bool (base) class only TrueClass|FalseClass
34
+ def zero?() false; end
35
+ end
36
+
37
+ class FalseClass
38
+ def zero?() true; end
39
+ end
40
+
41
+ ##################
42
+ #### with reference semantics (new copy ALWAYS needed)
32
43
  class String
33
44
  def self.new_zero() new; end
34
45
  def self.zero() @zero ||= new_zero.freeze; end
46
+ def zero?() self == self.class.zero; end
35
47
  end
36
48
 
37
49
 
@@ -90,9 +102,14 @@ module Safe
90
102
  def struct( class_name, **attributes )
91
103
  SafeStruct.new( class_name, attributes )
92
104
  end
105
+
106
+ ### note: do NOT add helpers for
107
+ ## - hash( class_name, ...) and
108
+ ## - array( class_name, ...) for now
109
+ ## why? why not? needs more testing/considerations for overloading / breaking builtin defaults
93
110
  end # module ClassMethods
94
111
  end # module Safe
95
112
 
96
113
 
97
114
 
98
- puts Safe.banner ## say hello
115
+ puts SaferStruct.banner ## say hello
@@ -18,14 +18,23 @@ class SafeArray
18
18
  if klass.nil?
19
19
 
20
20
  klass = Class.new( SafeArray )
21
- klass.class_eval( <<RUBY )
22
- def self.klass_value
23
- @klass_value ||= #{klass_value}
24
- end
25
- def self.klass_size
26
- @klass_size ||= #{size}
27
- end
28
- RUBY
21
+ klass.define_singleton_method( :klass_value ) do
22
+ @klass_value ||= klass_value
23
+ end
24
+ klass.define_singleton_method( :klass_size ) do
25
+ @klass_size ||= size
26
+ end
27
+
28
+ ##### was: not working for anymous class e.g. klass_value.to_s => #<Class:>
29
+ # klass.class_eval( <<RUBY )
30
+ # def self.klass_value
31
+ # @klass_value ||= #{klass_value}
32
+ # end
33
+ # def self.klass_size
34
+ # @klass_size ||= #{size}
35
+ # end
36
+ # RUBY
37
+
29
38
  ## add to cache for later (re)use
30
39
  cache[ klass_value ][ size ] = klass
31
40
  end
@@ -36,6 +45,8 @@ RUBY
36
45
  def self.new_zero() new; end
37
46
  def self.zero() @zero ||= new_zero.freeze; end
38
47
 
48
+ def zero?() self == self.class.zero; end
49
+
39
50
 
40
51
  def initialize( size=self.class.klass_size )
41
52
  @ary = []
@@ -71,11 +82,11 @@ RUBY
71
82
  ## note: use a new unfrozen copy of the zero object
72
83
  ## changes to the object MUST be possible (new "empty" modifable object expected)
73
84
  diff.times { @ary << self.class.klass_value.new_zero }
74
- else # assume value semantics e.g. Integer, Bool, etc. zero values gets replaced
85
+ else # assume value semantics e.g. Integer, Bool, etc. zero values gets replaced
75
86
  ## puts "use value semantics"
76
87
  diff.times { @ary << self.class.klass_value.zero }
77
- end
78
- self # return reference to self
88
+ end
89
+ self # return reference to self
79
90
  end
80
91
  alias_method :'length=', :'size='
81
92
 
@@ -26,6 +26,7 @@ class SafeHash
26
26
  if debug?
27
27
  puts "[debug] SafeHash - build_class klass_value:"
28
28
  pp klass_value
29
+ pp klass_value.to_s ## note: for "anonymous" class something like #<Class:>
29
30
  end
30
31
 
31
32
  if klass.nil?
@@ -34,14 +35,24 @@ class SafeHash
34
35
  end
35
36
 
36
37
  klass = Class.new( SafeHash )
37
- klass.class_eval( <<RUBY )
38
- def self.klass_key
39
- @klass_key ||= #{klass_key}
40
- end
41
- def self.klass_value
42
- @klass_value ||= #{klass_value}
43
- end
44
- RUBY
38
+
39
+ klass.define_singleton_method( :klass_key ) do
40
+ @klass_key ||= klass_key
41
+ end
42
+ klass.define_singleton_method( :klass_value ) do
43
+ @klass_value ||= klass_value
44
+ end
45
+
46
+ ### was: - NOT working for "anonymous" classes e.g. klass_value.to_s starting with #<Class:>
47
+ # klass.class_eval( <<RUBY )
48
+ # def self.klass_key
49
+ # @klass_key ||= #{klass_key}
50
+ # end
51
+ # def self.klass_value
52
+ # @klass_value ||= #{klass_value}
53
+ # end
54
+ # RUBY
55
+
45
56
  ## add to cache for later (re)use
46
57
  cache[ klass_value ] = klass
47
58
  else
@@ -58,6 +69,8 @@ RUBY
58
69
  def self.new_zero() new; end
59
70
  def self.zero() @zero ||= new_zero.freeze; end
60
71
 
72
+ def zero?() self == self.class.zero; end
73
+
61
74
 
62
75
  def initialize
63
76
  ## todo/check: if hash works if value is a (nested) hash
@@ -100,11 +113,11 @@ RUBY
100
113
  if self.class.klass_value.respond_to?( :new_zero )
101
114
  ## note: use a dup(licated) unfrozen copy of the zero object
102
115
  ## changes to the object MUST be possible (new "empty" modifable object expected)
103
- item = @h[ key ] = self.class.klass_value.new_zero
104
- else # assume value semantics e.g. Integer, Bool, etc. zero values gets replaced
105
- ## puts "use value semantics"
106
- item = @h[ key ] = self.class.klass_value.zero
107
- end
116
+ item = @h[ key ] = self.class.klass_value.new_zero
117
+ else # assume value semantics e.g. Integer, Bool, etc. zero values gets replaced
118
+ ## puts "use value semantics"
119
+ item = @h[ key ] = self.class.klass_value.zero
120
+ end
108
121
  end
109
122
  item
110
123
  end
@@ -21,7 +21,7 @@ def self.build_class( class_name, **attributes )
21
21
  ## check if valid class_name MUST start with uppercase letter etc.
22
22
  ## todo/fix: check if constant is undefined in Safe namespace!!!!
23
23
 
24
-
24
+
25
25
  klass = Class.new( SafeStruct ) do
26
26
  define_method( :initialize ) do |*args|
27
27
  attributes.keys.zip( args ).each do |key, arg|
@@ -100,13 +100,13 @@ def self.build_class( class_name, **attributes )
100
100
  end
101
101
 
102
102
 
103
- ## note: use Object for "namespacing"
103
+ ## note: use Kernel for "namespacing"
104
104
  ## make all enums convenience converters (always) global
105
105
  ## including uppercase methods (e.g. State(), Color(), etc.) does NOT work otherwise (with other module includes)
106
106
 
107
- ## add global convenience converter function
107
+ ## add global "Kernel" convenience converter function
108
108
  ## e.g. Vote(0) is same as Vote.convert(0)
109
- Object.class_eval( <<RUBY )
109
+ Kernel.class_eval( <<RUBY )
110
110
  def #{class_name}( arg )
111
111
  #{class_name}.convert( arg )
112
112
  end
@@ -130,5 +130,9 @@ def self.zero
130
130
  ## freeze only works for now for "value" objects e.g. integer, bool, etc.
131
131
  @zero ||= new_zero.freeze
132
132
  end
133
+
134
+ def zero?() self == self.class.zero; end
135
+
136
+
133
137
  end # class SafeStruct
134
138
  end # module Safe
@@ -1,11 +1,18 @@
1
1
  # encoding: utf-8
2
2
 
3
3
 
4
- module Safe
4
+ ###
5
+ # note: do not "pollute" Safe namespace / module
6
+ # use its own module
7
+ #
8
+ # note: SafeStruct is already taken :-), thus, use SaferStruct
9
+
10
+
11
+ module SaferStruct
5
12
 
6
13
  MAJOR = 1
7
14
  MINOR = 2
8
- PATCH = 0
15
+ PATCH = 1
9
16
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
17
 
11
18
  def self.version
@@ -20,4 +27,4 @@ module Safe
20
27
  "#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
21
28
  end
22
29
 
23
- end # module Safe
30
+ end # module SaferStruct
@@ -23,6 +23,20 @@ class TestHash < MiniTest::Test
23
23
  ## nested e.g. String => (String => Integer)
24
24
  Hash_Hash_X_Integer = SafeHash.build_class( String, Hash_X_Integer )
25
25
 
26
+ SafeStruct.new( :Game123, host: '',
27
+ challenger: '',
28
+ turn: '')
29
+
30
+ def test_hash_of_hash
31
+ ## note: use Game123 (with unique/unused name)
32
+ ## for testing an "anonymous" hash class (e.g. without a class name)
33
+ h = Hash.of( String => Hash.of( String => Game123 ))
34
+ pp h
35
+ h2 = Hash.of( String => Hash.of( String => Game123 ))
36
+ pp h2
37
+ assert true
38
+ end
39
+
26
40
 
27
41
  def test_integer
28
42
  pp Hash_X_Integer
@@ -39,6 +53,11 @@ def test_integer
39
53
  assert_equal true, Hash_X_Integer.zero == Hash_X_Integer.new
40
54
  assert_equal true, Hash_X_Integer.zero == Hash_X_Integer.new_zero
41
55
 
56
+ assert_equal true, h.zero?
57
+ assert_equal true, Hash_X_Integer.zero.zero?
58
+ assert_equal true, Hash_X_Integer.new.zero?
59
+ assert_equal true, Hash_X_Integer.new_zero.zero?
60
+
42
61
  pp Hash_X_Integer.zero
43
62
  assert_equal true, Hash_X_Integer.zero.frozen?
44
63
  assert_equal false, Hash_X_Integer.new.frozen?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safestruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-07 00:00:00.000000000 Z
11
+ date: 2019-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: enums