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
@@ -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