deferred_enum 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in deferred_enum.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'rspec'
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Alexey Mikhaylov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ == Synopsys
2
+ Ruby Enumerable extension. Main idea is lazy computations within enumerators.
3
+
4
+ == Usage
5
+ Install as a gem:
6
+ sudo gem install deferred_enum
7
+
8
+ This gem introduces DeferredEnumerator class:
9
+ ary = [1, 2, 3, 4]
10
+ deferred = ary.defer # #<DeferredEnumerator: [1, 2, 3, 4]:each>
11
+
12
+ DeferredEnumerator brings some optimizations to all?, any? and none? predicates
13
+ deferred.all?(&:even?) # Will stop iteration after first false-result = 1 iteration
14
+ deferred.none?(&:even?) # 2 iterations
15
+ deferred.any?(&:even?) # 2 iterations
16
+
17
+ It also introduces lazy versions of Enumerable's #select, #map and #reject methods
18
+ deferred.map { |i| i + 1 } # #<DeferredEnumerator: #<Enumerator::Generator>:each>
19
+ deferred.select { |i| i.even? } # #<DeferredEnumerator: #<Enumerator::Generator>:each>
20
+ deferred.reject { |i| i.odd? } # #<DeferredEnumerator: #<Enumerator::Generator>:each>
21
+
22
+ So you can safely chain your filters, they won't be treated as arrays:
23
+ deferred.map(&:succ).select(&:even?) # #<DeferredEnumerator: #<Enumerator::Generator>:each>
24
+
25
+ You can build chains of Enumerables:
26
+ deferred.concat([2]).to_a # [1, 2, 3, 4, 2]
27
+
28
+ Or append elements to the end of enumerator:
29
+ deferred << 2
30
+
31
+ You can even remove duplicates from enumerator, though this operation can be tough:
32
+ deferred.uniq # #<DeferredEnumerator: #<Enumerator::Generator>:each>
33
+
34
+ There are many other methods in DeferredEnumerator, please refer to documentation.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "deferred_enum/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "deferred_enum"
7
+ s.version = DeferredEnum::VERSION
8
+ s.authors = ["Alexey Mikhaylov"]
9
+ s.email = ["amikhailov83@gmail.com"]
10
+ s.homepage = "https://github.com/take-five/deferred_enum"
11
+ s.summary = %q{Introduces lazy computations to Enumerable}
12
+ s.description = File.read(File.expand_path('../README.rdoc', __FILE__))
13
+ s.date = Time.now.strftime('%Y-%m-%d')
14
+
15
+ s.rubyforge_project = "deferred_enum"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1 @@
1
+ require "deferred_enumerable"
@@ -0,0 +1,5 @@
1
+ module Enumerable
2
+ def defer(method_id = :each)
3
+ DeferredEnumerator.new(self, method_id)
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module DeferredEnum
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,267 @@
1
+ module DeferredEnumerable
2
+ include Enumerable
3
+
4
+ # Passes each element of the collection to the given block.
5
+ # The method returns true if the block never returns false or nil.
6
+ def all?(&blk) # :yields: obj
7
+ blk ||= proc { |e| e }
8
+ each { |entry| return false unless blk.call(entry) }
9
+ true
10
+ end
11
+
12
+ # Passes each element of the collection to the given block.
13
+ # The method returns true if the block ever returns a value other than false or nil.
14
+ def any?(&blk) # :yields: obj
15
+ blk ||= proc { |e| e }
16
+ each { |entry| return true if blk.call(entry) }
17
+ false
18
+ end
19
+
20
+ # Passes each element of the collection to the given block.
21
+ # The method returns true if the block never returns true for all elements.
22
+ # If the block is not given, none? will return true only if none of the collection members is true.
23
+ def none?(&blk)
24
+ blk ||= proc { |e| e }
25
+ each { |entry| return false if blk.call(entry) }
26
+ true
27
+ end
28
+
29
+ # Returns a new enumerator with the results of running block once for every element in enum.
30
+ def collect # :yields: obj
31
+ return self unless block_given?
32
+
33
+ DeferredEnumerator.new do |yielder|
34
+ each { |entry| yielder << yield(entry) }
35
+ end
36
+ end
37
+ alias map collect
38
+
39
+ # Returns a enumerator containing all elements of enum for which block is not false
40
+ def select # :yields: obj
41
+ return self unless block_given?
42
+
43
+ DeferredEnumerator.new do |yielder|
44
+ each { |entry| yielder << entry if yield(entry) }
45
+ end
46
+ end
47
+ alias find_all select
48
+
49
+ # Returns a enumerator containing all elements of enum for which block is false
50
+ def reject # :yields: obj
51
+ return self unless block_given?
52
+
53
+ DeferredEnumerator.new do |yielder|
54
+ each { |entry| yielder << entry unless yield(entry) }
55
+ end
56
+ end
57
+
58
+ # Returns a new enumerator that is a one-dimensional flattening of this enumerator (recursively).
59
+ # That is, for every element that is an Enumerable, extract its elements into the new enumerator.
60
+ # If the optional level argument determines the level of recursion to flatten.
61
+ def flatten(level = nil)
62
+ do_recursion, next_level = if level.is_a?(Fixnum)
63
+ [level > 0, level - 1]
64
+ else
65
+ [true, nil]
66
+ end
67
+
68
+ DeferredEnumerator.new do |yielder|
69
+ each do |entry|
70
+ if entry.is_a?(Enumerable) && do_recursion
71
+ entry.defer.flatten(next_level).each { |nested| yielder << nested }
72
+ else
73
+ yielder << entry
74
+ end
75
+ end
76
+ end # Enumerator.new
77
+ end # def flatten
78
+
79
+ # Returns a new enumerator with the concatenated results of running block once for every element in enum.
80
+ def flat_map(&blk) # :yields: obj
81
+ return flatten unless block_given?
82
+
83
+ flatten.collect(&blk)
84
+ end
85
+ alias collect_concat flat_map
86
+
87
+ # Calls block for each element of enum repeatedly n times or forever if none or nil is given.
88
+ # If a non-positive number is given or the collection is empty, does nothing.
89
+ # Returns nil if the loop has finished without getting interrupted.
90
+ #
91
+ # Unlike <tt>Enumerable#cycle</tt> <tt>DeferredEnumerable#cycle</tt> DOES NOT save elements in an internal array.
92
+ #
93
+ # If no block is given, an enumerator is returned instead.
94
+ def cycle(n = nil) # :yields: obj
95
+ cycles_num = n.is_a?(Fixnum) ? n : nil
96
+
97
+ enum = DeferredEnumerator.new do |yielder|
98
+ while cycles_num.nil? || cycles_num > 0
99
+ each { |entry| yielder << entry }
100
+
101
+ cycles_num -= 1 if cycles_num
102
+ end
103
+ end
104
+
105
+ unless block_given?
106
+ enum
107
+ else
108
+ enum.each { |e| yield(e) }
109
+
110
+ nil
111
+ end
112
+ end
113
+
114
+ # Drops first n elements from enum, and returns rest elements in an enumerator.
115
+ def drop(n)
116
+ raise TypeError, 'Integer (> 0) expected' unless n.is_a?(Fixnum) && n > 0
117
+
118
+ DeferredEnumerator.new do |yielder|
119
+ each { |entry| yielder << entry if (n -= 1) < 0}
120
+ end
121
+ end
122
+
123
+ # Returns first n elements from enum.
124
+ def take(n)
125
+ raise TypeError, 'Integer (> 0) expected' unless n.is_a?(Fixnum) && n > 0
126
+
127
+ DeferredEnumerator.new do |yielder|
128
+ each { |entry| yielder << entry if (n -= 1) >= 0}
129
+ end
130
+ end
131
+
132
+ # Drops elements up to, but not including, the first element for which the block returns nil
133
+ # or false and returns an enumerator containing the remaining elements.
134
+ def drop_while # :yields: obj
135
+ return self unless block_given?
136
+
137
+ DeferredEnumerator.new do |yielder|
138
+ keep = false
139
+ each do |entry|
140
+ keep ||= !yield(entry)
141
+
142
+ yielder << entry if keep
143
+ end
144
+ end
145
+ end
146
+
147
+ # Passes elements to the block until the block returns <code>nil</code> or <code>false</code>,
148
+ # then stops iterating and returns an enumerator of all prior elements.
149
+ def take_while # :yields: obj
150
+ return self unless block_given?
151
+
152
+ DeferredEnumerator.new do |yielder|
153
+ each do |entry|
154
+ break unless yield(entry)
155
+
156
+ yielder << entry
157
+ end
158
+ end
159
+ end
160
+
161
+ # Returns an array of every element in enum for which <code>Pattern === element</code>.
162
+ # If the optional <code>block</code> is supplied, each matching element is passed to it,
163
+ # and the block's result is stored in the output array.
164
+ def grep(pattern, &blk) # :yields: obj
165
+ filtered = select { |obj| pattern === obj }
166
+
167
+ block_given? ?
168
+ filtered.collect(&blk) :
169
+ filtered
170
+ end
171
+
172
+ # Returns <code>true</code> if any member of <code>enum</code> equals <code>obj</code>.
173
+ # Equality is tested using <code>==</code>.
174
+ def include?(obj) # :yields: obj
175
+ any? { |e| obj == e }
176
+ end
177
+ alias member? include?
178
+
179
+ # Returns two enums, the first containing the elements of enum for which the block evaluates to true, the second containing the rest.
180
+ def partition # :yields: obj
181
+ super.map(&:defer)
182
+ end
183
+
184
+ # Returns an enumerator containing the items in enum sorted,
185
+ # either according to their own <=> method,
186
+ # or by using the results of the supplied block.
187
+ def sort
188
+ super.defer
189
+ end
190
+
191
+ # Sorts enum using a set of keys generated by mapping the values in enum through the given block.
192
+ def sort_by
193
+ super.defer
194
+ end
195
+
196
+ # Takes one element from <i>enum</i> and merges corresponding
197
+ # elements from each <i>enumerables</i>. This generates a sequence of
198
+ # <em>n</em>-element arrays, where <em>n</em> is one more than the
199
+ # count of arguments. The length of the resulting sequence will be
200
+ # <code>enum#size</code>. If the size of any argument is less than
201
+ # <code>enum#size</code>, <code>nil</code> values are supplied. If
202
+ # a block is given, it is invoked for each output array, otherwise
203
+ # an enumerator of arrays is returned.
204
+ def zip(*enumerables)
205
+ return super if block_given?
206
+
207
+ raise TypeError, 'Zip accepts only enumerables' unless enumerables.all? { |e| e.is_a?(Enumerable) }
208
+
209
+ deferred = enumerables.map(&:defer)
210
+
211
+ DeferredEnumerator.new do |yielder|
212
+ each do |entry|
213
+ ary = [entry]
214
+
215
+ deferred.each do |enum|
216
+ ary << begin
217
+ enum.next
218
+ rescue StopIteration
219
+ nil
220
+ end
221
+ end
222
+
223
+ yielder << ary
224
+ end
225
+ end
226
+ end
227
+
228
+ # Returns a enumerator with all nil elements removed.
229
+ def compact
230
+ reject(&:nil?)
231
+ end
232
+
233
+ # Appends the <code>enumerables</code> to self.
234
+ def concat(*enumerables)
235
+ raise TypeError, 'DeferredEnumerabler#concat accepts only enumerables' unless enumerables.all? { |e| e.is_a?(Enumerable) }
236
+
237
+ DeferredEnumerator.new do |yielder|
238
+ [self, *enumerables].each do |enum|
239
+ enum.each { |entry| yielder << entry }
240
+ end
241
+ end
242
+ end
243
+ alias chain concat
244
+ alias + concat
245
+
246
+ # Appends the <code>element</code> to end of enumerator
247
+ def push(element)
248
+ concat([element])
249
+ end
250
+ alias << push
251
+
252
+ # Returns a new enumerator by removing duplicate values in self.
253
+ def uniq
254
+ values = {}
255
+
256
+ select { |entry|
257
+ value = block_given? ? yield(entry) : entry
258
+
259
+ unless values.has_key?(value)
260
+ values.store(value, true)
261
+ end
262
+ }
263
+ end
264
+ end
265
+
266
+ require "deferred_enumerator"
267
+ require "deferred_enum/enumerable"
@@ -0,0 +1,6 @@
1
+ require "deferred_enumerable"
2
+ require "deferred_enum/enumerable"
3
+
4
+ class DeferredEnumerator < Enumerator
5
+ include ::DeferredEnumerable
6
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Enumerable do
4
+ it "should have defer method" do
5
+ ary = []
6
+ ary.should respond_to(:defer)
7
+ end
8
+
9
+ it "should return DeferredEnumerable" do
10
+ [].defer.should be_a(DeferredEnumerable)
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe DeferredEnumerator do
4
+ it "should drop elements from collections" do
5
+ [1, 2, 3, 4, 3].defer.drop(3).to_a.should == [4, 3]
6
+
7
+ [1, 2, 3, 4, 3].defer.drop_while {|n| n <= 3 }.to_a.should == [4, 3]
8
+ end
9
+
10
+ it "should take first elements from collections" do
11
+ [4, 3, 2, 1, 4].defer.take(3).to_a.should == [4, 3, 2]
12
+
13
+ [4, 3, 2, 1, 4].defer.take_while { |n| n > 1 }.to_a.should == [4, 3, 2]
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe DeferredEnumerator do
4
+ it "should map collections" do
5
+ [1, 2, 3].defer.map { |i| i + 1 }.to_a.should == [2, 3, 4]
6
+ end
7
+
8
+ it "should filter collections" do
9
+ [1, 2, 3].defer.select { |i| i.odd? }.to_a.should == [1, 3]
10
+ end
11
+
12
+ it "should reject elements from collections" do
13
+ [1, 2, 3].defer.reject { |i| i.odd? }.to_a.should == [2]
14
+ end
15
+
16
+ it "should flatten collections" do
17
+ [[1, 2], 3, [4]].defer.flatten.to_a.should == [1, 2, 3, 4]
18
+
19
+ [[1, [2]], 3].defer.flatten(1).to_a.should == [1, [2], 3]
20
+ end
21
+
22
+ it "should flat and map collections" do
23
+ [[1, 2], 3, [4]].defer.flat_map { |i| i + 1 }.to_a.should == [2, 3, 4, 5]
24
+ end
25
+
26
+ it "should cycle collections" do
27
+ [1].defer.cycle(2).to_a.should == [1, 1]
28
+
29
+ counts = 0
30
+ [1].defer.cycle { counts += 1; break if counts == 10 }
31
+ counts.should == 10
32
+ end
33
+
34
+ it "should grep collections" do
35
+ ['abc', 'def', 'ghi'].defer.grep(/abc/).to_a.should == ['abc']
36
+ end
37
+
38
+ it "should compact collections" do
39
+ [1, 2, nil].defer.compact.to_a.should == [1, 2]
40
+ end
41
+
42
+ it "should chain collections" do
43
+ [1, 2].defer.chain([3], [], [4]).to_a.should == [1, 2, 3, 4]
44
+ end
45
+
46
+ it "should remove duplicates from collections" do
47
+ [1, 2, 3, 4, 3, 4].defer.uniq.to_a.should == [1, 2, 3, 4]
48
+
49
+ [1, 2, 3, 4].defer.uniq { |n| n.even? }.to_a.should == [1, 2]
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe DeferredEnumerator do
4
+ it "should lazily execute all? method" do
5
+ counts = 0
6
+
7
+ [2, 3, 4].all? { |e| counts += 1; e.even? }.should == false
8
+ counts.should == 2
9
+ end
10
+
11
+ it "should lazily execute any? method" do
12
+ counts = 0
13
+
14
+ [2, 3, 4].any? { |e| counts += 1; e.odd? }.should == true
15
+ counts.should == 2
16
+ end
17
+
18
+ it "should lazily execute none? method" do
19
+ counts = 0
20
+
21
+ [2, 3, 4].none? { |e| counts += 1; e.odd? }.should == false
22
+ counts.should == 2
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup
4
+
5
+ require "deferred_enum"
data/spec/zip_spec.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe DeferredEnumerator do
4
+ it "should zip collections" do
5
+ seq1 = [2, 3, 4]
6
+ seq2 = [3, 4]
7
+
8
+ [1, 2, 3].defer.zip(seq1, seq2).to_a.should == [[1, 2, 3], [2, 3, 4], [3, 4, nil]]
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deferred_enum
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Alexey Mikhaylov
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-12-11 00:00:00 +06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ description: |-
34
+ == Synopsys
35
+ Ruby Enumerable extension. Main idea is lazy computations within enumerators.
36
+
37
+ == Usage
38
+ Install as a gem:
39
+ sudo gem install deferred_enum
40
+
41
+ This gem introduces DeferredEnumerator class:
42
+ ary = [1, 2, 3, 4]
43
+ deferred = ary.defer # #<DeferredEnumerator: [1, 2, 3, 4]:each>
44
+
45
+ DeferredEnumerator brings some optimizations to all?, any? and none? predicates
46
+ deferred.all?(&:even?) # Will stop iteration after first false-result = 1 iteration
47
+ deferred.none?(&:even?) # 2 iterations
48
+ deferred.any?(&:even?) # 2 iterations
49
+
50
+ It also introduces lazy versions of Enumerable's #select, #map and #reject methods
51
+ deferred.map { |i| i + 1 } # #<DeferredEnumerator: #<Enumerator::Generator>:each>
52
+ deferred.select { |i| i.even? } # #<DeferredEnumerator: #<Enumerator::Generator>:each>
53
+ deferred.reject { |i| i.odd? } # #<DeferredEnumerator: #<Enumerator::Generator>:each>
54
+
55
+ So you can safely chain your filters, they won't be treated as arrays:
56
+ deferred.map(&:succ).select(&:even?) # #<DeferredEnumerator: #<Enumerator::Generator>:each>
57
+
58
+ You can build chains of Enumerables:
59
+ deferred.concat([2]).to_a # [1, 2, 3, 4, 2]
60
+
61
+ Or append elements to the end of enumerator:
62
+ deferred << 2
63
+
64
+ You can even remove duplicates from enumerator, though this operation can be tough:
65
+ deferred.uniq # #<DeferredEnumerator: #<Enumerator::Generator>:each>
66
+
67
+ There are many other methods in DeferredEnumerator, please refer to documentation.
68
+ email:
69
+ - amikhailov83@gmail.com
70
+ executables: []
71
+
72
+ extensions: []
73
+
74
+ extra_rdoc_files: []
75
+
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.rdoc
81
+ - Rakefile
82
+ - deferred_enum.gemspec
83
+ - lib/deferred_enum.rb
84
+ - lib/deferred_enum/enumerable.rb
85
+ - lib/deferred_enum/version.rb
86
+ - lib/deferred_enumerable.rb
87
+ - lib/deferred_enumerator.rb
88
+ - spec/defer_spec.rb
89
+ - spec/drop_take_spec.rb
90
+ - spec/map_select_spec.rb
91
+ - spec/predicates_spec.rb
92
+ - spec/test_helper.rb
93
+ - spec/zip_spec.rb
94
+ has_rdoc: true
95
+ homepage: https://github.com/take-five/deferred_enum
96
+ licenses: []
97
+
98
+ post_install_message:
99
+ rdoc_options: []
100
+
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ requirements: []
120
+
121
+ rubyforge_project: deferred_enum
122
+ rubygems_version: 1.3.7
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Introduces lazy computations to Enumerable
126
+ test_files: []
127
+