striuct 0.3.1 → 0.3.2

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