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
@@ -0,0 +1,94 @@
1
+ class Striuct; module ClassMethods
2
+
3
+ # @group Named
4
+
5
+ # @param [Symbol, String, #to_sym] name
6
+ # @return [Symbol]
7
+ def keyable_for(name)
8
+ name.to_sym
9
+ end
10
+
11
+ # @return [Array<Symbol>]
12
+ def autonyms
13
+ @autonyms.dup
14
+ end
15
+
16
+ alias_method :names, :autonyms
17
+ alias_method :members, :autonyms
18
+ alias_method :keys, :autonyms
19
+
20
+ # @return [Array<Symbol>]
21
+ def all_members
22
+ @autonyms + @aliases.keys
23
+ end
24
+
25
+ def has_member?(name)
26
+ autonym_for name
27
+ rescue Exception
28
+ false
29
+ else
30
+ true
31
+ end
32
+
33
+ alias_method :member?, :has_member?
34
+ alias_method :has_key?, :has_member?
35
+ alias_method :key?, :has_key?
36
+
37
+ # @param [Symbol, String, #to_sym, #to_str] name
38
+ # @return [Symbol]
39
+ def autonym_for(name)
40
+ name = keyable_for name
41
+
42
+ if _autonyms.include? name
43
+ name
44
+ else
45
+ if autonym = _autonym_for(name)
46
+ autonym
47
+ else
48
+ raise NameError, "not defined member for #{name}"
49
+ end
50
+ end
51
+ end
52
+
53
+ # @param [Symbol, String] name
54
+ def autonym?(name)
55
+ name = keyable_for name
56
+ raise NameError unless member? name
57
+
58
+ @autonyms.include? name
59
+ end
60
+
61
+ alias_method :original?, :autonym?
62
+
63
+ # @param [Symbol, String] name
64
+ def aliased?(name)
65
+ name = keyable_for name
66
+ raise NameError unless member? name
67
+
68
+ @aliases.has_key? name
69
+ end
70
+
71
+ # @param [Symbol, String] autonym
72
+ def has_aliases?(autonym)
73
+ raise NameError unless autonym? autonym
74
+
75
+ @aliases.has_value? autonym
76
+ end
77
+
78
+ # @param [Symbol, String] autonym
79
+ # @return [Array<Symbol>]
80
+ def aliases_for(autonym)
81
+ autonym = keyable_for autonym
82
+ raise NameError unless has_aliases? autonym
83
+
84
+ _aliases_for autonym
85
+ end
86
+
87
+ # @return [Hash] alias => autonym
88
+ def aliases
89
+ @aliases.dup
90
+ end
91
+
92
+ # @endgroup
93
+
94
+ end; end
@@ -0,0 +1,24 @@
1
+ class Striuct; module ClassMethods
2
+
3
+ # @group Basic Methods for Ruby's Object
4
+
5
+ # @return [self]
6
+ def freeze
7
+ __stores__.each(&:freeze)
8
+ super
9
+ end
10
+
11
+ # @return [Class]
12
+ def dup
13
+ r = super
14
+ @autonyms, @adjusters, @defaults, @aliases,
15
+ @setter_validations, @getter_validations =
16
+ *[@autonyms, @adjusters, @defaults, @aliases,
17
+ @setter_validations, @getter_validations].map(&:dup)
18
+ @conditions, @inferences = @conditions.dup, @inferences.dup
19
+ r
20
+ end
21
+
22
+ # @endgroup
23
+
24
+ end; end
@@ -0,0 +1,89 @@
1
+ class Striuct; module ClassMethods
2
+
3
+ # @group Prevent Naming Conflicts
4
+
5
+ NAMING_RISKS = {
6
+ conflict: 10,
7
+ no_identifier: 9,
8
+ bad_manners: 5,
9
+ no_ascii: 3,
10
+ strict: 0
11
+ }.freeze
12
+
13
+ PROTECT_LEVELS = {
14
+ struct: {error: 99, warn: 99},
15
+ warning: {error: 99, warn: 5},
16
+ error: {error: 9, warn: 5},
17
+ prevent: {error: 5, warn: 1},
18
+ nervous: {error: 1, warn: 1}
19
+ }.each(&:freeze).freeze
20
+
21
+ # @param [Object] name
22
+ # accpeptable the name into own member, under protect level of runtime
23
+ def cname?(name)
24
+ _check_safety_naming(keyable_for name){|r|r}
25
+ rescue Exception
26
+ false
27
+ end
28
+
29
+ private
30
+
31
+ # @param [Symbol] level
32
+ # @return [nil]
33
+ # change protect level for risk of naming members
34
+ def protect_level(level)
35
+ raise NameError unless PROTECT_LEVELS.has_key? level
36
+
37
+ @protect_level = level
38
+ nil
39
+ end
40
+
41
+ # @param [Symbol] name
42
+ # @return [void]
43
+ # @yieldreturn [Boolean]
44
+ def _check_safety_naming(name)
45
+ estimation = _estimate_naming name
46
+ risk = NAMING_RISKS[estimation]
47
+ plevels = PROTECT_LEVELS[@protect_level]
48
+ caution = "undesirable naming '#{name}', because #{estimation}"
49
+
50
+ r = (
51
+ case
52
+ when risk >= plevels[:error]
53
+ raise NameError, caution unless block_given?
54
+ false
55
+ when risk >= plevels[:warn]
56
+ warn caution unless block_given?
57
+ false
58
+ else
59
+ true
60
+ end
61
+ )
62
+
63
+ yield r if block_given?
64
+ end
65
+
66
+ # @param [Symbol] name
67
+ # @return [Symbol]
68
+ def _estimate_naming(name)
69
+ if (instance_methods + private_instance_methods).include? name
70
+ return :conflict
71
+ end
72
+
73
+ return :no_ascii unless name.encoding.equal? Encoding::ASCII
74
+
75
+ case name
76
+ when /[\W]/, /\A[^a-zA-Z_]/, :''
77
+ :no_identifier
78
+ when /\Aeach/, /\A__[^_]*__\z/, /\A_[^_]*\z/, /[!?]\z/, /\Ato_/
79
+ :bad_manners
80
+ when /\A[a-zA-Z_]\w*\z/
81
+ :strict
82
+ else
83
+ raise 'must not happen'
84
+ end
85
+ end
86
+
87
+ # @endgroup
88
+
89
+ end; end
@@ -1,7 +1,12 @@
1
- require_relative 'constants'
2
1
  require_relative 'inner'
3
- require_relative 'basic'
2
+ require_relative 'named'
3
+ require_relative 'object'
4
+ require_relative 'length'
5
+ require_relative 'to_struct'
4
6
  require_relative 'constructor'
5
- require_relative 'handy'
7
+ require_relative 'enum'
8
+ require_relative 'default'
9
+ require_relative 'adjustment'
6
10
  require_relative 'macro'
7
- require_relative 'safety'
11
+ require_relative 'prevent_conflicts'
12
+ require_relative 'validation'
@@ -0,0 +1,26 @@
1
+ class Striuct; module ClassMethods
2
+
3
+ # @group To Ruby's Struct Class
4
+
5
+ # @return [Class]
6
+ def to_struct_class
7
+ raise 'No defined members' if autonyms.empty?
8
+
9
+ struct_klass = Struct.new(*names)
10
+
11
+ if name
12
+ tail_name = name.slice(/[^:]+\z/)
13
+ if ::Striuct::Structs.const_defined?(tail_name) &&
14
+ ((already = ::Striuct::Structs.const_get(tail_name)).members == members)
15
+ already
16
+ else
17
+ ::Striuct::Structs.const_set tail_name, struct_klass
18
+ end
19
+ else
20
+ struct_klass
21
+ end
22
+ end
23
+
24
+ # @endgroup
25
+
26
+ end; end
@@ -0,0 +1,56 @@
1
+ class Striuct; module ClassMethods
2
+
3
+ # @group Validation
4
+
5
+ # @param [Symbol, String] name
6
+ # inference checker is waiting yet
7
+ def inference?(name)
8
+ autonym = autonym_for name
9
+
10
+ @inferences.has_key? autonym
11
+ end
12
+
13
+ # @param [Symbol, String] name
14
+ def has_validator?(name)
15
+ autonym = autonym_for name
16
+
17
+ @conditions.has_key? autonym
18
+ end
19
+
20
+ alias_method :has_condition?, :has_validator?
21
+ alias_method :restrict?, :has_validator?
22
+
23
+ # @param [Symbol, String] name
24
+ def validator_for(name)
25
+ _condition_for autonym_for(name)
26
+ end
27
+
28
+ alias_method :condition_for, :validator_for
29
+
30
+ # @param [Symbol, String] name
31
+ def safety_getter?(name)
32
+ autonym = autonym_for name
33
+
34
+ @getter_validations.has_key? autonym
35
+ end
36
+
37
+ alias_method :safety_reader?, :safety_getter?
38
+
39
+ # @param [Symbol, String] name
40
+ def safety_setter?(name)
41
+ autonym = autonym_for name
42
+
43
+ @setter_validations.has_key? autonym
44
+ end
45
+
46
+ alias_method :safety_writer?, :safety_setter?
47
+
48
+ private
49
+
50
+ def _condition_for(name)
51
+ @conditions[name]
52
+ end
53
+
54
+ # @endgroup
55
+
56
+ end; end
@@ -0,0 +1,31 @@
1
+ require_relative 'subscript'
2
+
3
+ class Striuct; module InstanceMethods
4
+
5
+ # @group Assign
6
+
7
+ alias_method :assign, :[]=
8
+
9
+ # @param [Symbol, String] name
10
+ def assign?(name)
11
+ autonym = autonym_for name
12
+
13
+ @db.has_key? autonym
14
+ end
15
+
16
+ # @param [Symbol, String, Fixnum] key
17
+ def clear_at(key)
18
+ __subscript__(key){|autonym|__clear__ autonym}
19
+ end
20
+
21
+ alias_method :unassign, :clear_at
22
+ alias_method :reset_at, :clear_at
23
+
24
+ # all members aren't assigned
25
+ def empty?
26
+ autonyms.none?{|autonym|assign? autonym}
27
+ end
28
+
29
+ # @endgroup
30
+
31
+ end; end
@@ -0,0 +1,31 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Compare with other
4
+
5
+ # @return [Boolean]
6
+ def ==(other)
7
+ __compare_all__ other, :==
8
+ end
9
+
10
+ alias_method :===, :==
11
+
12
+ def eql?(other)
13
+ __compare_all__ other, :eql?
14
+ end
15
+
16
+ # @return [Integer]
17
+ def hash
18
+ @db.hash
19
+ end
20
+
21
+ private
22
+
23
+ # @param [Symbol] method
24
+ def __compare_all__(other, method)
25
+ instance_of?(other.class) && \
26
+ each_pair.all?{|k, v|v.__send__ method, other[k]}
27
+ end
28
+
29
+ # @endgroup
30
+
31
+ end; end
@@ -0,0 +1,14 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Default Value
4
+
5
+ # @param [Symbol, String] name
6
+ def default?(name)
7
+ autonym = autonym_for name
8
+
9
+ default_for(autonym) == self[autonym]
10
+ end
11
+
12
+ # @endgroup
13
+
14
+ end; end
@@ -0,0 +1,20 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Delegate Class Methods
4
+
5
+ # @see self.class.*args
6
+ delegate_class_methods(
7
+ :keyable_for, :autonym_for, :aliases_for,
8
+ :validator_for, :condition_for,
9
+ :adjuster_for, :flavor_for,
10
+ :members, :keys, :names, :autonyms, :all_members, :aliases,
11
+ :has_member?, :member?, :has_key?, :key?,
12
+ :length, :size,
13
+ :restrict?, :has_validator?, :has_condition?,
14
+ :safety_getter?, :safety_reader?, :safety_setter?, :safty_writer?, :inference?,
15
+ :has_default?, :default_for, :has_adjuster?, :has_flavor?
16
+ )
17
+
18
+ # @endgroup
19
+
20
+ end; end
@@ -0,0 +1,104 @@
1
+ class Striuct; module InstanceMethods
2
+
3
+ # @group Enumerative
4
+
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__) unless block_given?
11
+
12
+ self.class.each_autonym(&block)
13
+ self
14
+ end
15
+
16
+ alias_method :each_name, :each_autonym
17
+ alias_method :each_member, :each_autonym
18
+ alias_method :each_key, :each_autonym
19
+
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__) unless block_given?
27
+
28
+ each_autonym{|autonym|yield self[autonym]}
29
+ end
30
+
31
+ alias_method :each, :each_value
32
+
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__) unless block_given?
42
+
43
+ each_autonym{|autonym|yield autonym, self[autonym]}
44
+ end
45
+
46
+ # @yield [index]
47
+ # @yieldparam [Integer] index
48
+ # @yieldreturn [self]
49
+ # @return [Enumerator]
50
+ def each_index
51
+ return to_enum(__callee__) unless block_given?
52
+
53
+ self.class.each_index{|index|yield index}
54
+ self
55
+ end
56
+
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__) unless block_given?
64
+
65
+ self.class.each_autonym_with_index{|autonym, index|yield autonym, index}
66
+ self
67
+ end
68
+
69
+ alias_method :each_name_with_index, :each_autonym_with_index
70
+ alias_method :each_member_with_index, :each_autonym_with_index
71
+ alias_method :each_key_with_index, :each_autonym_with_index
72
+
73
+ # @yield [value, index]
74
+ # @yieldparam [Integer] index
75
+ # @yieldreturn [self]
76
+ # @return [Enumerator]
77
+ def each_value_with_index
78
+ return to_enum(__callee__) unless block_given?
79
+
80
+ each_value.with_index{|value, index|yield value, index}
81
+ self
82
+ end
83
+
84
+ alias_method :each_with_index, :each_value_with_index
85
+
86
+ # @yield [autonym, value, index]
87
+ # @yieldparam [Symbol] autonym
88
+ # @yieldparam [Integer] index
89
+ # @yieldreturn [self]
90
+ # @return [Enumerator]
91
+ def each_pair_with_index
92
+ return to_enum(__callee__) unless block_given?
93
+
94
+ index = 0
95
+ each_pair do |autonym, value|
96
+ yield autonym, value, index
97
+ index += 1
98
+ end
99
+ self
100
+ end
101
+
102
+ # @endgroup
103
+
104
+ end; end
@@ -1,30 +1,22 @@
1
+ require_relative 'subscript'
2
+
1
3
  class Striuct; module InstanceMethods
2
- # @group HashLike
4
+
5
+ # @group Like Ruby's Hash
6
+
7
+ alias_method :fetch, :[]
3
8
 
4
9
  # @return [Hash]
5
10
  def to_h(reject_no_assign=false)
6
11
  return @db.dup if reject_no_assign
7
12
 
8
13
  {}.tap {|h|
9
- each_pair do |k, v|
10
- h[k] = v
14
+ each_pair do |autonym, val|
15
+ h[autonym] = val
11
16
  end
12
17
  }
13
18
  end
14
19
 
15
- # @yield [name]
16
- # @yieldparam [Symbol] name - sequential under defined
17
- # @yieldreturn [self]
18
- # @return [Enumerator]
19
- def each_name(&block)
20
- return to_enum(__method__) unless block_given?
21
- self.class.each_name(&block)
22
- self
23
- end
24
-
25
- alias_method :each_member, :each_name
26
- alias_method :each_key, :each_name
27
-
28
20
  def has_value?(value)
29
21
  @db.has_value? value
30
22
  end
@@ -32,20 +24,20 @@ class Striuct; module InstanceMethods
32
24
  alias_method :value?, :has_value?
33
25
 
34
26
  # keep truthy only (unassign falsy member)
35
- # @yield [name, value]
36
- # @yieldparam [Symbol] name
27
+ # @yield [autonym, value]
28
+ # @yieldparam [Symbol] autonym
37
29
  # @see #each_pair
38
30
  # @return [Enumerator]
39
31
  # @yieldreturn [self]
40
32
  # @yieldreturn [nil]
41
33
  def select!
42
34
  raise "can't modify frozen #{self.class}" if frozen?
43
- return to_enum(__method__) unless block_given?
35
+ return to_enum(__callee__) unless block_given?
44
36
 
45
37
  modified = false
46
- each_pair do |name, value|
47
- unless yield name, value
48
- unassign name
38
+ each_pair do |autonym, value|
39
+ unless yield autonym, value
40
+ unassign autonym
49
41
  modified = true
50
42
  end
51
43
  end
@@ -54,29 +46,30 @@ class Striuct; module InstanceMethods
54
46
  end
55
47
 
56
48
  # @see #select!
57
- # @yield [name, value]
58
- # @yieldparam [Symbol] name
49
+ # @yield [autonym, value]
50
+ # @yieldparam [Symbol] autonym
59
51
  # @return [Enumerator]
60
52
  def keep_if(&block)
61
53
  raise "can't modify frozen #{self.class}" if frozen?
62
- return to_enum(__method__) unless block_given?
54
+ return to_enum(__callee__) unless block_given?
55
+
63
56
  select!(&block)
64
57
  self
65
58
  end
66
59
 
67
60
  # @see #select!
68
61
  # keep falsy only (unassign truthy member)
69
- # @yield [name, value]
70
- # @yieldparam [Symbol] name
62
+ # @yield [autonym, value]
63
+ # @yieldparam [Symbol] autonym
71
64
  # @return [Enumerator]
72
65
  def reject!
73
66
  raise "can't modify frozen #{self.class}" if frozen?
74
- return to_enum(__method__) unless block_given?
67
+ return to_enum(__callee__) unless block_given?
75
68
 
76
69
  modified = false
77
- each_pair do |name, value|
78
- if yield name, value
79
- unassign name
70
+ each_pair do |autonym, value|
71
+ if yield autonym, value
72
+ unassign autonym
80
73
  modified = true
81
74
  end
82
75
  end
@@ -85,28 +78,28 @@ class Striuct; module InstanceMethods
85
78
  end
86
79
 
87
80
  # @see #reject!
88
- # @yield [name, value]
89
- # @yieldparam [Symbol] name
81
+ # @yield [autonym, value]
82
+ # @yieldparam [Symbol] autonym
90
83
  # @return [Enumerator]
91
84
  def delete_if(&block)
92
85
  raise "can't modify frozen #{self.class}" if frozen?
93
- return to_enum(__method__) unless block_given?
86
+ return to_enum(__callee__) unless block_given?
94
87
 
95
88
  reject!(&block)
96
89
  self
97
90
  end
98
91
 
99
92
  # @param [Symbol, String] name
100
- # @return [Array] e.g [name, value]
93
+ # @return [Array] e.g [autonym, value]
101
94
  def assoc(name)
102
- name = autonym_for name
95
+ autonym = autonym_for name
103
96
 
104
- [name, self[name]]
97
+ [autonym, self[name]]
105
98
  end
106
99
 
107
- # @return [Array] [name, value]
100
+ # @return [Array] [autonym, value]
108
101
  def rassoc(value)
109
- each_pair.find{|pair|pair[1] == value}
102
+ each_pair.find{|_, val|val == value}
110
103
  end
111
104
 
112
105
  # @see Hash#flatten
@@ -116,24 +109,25 @@ class Striuct; module InstanceMethods
116
109
  end
117
110
 
118
111
  # @see #select!
119
- # @yield [name, value]
120
- # @yieldparam [Symbol] name
112
+ # @yield [autonym, value]
113
+ # @yieldparam [Symbol] autonym
121
114
  # @return [Striuct]
122
115
  def select(&block)
123
- return to_enum(__method__) unless block_given?
116
+ return to_enum(__callee__) unless block_given?
124
117
 
125
118
  dup.tap {|r|r.select!(&block)}
126
119
  end
127
120
 
128
121
  # @see #reject!
129
- # @yield [name, value]
130
- # @yieldparam [Symbol] name
122
+ # @yield [autonym, value]
123
+ # @yieldparam [Symbol] autonym
131
124
  # @return [Striuct]
132
125
  def reject(&block)
133
- return to_enum(__method__) unless block_given?
126
+ return to_enum(__callee__) unless block_given?
134
127
 
135
128
  dup.tap {|r|r.reject!(&block)}
136
129
  end
137
130
 
138
131
  # @endgroup
132
+
139
133
  end; end