striuct 0.3.1 → 0.3.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.
Files changed (53) hide show
  1. data/.gitignore +2 -0
  2. data/.yardopts +1 -0
  3. data/History.rdoc +6 -0
  4. data/Manifest.txt +38 -17
  5. data/README.md +6 -4
  6. data/{benchmarks → benchmark}/basics.rb +0 -0
  7. data/{examples → example}/README.rb +0 -0
  8. data/{examples → example}/example.old.rdoc +0 -0
  9. data/{examples → example}/example1.rb +0 -0
  10. data/{examples → example}/example2.rb +0 -0
  11. data/{examples → example}/see_trace.rb +0 -0
  12. data/lib/striuct/classmethods/adjustment.rb +31 -0
  13. data/lib/striuct/classmethods/constructor.rb +8 -8
  14. data/lib/striuct/classmethods/default.rb +28 -0
  15. data/lib/striuct/classmethods/enum.rb +49 -0
  16. data/lib/striuct/classmethods/inner.rb +25 -108
  17. data/lib/striuct/classmethods/length.rb +14 -0
  18. data/lib/striuct/classmethods/macro.rb +38 -41
  19. data/lib/striuct/classmethods/named.rb +94 -0
  20. data/lib/striuct/classmethods/object.rb +24 -0
  21. data/lib/striuct/classmethods/prevent_conflicts.rb +89 -0
  22. data/lib/striuct/classmethods/requiremnets.rb +9 -4
  23. data/lib/striuct/classmethods/to_struct.rb +26 -0
  24. data/lib/striuct/classmethods/validation.rb +56 -0
  25. data/lib/striuct/instancemethods/assign.rb +31 -0
  26. data/lib/striuct/instancemethods/compare.rb +31 -0
  27. data/lib/striuct/instancemethods/default.rb +14 -0
  28. data/lib/striuct/instancemethods/delegate_class_methods.rb +20 -0
  29. data/lib/striuct/instancemethods/enum.rb +104 -0
  30. data/lib/striuct/instancemethods/{hashlike.rb → hashy.rb} +39 -45
  31. data/lib/striuct/instancemethods/inner.rb +16 -77
  32. data/lib/striuct/instancemethods/lock.rb +51 -0
  33. data/lib/striuct/instancemethods/object.rb +47 -0
  34. data/lib/striuct/instancemethods/requirements.rb +12 -3
  35. data/lib/striuct/instancemethods/safety.rb +2 -66
  36. data/lib/striuct/instancemethods/singleton_class.rb +4 -1
  37. data/lib/striuct/instancemethods/subscript.rb +55 -0
  38. data/lib/striuct/instancemethods/to_struct.rb +12 -0
  39. data/lib/striuct/instancemethods/validation.rb +25 -0
  40. data/lib/striuct/instancemethods/values.rb +64 -0
  41. data/lib/striuct/singleton_class.rb +10 -10
  42. data/lib/striuct/specificcontainer.rb +3 -1
  43. data/lib/striuct/version.rb +1 -1
  44. data/striuct.gemspec +1 -1
  45. data/test/test_striuct_subclass_alias_member.rb +3 -3
  46. data/test/test_striuct_subclass_for_pairs.rb +8 -1
  47. metadata +32 -17
  48. data/lib/striuct/classmethods/basic.rb +0 -54
  49. data/lib/striuct/classmethods/constants.rb +0 -23
  50. data/lib/striuct/classmethods/handy.rb +0 -124
  51. data/lib/striuct/classmethods/safety.rb +0 -52
  52. data/lib/striuct/instancemethods/basic.rb +0 -135
  53. data/lib/striuct/instancemethods/handy.rb +0 -91
@@ -1,23 +1,14 @@
1
1
  class Striuct; module InstanceMethods
2
2
 
3
- private
4
-
5
3
  # @group Use Only Inner
6
-
7
- # see self.class.*args
8
- delegate_class_methods(
9
- :keyable_for, :flavor_for, :condition_for, :autonym_for
10
- )
11
-
12
- def initialize_copy(original)
13
- @db, @locks = @db.dup, {}
14
- end
4
+
5
+ private
15
6
 
16
7
  def __get__(name)
17
- name = autonym_for name
18
- value = @db[name]
8
+ autonym = autonym_for name
9
+ value = @db[autonym]
19
10
 
20
- if safety_getter?(name) and !accept?(name, value)
11
+ if safety_getter?(autonym) and !accept?(autonym, value)
21
12
  raise ::Validation::InvalidReadingError,
22
13
  "#{value.inspect} is deficient for #{name} in #{self.class}"
23
14
  end
@@ -27,27 +18,27 @@ class Striuct; module InstanceMethods
27
18
 
28
19
  def __set__(name, value)
29
20
  raise "can't modify frozen #{self.class}" if frozen?
30
- name = autonym_for name
31
- raise "can't modify locked member #{name}" if lock? name
21
+ autonym = autonym_for name
22
+ raise "can't modify locked member #{name}" if lock? autonym
32
23
 
33
- if has_flavor? name
24
+ if has_adjuster? autonym
34
25
  begin
35
- value = instance_exec value, &flavor_for(name)
26
+ value = instance_exec value, &adjuster_for(autonym)
36
27
  rescue Exception
37
28
  raise ::Validation::UnmanagebleError
38
29
  end
39
30
  end
40
31
 
41
- if safety_setter?(name) and !accept?(name, value)
32
+ if safety_setter?(autonym) and !accept?(autonym, value)
42
33
  raise ::Validation::InvalidWritingError,
43
34
  "#{value.inspect} is deficient for #{name} in #{self.class}"
44
35
  end
45
36
 
46
- if inference? name
47
- self.class.__send__ :__found_family__!, self, name, value
37
+ if inference? autonym
38
+ self.class.__send__ :__found_family__!, self, autonym, value
48
39
  end
49
40
 
50
- @db[name] = value
41
+ @db[autonym] = value
51
42
  rescue ::Validation::InvalidError
52
43
  unless /in \[\]=/ =~ caller[1].slice(/([^:]+)\z/)
53
44
  $!.backtrace.delete_if{|s|/#{Regexp.escape(File.dirname __FILE__)}/ =~ s}
@@ -57,65 +48,13 @@ class Striuct; module InstanceMethods
57
48
  raise
58
49
  end
59
50
 
60
- def __subscript__(key)
61
- case key
62
- when Symbol, String
63
- name = keyable_for key
64
- if member? name
65
- yield autonym_for(name)
66
- else
67
- raise NameError
68
- end
69
- when Fixnum
70
- if name = members[key]
71
- yield name
72
- else
73
- raise IndexError
74
- end
75
- else
76
- raise ArgumentError
77
- end
78
- end
79
-
80
- # @param [Symbol] name
81
- def __clear__(name)
51
+ # @param [Symbol] autonym
52
+ def __clear__(autonym)
82
53
  raise "can't modify frozen #{self.class}" if frozen?
83
54
 
84
- @db.delete name
85
- end
86
-
87
- def replace_values(*values)
88
- unless values.size <= size
89
- raise ArgumentError, "struct size differs (max: #{size})"
90
- end
91
-
92
- values.each_with_index do |value, index|
93
- self[index] = value
94
- end
95
-
96
- excess = members.last(size - values.size)
97
-
98
- excess.each do |name|
99
- if has_default? name
100
- self[name] = (
101
- if (value = default_for name).kind_of? SpecificContainer
102
- block = value.value
103
- args = [self, name][0, block.arity]
104
- block.call(*args)
105
- else
106
- value
107
- end
108
- )
109
- end
110
- end
55
+ @db.delete autonym
111
56
  end
112
57
 
113
- # @param [Symbol] method
114
- def __compare_all__(other, method)
115
- instance_of?(other.class) && \
116
- each_pair.all?{|k, v|v.__send__ method, other[k]}
117
- end
118
-
119
58
  # @endgroup
120
59
 
121
60
  end; end
@@ -0,0 +1,51 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Lock
4
+
5
+ # @overload lock(key)
6
+ # lock a setter for key
7
+ # @param [Symbol, String, Fixnum] key
8
+ # @overload lock(true)
9
+ # lock setters for all members
10
+ # @param [true] true
11
+ # @return [self]
12
+ def lock(key=true)
13
+ raise "can't modify frozen #{self.class}" if frozen?
14
+
15
+ if key.equal? true
16
+ autonyms.each do |autonym|
17
+ @locks[autonym] = true
18
+ end
19
+ else
20
+ __subscript__(key){|autonym|@locks[autonym] = true}
21
+ end
22
+
23
+ self
24
+ end
25
+
26
+ # @see #lock
27
+ def lock?(key=true)
28
+ if key.equal? true
29
+ autonyms.all?{|autonym|@locks[autonym]}
30
+ else
31
+ __subscript__(key){|autonym|@locks[autonym]} || false
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def unlock(key=true)
38
+ raise "can't modify frozen #{self.class}" if frozen?
39
+
40
+ if key.equal? true
41
+ @locks.clear
42
+ else
43
+ __subscript__(key){|autonym|@locks.delete autonym}
44
+ end
45
+
46
+ self
47
+ end
48
+
49
+ # @endgroup
50
+
51
+ end; end
@@ -0,0 +1,47 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Basic Methods for Ruby's Object
4
+
5
+ def initialize(*values)
6
+ @db, @locks = {}, {}
7
+ replace_values(*values)
8
+ end
9
+
10
+ # @return [String]
11
+ def inspect
12
+ "#<#{self.class} (Striuct)".tap {|s|
13
+ each_pair do |autonym, value|
14
+ suffix = (has_default?(autonym) && default?(autonym)) ? '(default)' : nil
15
+ s << " #{autonym}=#{value.inspect}#{suffix}"
16
+ end
17
+
18
+ s << ">"
19
+ }
20
+ end
21
+
22
+ # @return [String]
23
+ def to_s
24
+ "#<struct #{self.class}".tap {|s|
25
+ each_pair do |autonym, value|
26
+ s << " #{autonym}=#{value.inspect}"
27
+ end
28
+
29
+ s << '>'
30
+ }
31
+ end
32
+
33
+ # @return [self]
34
+ def freeze
35
+ [@db, @locks].each(&:freeze)
36
+ super
37
+ end
38
+
39
+ private
40
+
41
+ def initialize_copy(original)
42
+ @db, @locks = @db.dup, {}
43
+ end
44
+
45
+ # @endgroup
46
+
47
+ end; end
@@ -1,6 +1,15 @@
1
1
  require_relative 'singleton_class'
2
+ require_relative 'delegate_class_methods'
2
3
  require_relative 'inner'
3
- require_relative 'basic'
4
- require_relative 'handy'
5
- require_relative 'hashlike'
4
+ require_relative 'object'
5
+ require_relative 'compare'
6
+ require_relative 'values'
7
+ require_relative 'to_struct'
8
+ require_relative 'default'
9
+ require_relative 'enum'
10
+ require_relative 'hashy'
11
+ require_relative 'subscript'
12
+ require_relative 'assign'
13
+ require_relative 'lock'
14
+ require_relative 'validation'
6
15
  require_relative 'safety'
@@ -1,76 +1,12 @@
1
1
  class Striuct; module InstanceMethods
2
- # @group Struct+ Safety
3
-
4
- # see self.class.*args
5
- delegate_class_methods :restrict?, :has_condition?,
6
- :safety_getter?, :safety_reader?, :safety_setter?, :safty_writer?, :inference?
7
-
8
- # @param [Symbol, String] name
9
- # @param [Object] value - no argument and use own
10
- # passed under any condition
11
- def sufficient?(name, value=self[name])
12
- name = autonym_for name
13
- return true unless restrict? name
14
-
15
- _valid? condition_for(name), value
16
- end
17
-
18
- alias_method :accept?, :sufficient?
19
- alias_method :valid?, :sufficient?
20
2
 
21
- # all members passed under any condition
22
- def strict?
23
- each_pair.all?{|name, value|sufficient? name, value}
24
- end
3
+ # @group Safety
25
4
 
26
5
  # freezed, fixed familar members, all members passed any condition
27
6
  def secure?
28
7
  (frozen? || lock?) && self.class.closed? && strict?
29
8
  end
30
9
 
31
- # @overload lock(key)
32
- # lock a setter for key
33
- # @param [Symbol, String, Fixnum] key
34
- # @overload lock(true)
35
- # lock setters for all members
36
- # @param [true] true
37
- # @return [self]
38
- def lock(key=true)
39
- raise "can't modify frozen #{self.class}" if frozen?
40
-
41
- if key.equal? true
42
- names.each do |name|
43
- @locks[name] = true
44
- end
45
- else
46
- __subscript__(key){|name|@locks[name] = true}
47
- end
48
-
49
- self
50
- end
51
-
52
- # @see #lock
53
- def lock?(key=true)
54
- if key.equal? true
55
- names.all?{|name|@locks[name]}
56
- else
57
- __subscript__(key){|name|@locks[name]} || false
58
- end
59
- end
60
-
61
- private
62
-
63
- def unlock(key=true)
64
- raise "can't modify frozen #{self.class}" if frozen?
65
-
66
- if key.equal? true
67
- @locks.clear
68
- else
69
- __subscript__(key){|name|@locks.delete name}
70
- end
71
-
72
- self
73
- end
74
-
75
10
  # @endgroup
11
+
76
12
  end; end
@@ -4,12 +4,15 @@ class Striuct; module InstanceMethods
4
4
 
5
5
  private
6
6
 
7
+ # @param [Symbol, String] name
7
8
  def delegate_class_method(name)
8
9
  define_method name do |*args, &block|
9
10
  self.class.__send__ name, *args, &block
10
11
  end
11
12
  end
12
-
13
+
14
+ # @param [Symbol, String] name
15
+ # @param [Symbol, String] names
13
16
  def delegate_class_methods(name, *names)
14
17
  [name, *names].each{|_name|delegate_class_method _name}
15
18
  end
@@ -0,0 +1,55 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Subscript
4
+
5
+ # @param [Symbol, String, Fixnum] key
6
+ def [](key)
7
+ __subscript__(key){|autonym|__get__ autonym}
8
+ end
9
+
10
+ # @param [Symbol, String, Fixnum] key
11
+ # @param [Object] value
12
+ # @return [value]
13
+ def []=(key, value)
14
+ true_name = nil
15
+ __subscript__(key){|autonym|
16
+ true_name = autonym
17
+ __set__ autonym, value
18
+ }
19
+ rescue Validation::InvalidWritingError
20
+ $!.set_backtrace([
21
+ "#{$!.backtrace[-1].sub(/[^:]+\z/){''}}in `[#{key.inspect}(#{true_name})]=': #{$!.message}",
22
+ $!.backtrace[-1]
23
+ ])
24
+
25
+ raise
26
+ end
27
+
28
+ private
29
+
30
+ # @param [Symbol, String, Fixnum] key
31
+ # @yield [autonym]
32
+ # @yieldparam [Symbol] autonym
33
+ def __subscript__(key)
34
+ case key
35
+ when Symbol, String
36
+ name = keyable_for key
37
+ if member? name
38
+ yield autonym_for(name)
39
+ else
40
+ raise NameError
41
+ end
42
+ when Fixnum
43
+ if autonym = autonyms[key]
44
+ yield autonym
45
+ else
46
+ raise IndexError
47
+ end
48
+ else
49
+ raise ArgumentError
50
+ end
51
+ end
52
+
53
+ # @endgroup
54
+
55
+ end; end
@@ -0,0 +1,12 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group To Ruby's Struct
4
+
5
+ # @return [Struct]
6
+ def to_struct
7
+ self.class.to_struct_class.new(*values)
8
+ end
9
+
10
+ # @endgroup
11
+
12
+ end; end
@@ -0,0 +1,25 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Validation
4
+
5
+ # @param [Symbol, String] name
6
+ # @param [Object] value - no argument and use own
7
+ # passed under any condition
8
+ def sufficient?(name, value=self[name])
9
+ autonym = autonym_for name
10
+ return true unless restrict? autonym
11
+
12
+ _valid? condition_for(autonym), value
13
+ end
14
+
15
+ alias_method :accept?, :sufficient?
16
+ alias_method :valid?, :sufficient?
17
+
18
+ # all members passed under any condition
19
+ def strict?
20
+ each_pair.all?{|autonym, value|sufficient? autonym, value}
21
+ end
22
+
23
+ # @endgroup
24
+
25
+ end; end
@@ -0,0 +1,64 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Behavior under Values
4
+
5
+ # @return [Array]
6
+ def values
7
+ each_value.to_a
8
+ end
9
+
10
+ alias_method :to_a, :values
11
+
12
+ # @param [Fixnum, Range] _keys
13
+ # @return [Array]
14
+ def values_at(*_keys)
15
+ [].tap {|r|
16
+ _keys.each do |key|
17
+ case key
18
+ when Fixnum
19
+ r << self[key]
20
+ when Range
21
+ key.each do |n|
22
+ raise TypeError unless n.instance_of? Fixnum
23
+ r << self[n]
24
+ end
25
+ else
26
+ raise TypeError
27
+ end
28
+ end
29
+ }
30
+ end
31
+
32
+ # @return [self]
33
+ def replace_values(*values)
34
+ unless values.size <= size
35
+ raise ArgumentError, "struct size differs (max: #{size})"
36
+ end
37
+
38
+ values.each_with_index do |value, index|
39
+ self[index] = value
40
+ end
41
+
42
+ excess = autonyms.last(size - values.size)
43
+
44
+ excess.each do |autonym|
45
+ if has_default? autonym
46
+ self[autonym] = (
47
+ value = default_for autonym
48
+ if value.kind_of? DefaultProcHolder
49
+ block = value.value
50
+ args = [self, autonym][0, block.arity]
51
+ block.call(*args)
52
+ else
53
+ value
54
+ end
55
+ )
56
+ end
57
+ end
58
+
59
+ self
60
+ end
61
+
62
+ # @endgroup
63
+
64
+ end; end
@@ -9,18 +9,18 @@ class Striuct
9
9
  alias_method :new_instance, :new
10
10
  private :new_instance
11
11
 
12
- # @param [Symbol, String] *names
12
+ # @param [Symbol, String] autonyms
13
13
  # @return [Class]
14
- def new(*names, &block)
14
+ def new(*autonyms, &block)
15
15
  # warning for Ruby's Struct.new user
16
- first = names.first
16
+ first = autonyms.first
17
17
  if first.instance_of?(String) and /\A[A-Z]/ =~ first
18
18
  warn "no define constant #{first}"
19
19
  end
20
20
 
21
21
  Class.new self do
22
- names.each do |name|
23
- member name
22
+ autonyms.each do |autonym|
23
+ add_member autonym
24
24
  end
25
25
 
26
26
  class_eval(&block) if block_given?
@@ -34,7 +34,7 @@ class Striuct
34
34
 
35
35
  new(&block).tap do |subclass|
36
36
  subclass.instance_eval do
37
- raise 'not yet finished' if members.empty?
37
+ raise 'not yet finished' if autonyms.empty?
38
38
  close
39
39
  end
40
40
  end
@@ -53,7 +53,7 @@ class Striuct
53
53
  else
54
54
  [
55
55
  *[
56
- @names, @conditions, @flavors, @defaults,
56
+ @autonyms, @conditions, @adjusters, @defaults,
57
57
  @inferences, @aliases, @setter_validations,
58
58
  @getter_validations
59
59
  ].map(&:dup), @protect_level
@@ -72,15 +72,15 @@ class Striuct
72
72
  include InstanceMethods
73
73
  end
74
74
 
75
- @names, @conditions, @flavors, @defaults,
75
+ @autonyms, @conditions, @adjusters, @defaults,
76
76
  @inferences, @aliases, @setter_validations,
77
77
  @getter_validations, @protect_level = *attributes
78
78
 
79
79
  singleton_class.instance_eval do
80
80
  define_method :initialize_copy do |original|
81
- @names, @flavors, @defaults, @aliases,
81
+ @autonyms, @adjusters, @defaults, @aliases,
82
82
  @setter_validations, @getter_validations =
83
- *[@names, @flavors, @defaults, @aliases,
83
+ *[@autonyms, @adjusters, @defaults, @aliases,
84
84
  @setter_validations, @getter_validations].map(&:dup)
85
85
  @conditions, @inferences = @conditions.dup, @inferences.dup
86
86
  end
@@ -10,8 +10,10 @@ class Striuct
10
10
 
11
11
  end
12
12
 
13
+ class DefaultProcHolder < SpecificContainer; end
14
+
13
15
  if respond_to? :private_constant
14
- private_constant :SpecificContainer
16
+ private_constant :SpecificContainer, :DefaultProcHolder
15
17
  end
16
18
 
17
19
  end
@@ -1,5 +1,5 @@
1
1
  class Striuct
2
2
 
3
- VERSION = '0.3.1'.freeze
3
+ VERSION = '0.3.2'.freeze
4
4
 
5
5
  end
data/striuct.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
18
18
 
19
19
  gem.required_ruby_version = '>=1.9.2'
20
20
  gem.add_runtime_dependency 'validation', '~>0.0.3.1'
21
- gem.add_runtime_dependency 'keyvalidatable', '~>0.0.2'
21
+ gem.add_runtime_dependency 'keyvalidatable', '~>0.0.3'
22
22
  gem.add_development_dependency 'yard', '>=0.8.2.1'
23
23
  end
24
24
 
@@ -23,9 +23,9 @@ class TestStriuctAliasMember < Test::Unit::TestCase
23
23
  assert_equal [:foo, :bar, :hoge, :abc], sth.all_members
24
24
 
25
25
  assert_equal 8, sth[:abc]
26
- flavor = Sth.__send__(:flavor_for, :abc)
27
- assert_kind_of Proc, flavor
28
- assert_same flavor, Sth.__send__(:flavor_for, :bar)
26
+ adjuster = Sth.__send__(:adjuster_for, :abc)
27
+ assert_kind_of Proc, adjuster
28
+ assert_same adjuster, Sth.__send__(:adjuster_for, :bar)
29
29
  assert_equal 8, sth.abc
30
30
  sth.abc = 5
31
31
  assert_equal 5, sth.bar
@@ -3,11 +3,18 @@ require_relative 'helper'
3
3
  class TestStriuctForPairs < Test::Unit::TestCase
4
4
 
5
5
  Sth = Striuct.new :foo, :bar, :hoge
6
+ SampleStruct = Struct.new :foo, :bar, :hoge
6
7
 
7
- def test_for_pairs
8
+ def test_for_pairs_from_hash
8
9
  sth = Sth[hoge: 7, foo: 8]
9
10
 
10
11
  assert_equal [8, nil, 7], sth.values
11
12
  end
12
13
 
14
+ def test_for_pairs_from_struct
15
+ sth = Sth[SampleStruct.new 8, nil, 7]
16
+
17
+ assert_equal [8, nil, 7], sth.values
18
+ end
19
+
13
20
  end