striuct 0.6.1 → 0.7.0

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE.txt +21 -0
  3. data/README.md +19 -39
  4. data/lib/striuct.rb +3 -3
  5. data/lib/striuct/classmethods/README.md +2 -2
  6. data/lib/striuct/classmethods/adjustment.rb +15 -13
  7. data/lib/striuct/classmethods/attributes.rb +94 -92
  8. data/lib/striuct/classmethods/conflict_management.rb +109 -106
  9. data/lib/striuct/classmethods/constructor.rb +47 -54
  10. data/lib/striuct/classmethods/copy.rb +45 -43
  11. data/lib/striuct/classmethods/default.rb +23 -21
  12. data/lib/striuct/classmethods/enum.rb +46 -44
  13. data/lib/striuct/classmethods/fix.rb +23 -21
  14. data/lib/striuct/classmethods/hashdeepdupulicatable.rb +15 -15
  15. data/lib/striuct/classmethods/inner.rb +57 -55
  16. data/lib/striuct/classmethods/length.rb +12 -10
  17. data/lib/striuct/classmethods/macro.rb +110 -106
  18. data/lib/striuct/classmethods/names.rb +69 -65
  19. data/lib/striuct/classmethods/predicate.rb +131 -129
  20. data/lib/striuct/classmethods/requirements.rb +3 -1
  21. data/lib/striuct/classmethods/to_struct.rb +21 -18
  22. data/lib/striuct/classmethods/validation.rb +15 -13
  23. data/lib/striuct/instancemethods/README.md +2 -2
  24. data/lib/striuct/instancemethods/assign.rb +29 -27
  25. data/lib/striuct/instancemethods/cast.rb +28 -26
  26. data/lib/striuct/instancemethods/compare.rb +26 -24
  27. data/lib/striuct/instancemethods/default.rb +31 -29
  28. data/lib/striuct/instancemethods/delegate_class_methods.rb +35 -33
  29. data/lib/striuct/instancemethods/enum.rb +86 -84
  30. data/lib/striuct/instancemethods/getter.rb +39 -37
  31. data/lib/striuct/instancemethods/hashy.rb +99 -97
  32. data/lib/striuct/instancemethods/keyvalidatable.rb +8 -6
  33. data/lib/striuct/instancemethods/lock.rb +46 -44
  34. data/lib/striuct/instancemethods/object.rb +50 -48
  35. data/lib/striuct/instancemethods/requirements.rb +11 -9
  36. data/lib/striuct/instancemethods/safety.rb +11 -9
  37. data/lib/striuct/instancemethods/setter.rb +46 -45
  38. data/lib/striuct/instancemethods/to_s.rb +39 -37
  39. data/lib/striuct/instancemethods/validation.rb +31 -29
  40. data/lib/striuct/instancemethods/values.rb +50 -48
  41. data/lib/striuct/requirements.rb +3 -1
  42. data/lib/striuct/singleton_class.rb +12 -17
  43. data/lib/striuct/structs.rb +3 -3
  44. metadata +33 -178
  45. data/.gitignore +0 -35
  46. data/.travis.yml +0 -17
  47. data/.yardopts +0 -1
  48. data/Gemfile +0 -11
  49. data/MIT-LICENSE +0 -22
  50. data/Rakefile +0 -11
  51. data/benchmark/basics.rb +0 -56
  52. data/example/README.rb +0 -50
  53. data/example/example1.rb +0 -195
  54. data/example/example2.rb +0 -20
  55. data/example/see_trace.rb +0 -32
  56. data/striuct.gemspec +0 -45
  57. data/test/helper.rb +0 -3
  58. data/test/test_sglc-constructor.rb +0 -36
  59. data/test/test_subc-c-add_members.rb +0 -13
  60. data/test/test_subc-c-close_member.rb +0 -36
  61. data/test/test_subc-c-constructor.rb +0 -92
  62. data/test/test_subc-c-copy.rb +0 -71
  63. data/test/test_subc-c-freeze.rb +0 -36
  64. data/test/test_subc-c-inheritable.rb +0 -58
  65. data/test/test_subc-c-safety_naming.rb +0 -73
  66. data/test/test_subc-f-alias_member.rb +0 -54
  67. data/test/test_subc-f-enum.rb +0 -159
  68. data/test/test_subc-f-predicate.rb +0 -647
  69. data/test/test_subc-f-to_struct.rb +0 -61
  70. data/test/test_subc-f-validation_util.rb +0 -59
  71. data/test/test_subc-f_debug.rb +0 -39
  72. data/test/test_subc-f_name.rb +0 -525
  73. data/test/test_subc-i-accessor.rb +0 -138
  74. data/test/test_subc-i-adjuster.rb +0 -95
  75. data/test/test_subc-i-assign.rb +0 -53
  76. data/test/test_subc-i-basic.rb +0 -43
  77. data/test/test_subc-i-cast.rb +0 -27
  78. data/test/test_subc-i-compare.rb +0 -52
  79. data/test/test_subc-i-copy.rb +0 -23
  80. data/test/test_subc-i-default_value.rb +0 -129
  81. data/test/test_subc-i-freeze.rb +0 -19
  82. data/test/test_subc-i-hashlike.rb +0 -144
  83. data/test/test_subc-i-keyvalidatable.rb +0 -25
  84. data/test/test_subc-i-lock.rb +0 -40
  85. data/test/test_subc-i-must.rb +0 -30
  86. data/test/test_subc-i-to_s_family.rb +0 -26
  87. data/test/test_subc-i-validation_specific_conditions.rb +0 -297
  88. data/test/test_subc-i-validation_with_getter.rb +0 -33
  89. data/test/test_version.rb +0 -13
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optionalargument'
2
4
 
3
5
  require_relative 'hashdeepdupulicatable'
@@ -15,4 +17,4 @@ require_relative 'default'
15
17
  require_relative 'adjustment'
16
18
  require_relative 'macro'
17
19
  require_relative 'conflict_management'
18
- require_relative 'validation'
20
+ require_relative 'validation'
@@ -1,24 +1,27 @@
1
- class Striuct; module ClassMethods
1
+ # frozen_string_literal: true
2
2
 
3
- # @group To Ruby's Struct Class
3
+ class Striuct
4
+ module ClassMethods
5
+ # @group To Ruby's Struct Class
4
6
 
5
- # @return [Class]
6
- def to_struct_class
7
- raise 'No defined members' if autonyms.empty?
7
+ # @return [Class]
8
+ def to_struct_class
9
+ raise 'No defined members' if autonyms.empty?
8
10
 
9
- struct_cls = ::Struct.new(*autonyms)
10
- return struct_cls unless name
11
+ struct_cls = ::Struct.new(*autonyms)
12
+ return struct_cls unless name
11
13
 
12
- const_suffix = name.slice(/[^:]+\z/).to_sym
13
- if ::Striuct::Structs.const_defined?(const_suffix, false) &&
14
- (already_cls = ::Striuct::Structs.const_get(const_suffix, false)).members == autonyms
15
- raise unless already_cls.superclass.equal? Struct
16
- already_cls
17
- else
18
- ::Striuct::Structs.const_set const_suffix, struct_cls
19
- end
20
- end
14
+ const_suffix = name.slice(/[^:]+\z/).to_sym
15
+ if ::Striuct::Structs.const_defined?(const_suffix, false) &&
16
+ (already_cls = ::Striuct::Structs.const_get(const_suffix, false)).members == autonyms
17
+ raise unless already_cls.superclass.equal?(Struct)
21
18
 
22
- # @endgroup
19
+ already_cls
20
+ else
21
+ ::Striuct::Structs.const_set(const_suffix, struct_cls)
22
+ end
23
+ end
23
24
 
24
- end; end
25
+ # @endgroup
26
+ end
27
+ end
@@ -1,15 +1,17 @@
1
- class Striuct; module ClassMethods
2
-
3
- # @group Validation
4
-
5
- # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
6
- def condition_for(key)
7
- autonym = autonym_for_key key
8
- raise KeyError unless with_condition? autonym
9
-
10
- _attributes_for(autonym).condition
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ class Striuct
4
+ module ClassMethods
5
+ # @group Validation
12
6
 
13
- # @endgroup
7
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
8
+ def condition_for(key)
9
+ autonym = autonym_for_key(key)
10
+ raise KeyError unless with_condition?(autonym)
14
11
 
15
- end; end
12
+ _attributes_for(autonym).condition
13
+ end
14
+
15
+ # @endgroup
16
+ end
17
+ end
@@ -1,5 +1,5 @@
1
1
  Note
2
2
  =====
3
3
 
4
- This dir's tree is diveded under roles/features.
5
- Not under CONSTANT names.
4
+ This dir's tree is divided under roles/features.
5
+ Not under CONSTANT names.
@@ -1,33 +1,35 @@
1
- class Striuct; module InstanceMethods
1
+ # frozen_string_literal: true
2
2
 
3
- # @group Assign / Unassign
4
-
5
- # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
6
- def assigned?(key)
7
- @db.has_key? autonym_for_key(key)
8
- end
3
+ class Striuct
4
+ module InstanceMethods
5
+ # @group Assign / Unassign
9
6
 
10
- alias_method :assign?, :assigned?
11
-
12
- # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
13
- # @return value / nil - value assigned under the key
14
- def unassign(key)
15
- _check_frozen
16
- _check_locked key
17
- if must? key
18
- raise InvalidOperationError, "`#{key}` require a value under `must` option"
7
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
8
+ def assigned?(key)
9
+ @db.key?(autonym_for_key(key))
19
10
  end
20
-
21
- @db.delete autonym_for_key(key)
22
- end
23
-
24
- alias_method :delete_at, :unassign
25
11
 
26
- # true if all members are not yet assigned
27
- def empty?
28
- _autonyms.none?{|autonym|@db.has_key? autonym}
29
- end
12
+ alias_method :assign?, :assigned?
30
13
 
31
- # @endgroup
14
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
15
+ # @return value / nil - value assigned under the key
16
+ def unassign(key)
17
+ _check_frozen
18
+ _check_locked(key)
19
+ if must?(key)
20
+ raise InvalidOperationError, "`#{key}` require a value under `must` option"
21
+ end
22
+
23
+ @db.delete(autonym_for_key(key))
24
+ end
32
25
 
33
- end; end
26
+ alias_method :delete_at, :unassign
27
+
28
+ # true if all members are not yet assigned
29
+ def empty?
30
+ _autonyms.none? { |autonym| @db.key?(autonym) }
31
+ end
32
+
33
+ # @endgroup
34
+ end
35
+ end
@@ -1,32 +1,34 @@
1
- class Striuct; module InstanceMethods
1
+ # frozen_string_literal: true
2
2
 
3
- # @group Cast
3
+ class Striuct
4
+ module InstanceMethods
5
+ # @group Cast
4
6
 
5
- # @return [self]
6
- def to_striuct
7
- self
8
- end
7
+ # @return [self]
8
+ def to_striuct
9
+ self
10
+ end
9
11
 
10
- # @return [Struct]
11
- def to_struct
12
- self.class.to_struct_class.new(*values)
13
- end
14
-
15
- # @param [Boolean] include_no_assign
16
- # @return [Hash]
17
- def to_h(include_no_assign=true)
18
- return @db.dup unless include_no_assign
12
+ # @return [Struct]
13
+ def to_struct
14
+ self.class.to_struct_class.new(*values)
15
+ end
19
16
 
20
- Hash[each_pair.to_a]
21
- end
22
-
23
- # @return [Array]
24
- def values
25
- each_value.to_a
26
- end
27
-
28
- alias_method :to_a, :values
17
+ # @param [Boolean] include_no_assign
18
+ # @return [Hash]
19
+ def to_h(include_no_assign: true)
20
+ return @db.dup unless include_no_assign
29
21
 
30
- # @endgroup
22
+ each_pair.to_a.to_h
23
+ end
31
24
 
32
- end; end
25
+ # @return [Array]
26
+ def values
27
+ each_value.to_a
28
+ end
29
+
30
+ alias_method :to_a, :values
31
+
32
+ # @endgroup
33
+ end
34
+ end
@@ -1,30 +1,32 @@
1
- class Striuct; module InstanceMethods
2
-
3
- # @group Compare with other
4
-
5
- # @return [Boolean]
6
- def ==(other)
7
- other.instance_of?(self.class) &&
8
- each_pair.all?{|autonym, val|other._get(autonym) == val}
9
- end
1
+ # frozen_string_literal: true
10
2
 
11
- alias_method :===, :==
12
-
13
- def eql?(other)
14
- other.instance_of?(self.class) && other._db.eql?(@db)
15
- end
3
+ class Striuct
4
+ module InstanceMethods
5
+ # @group Compare with other
16
6
 
17
- # @return [Integer]
18
- def hash
19
- @db.hash
20
- end
7
+ # @return [Boolean]
8
+ def ==(other)
9
+ other.instance_of?(self.class) &&
10
+ each_pair.all? { |autonym, val| other._get(autonym) == val }
11
+ end
21
12
 
22
- protected
13
+ alias_method :===, :==
23
14
 
24
- def _db
25
- @db
26
- end
15
+ def eql?(other)
16
+ other.instance_of?(self.class) && other._db.eql?(@db)
17
+ end
27
18
 
28
- # @endgroup
19
+ # @return [Integer]
20
+ def hash
21
+ @db.hash
22
+ end
29
23
 
30
- end; end
24
+ protected
25
+
26
+ def _db
27
+ @db
28
+ end
29
+
30
+ # @endgroup
31
+ end
32
+ end
@@ -1,36 +1,38 @@
1
- class Striuct; module InstanceMethods
1
+ # frozen_string_literal: true
2
2
 
3
- # @group Default Value
4
-
5
- # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
6
- def default?(key)
7
- autonym = autonym_for_key key
3
+ class Striuct
4
+ module InstanceMethods
5
+ # @group Default Value
8
6
 
9
- default_value_for(autonym) == fetch_by_autonym(autonym)
10
- end
7
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
8
+ def default?(key)
9
+ autonym = autonym_for_key(key)
10
+
11
+ default_value_for(autonym) == fetch_by_autonym(autonym)
12
+ end
11
13
 
12
- private
14
+ private
13
15
 
14
- # @param [Symbol] target_autonyms - MUST already converted to native autonym
15
- # @return [self]
16
- def _set_defaults(*target_autonyms)
17
- target_autonyms.each do |autonym|
18
- if with_default? autonym
19
- default = default_value_for autonym
20
- _set autonym, (
21
- if default_type_for(autonym) == :lazy
22
- args = [self, autonym][0, default.arity]
23
- default.call(*args)
24
- else
25
- default
26
- end
27
- )
16
+ # @param [Symbol] target_autonyms - MUST already converted to native autonym
17
+ # @return [self]
18
+ def _set_defaults(*target_autonyms)
19
+ target_autonyms.each do |autonym|
20
+ if with_default?(autonym)
21
+ default = default_value_for(autonym)
22
+ _set(autonym, (
23
+ if default_type_for(autonym) == :lazy
24
+ args = [self, autonym][0, default.arity]
25
+ default.call(*args)
26
+ else
27
+ default
28
+ end
29
+ ))
30
+ end
28
31
  end
29
- end
30
-
31
- self
32
- end
33
32
 
34
- # @endgroup
33
+ self
34
+ end
35
35
 
36
- end; end
36
+ # @endgroup
37
+ end
38
+ end
@@ -1,37 +1,39 @@
1
- class Striuct; module InstanceMethods
1
+ # frozen_string_literal: true
2
2
 
3
- # @group Delegate Class Methods
4
-
5
- def_delegators :'self.class',
6
- :autonym_for_alias,
7
- :autonym_for_member,
8
- :autonym_for_index,
9
- :autonym_for_key,
10
- :autonyms, :members, :all_members, :aliases, :attributes,
11
- :has_autonym?, :autonym?,
12
- :has_alias?, :alias?, :aliased?,
13
- :has_member?, :member?,
14
- :has_index?, :index?,
15
- :has_key?, :key?,
16
- :with_aliases?,
17
- :aliases_for_autonym,
18
- :length, :size,
19
- :with_condition?, :restrict?,
20
- :condition_for,
21
- :with_safety_getter?, :with_safety_reader?,
22
- :with_safety_setter?, :with_safety_writer?,
23
- :with_must?, :must?,
24
- :with_default?,
25
- :default_value_for, :default_type_for,
26
- :with_adjuster?,
27
- :adjuster_for
3
+ class Striuct
4
+ module InstanceMethods
5
+ # @group Delegate Class Methods
28
6
 
29
- private
7
+ def_delegators :'self.class',
8
+ :autonym_for_alias,
9
+ :autonym_for_member,
10
+ :autonym_for_index,
11
+ :autonym_for_key,
12
+ :autonyms, :members, :all_members, :aliases, :attributes,
13
+ :has_autonym?, :autonym?,
14
+ :has_alias?, :alias?, :aliased?,
15
+ :has_member?, :member?,
16
+ :has_index?, :index?,
17
+ :has_key?, :key?,
18
+ :with_aliases?,
19
+ :aliases_for_autonym,
20
+ :length, :size,
21
+ :with_condition?, :restrict?,
22
+ :condition_for,
23
+ :with_safety_getter?, :with_safety_reader?,
24
+ :with_safety_setter?, :with_safety_writer?,
25
+ :with_must?, :must?,
26
+ :with_default?,
27
+ :default_value_for, :default_type_for,
28
+ :with_adjuster?,
29
+ :adjuster_for
30
30
 
31
- def _autonyms
32
- self.class.__send__ :_autonyms
33
- end
31
+ private
32
+
33
+ def _autonyms
34
+ self.class.__send__(:_autonyms)
35
+ end
34
36
 
35
- # @endgroup
36
-
37
- end; end
37
+ # @endgroup
38
+ end
39
+ end
@@ -1,98 +1,100 @@
1
- class Striuct; module InstanceMethods
1
+ # frozen_string_literal: true
2
2
 
3
- # @group Enumerative
3
+ class Striuct
4
+ module InstanceMethods
5
+ # @group Enumerative
4
6
 
5
- # @yield [autonym]
6
- # @yieldparam [Symbol] autonym - sequential under defined
7
- # @yieldreturn [self]
8
- # @return [Enumerator]
9
- def each_autonym(&block)
10
- return to_enum(__callee__) { self.class.size } unless block_given?
7
+ # @yield [autonym]
8
+ # @yieldparam [Symbol] autonym - sequential under defined
9
+ # @yieldreturn [self]
10
+ # @return [Enumerator]
11
+ def each_autonym(&block)
12
+ return to_enum(__callee__) { self.class.size } unless block
11
13
 
12
- self.class.each_autonym(&block)
13
- self
14
- end
14
+ self.class.each_autonym(&block)
15
+ self
16
+ end
15
17
 
16
- alias_method :each_member, :each_autonym
17
-
18
- # @yield [value]
19
- # @yieldparam [Object] value - sequential under defined
20
- # @see #each_autonym
21
- # @yieldreturn [self]
22
- # @return [Enumerator]
23
- def each_value
24
- return to_enum(__callee__) { self.class.size } unless block_given?
25
-
26
- each_autonym{|autonym|yield _get(autonym)}
27
- end
28
-
29
- alias_method :each, :each_value
30
-
31
- # @yield [autonym, value]
32
- # @yieldparam [Symbol] autonym
33
- # @yieldparam [Object] value
34
- # @yieldreturn [self]
35
- # @return [Enumerator]
36
- # @see #each_autonym
37
- # @see #each_value
38
- def each_pair
39
- return to_enum(__callee__) { self.class.size } unless block_given?
40
-
41
- each_autonym{|autonym|yield autonym, _get(autonym)}
42
- end
18
+ alias_method :each_member, :each_autonym
43
19
 
44
- # @yield [index]
45
- # @yieldparam [Integer] index
46
- # @yieldreturn [self]
47
- # @return [Enumerator]
48
- def each_index
49
- return to_enum(__callee__) { self.class.size } unless block_given?
20
+ # @yield [value]
21
+ # @yieldparam [Object] value - sequential under defined
22
+ # @see #each_autonym
23
+ # @yieldreturn [self]
24
+ # @return [Enumerator]
25
+ def each_value
26
+ return to_enum(__callee__) { self.class.size } unless block_given?
50
27
 
51
- self.class.each_index{|index|yield index}
52
- self
53
- end
28
+ each_autonym { |autonym| yield _get(autonym) }
29
+ end
54
30
 
55
- # @yield [autonym, index]
56
- # @yieldparam [Symbol] autonym
57
- # @yieldparam [Integer] index
58
- # @yieldreturn [self]
59
- # @return [Enumerator]
60
- def each_autonym_with_index
61
- return to_enum(__callee__) { self.class.size } unless block_given?
31
+ alias_method :each, :each_value
62
32
 
63
- self.class.each_autonym_with_index{|autonym, index|yield autonym, index}
64
- self
65
- end
33
+ # @yield [autonym, value]
34
+ # @yieldparam [Symbol] autonym
35
+ # @yieldparam [Object] value
36
+ # @yieldreturn [self]
37
+ # @return [Enumerator]
38
+ # @see #each_autonym
39
+ # @see #each_value
40
+ def each_pair
41
+ return to_enum(__callee__) { self.class.size } unless block_given?
66
42
 
67
- alias_method :each_member_with_index, :each_autonym_with_index
43
+ each_autonym { |autonym| yield autonym, _get(autonym) }
44
+ end
68
45
 
69
- # @yield [value, index]
70
- # @yieldparam [Integer] index
71
- # @yieldreturn [self]
72
- # @return [Enumerator]
73
- def each_value_with_index
74
- return to_enum(__callee__) { self.class.size } unless block_given?
46
+ # @yield [index]
47
+ # @yieldparam [Integer] index
48
+ # @yieldreturn [self]
49
+ # @return [Enumerator]
50
+ def each_index
51
+ return to_enum(__callee__) { self.class.size } unless block_given?
75
52
 
76
- each_value.with_index{|value, index|yield value, index}
77
- end
78
-
79
- alias_method :each_with_index, :each_value_with_index
80
-
81
- # @yield [autonym, value, index]
82
- # @yieldparam [Symbol] autonym
83
- # @yieldparam [Integer] index
84
- # @yieldreturn [self]
85
- # @return [Enumerator]
86
- def each_pair_with_index
87
- return to_enum(__callee__) { self.class.size } unless block_given?
88
-
89
- index = 0
90
- each_pair do |autonym, value|
91
- yield autonym, value, index
92
- index += 1
53
+ self.class.each_index { |index| yield index }
54
+ self
93
55
  end
94
- end
95
56
 
96
- # @endgroup
57
+ # @yield [autonym, index]
58
+ # @yieldparam [Symbol] autonym
59
+ # @yieldparam [Integer] index
60
+ # @yieldreturn [self]
61
+ # @return [Enumerator]
62
+ def each_autonym_with_index
63
+ return to_enum(__callee__) { self.class.size } unless block_given?
97
64
 
98
- end; end
65
+ self.class.each_autonym_with_index { |autonym, index| yield autonym, index }
66
+ self
67
+ end
68
+
69
+ alias_method :each_member_with_index, :each_autonym_with_index
70
+
71
+ # @yield [value, index]
72
+ # @yieldparam [Integer] index
73
+ # @yieldreturn [self]
74
+ # @return [Enumerator]
75
+ def each_value_with_index
76
+ return to_enum(__callee__) { self.class.size } unless block_given?
77
+
78
+ each_value.with_index { |value, index| yield value, index }
79
+ end
80
+
81
+ alias_method :each_with_index, :each_value_with_index
82
+
83
+ # @yield [autonym, value, index]
84
+ # @yieldparam [Symbol] autonym
85
+ # @yieldparam [Integer] index
86
+ # @yieldreturn [self]
87
+ # @return [Enumerator]
88
+ def each_pair_with_index
89
+ return to_enum(__callee__) { self.class.size } unless block_given?
90
+
91
+ index = 0
92
+ each_pair do |autonym, value|
93
+ yield autonym, value, index
94
+ index += 1
95
+ end
96
+ end
97
+
98
+ # @endgroup
99
+ end
100
+ end