safestruct 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
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