pretty_ruby 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.
- checksums.yaml +7 -0
- data/lib/pretty_ruby.rb +286 -0
- metadata +44 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: da280c9e01ed54b9551ec457bba0cf67dc8cb8641fe40818ec06a4e769169b51
|
4
|
+
data.tar.gz: 9a515a6958ce87c06084b3372d5ffdc4ea1d307f6b95b86a937e87d366e66584
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 560699e08e3c3f211eab15af1be03029e9ff4776cdb86d4b11c37e39973fe69fa20a055582183fd7b29f1e9b5564d3ad8732c0399c62db4d3635f342c2649aea
|
7
|
+
data.tar.gz: c53be4b9eb4efea964e20df15e64345171477e4f90045e203109a110ed4dcbf0d9fb4501dfea5df0d70fcbe49e4b9415b3feda4f317d41d64e70f9b497250887
|
data/lib/pretty_ruby.rb
ADDED
@@ -0,0 +1,286 @@
|
|
1
|
+
# :count,
|
2
|
+
# :detect,
|
3
|
+
# :find_index,
|
4
|
+
# :find_all,
|
5
|
+
# :select,
|
6
|
+
# :reject,
|
7
|
+
# :collect,
|
8
|
+
# :map,
|
9
|
+
# :flat_map,
|
10
|
+
# :collect_concat,
|
11
|
+
# :inject,
|
12
|
+
# :reduce,
|
13
|
+
# :partition,
|
14
|
+
# :group_by,
|
15
|
+
# :first,
|
16
|
+
# :all?,
|
17
|
+
# :any?,
|
18
|
+
# :one?,
|
19
|
+
# :none?,
|
20
|
+
# :minmax,
|
21
|
+
# :minmax_by,
|
22
|
+
# :member?,
|
23
|
+
# :each_with_index,
|
24
|
+
# :reverse_each,
|
25
|
+
# :each_entry,
|
26
|
+
# :each_slice,
|
27
|
+
# :each_cons,
|
28
|
+
# :each_with_object,
|
29
|
+
# :zip,
|
30
|
+
# :take,
|
31
|
+
# :take_while,
|
32
|
+
# :drop,
|
33
|
+
# :drop_while,
|
34
|
+
# :cycle,
|
35
|
+
# :chunk,
|
36
|
+
# :slice_before,
|
37
|
+
# :slice_after,
|
38
|
+
# :slice_when,
|
39
|
+
# :chunk_while,
|
40
|
+
# :sum,
|
41
|
+
# :uniq]
|
42
|
+
|
43
|
+
module PrettyRuby
|
44
|
+
|
45
|
+
|
46
|
+
refine Numeric do
|
47
|
+
def max(other)
|
48
|
+
self >= other ? self : other
|
49
|
+
end
|
50
|
+
|
51
|
+
def min(other)
|
52
|
+
self <= other ? self : other
|
53
|
+
end
|
54
|
+
|
55
|
+
def squared
|
56
|
+
self * self
|
57
|
+
end
|
58
|
+
|
59
|
+
def doubled
|
60
|
+
2 * self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
refine Symbol do
|
65
|
+
def >>(next_proc)
|
66
|
+
->(x) { next_proc.to_proc.(self.to_proc.(x)) }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Need to redefine here so it picks up the other refinements
|
70
|
+
# They don't retroactively bubble up inheritance chains.
|
71
|
+
# Eg, `scan(:max)` requires that Numeric has our refined `max` method
|
72
|
+
#
|
73
|
+
def to_proc
|
74
|
+
->(*args, &blk) do
|
75
|
+
receiver = args.first
|
76
|
+
if (blk)
|
77
|
+
receiver.send(self, &blk)
|
78
|
+
else
|
79
|
+
args[0] = self
|
80
|
+
receiver.send(*args)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
refine Proc do
|
87
|
+
def >>(next_proc)
|
88
|
+
->(x) { next_proc.to_proc.(self.(x)) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
refine Array do
|
93
|
+
|
94
|
+
# TODO: avoid duplication with Enumerable?
|
95
|
+
def to_proc
|
96
|
+
fn = first.to_proc
|
97
|
+
args = drop(1)
|
98
|
+
# TODO: document better
|
99
|
+
# handles stuff like
|
100
|
+
# maxs = cols.map([:map, :to_s >> :size] >> :max)
|
101
|
+
if args.first.is_a?(Proc)
|
102
|
+
->(x) { fn.(x, &args.first) }
|
103
|
+
else
|
104
|
+
->(x) { fn.(x, *args) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def drop(n)
|
109
|
+
n >= 0 ? super(n) : take([0, size+n].max)
|
110
|
+
end
|
111
|
+
|
112
|
+
def take(n)
|
113
|
+
n >= 0 ? super(n) : drop([0, size+n].max)
|
114
|
+
end
|
115
|
+
|
116
|
+
def >>(other)
|
117
|
+
->(x) { other.to_proc.(to_proc.(x)) }
|
118
|
+
end
|
119
|
+
|
120
|
+
# def to_proc
|
121
|
+
# ArrayWithToProc.new(self).to_proc
|
122
|
+
# end
|
123
|
+
|
124
|
+
# Because Array has a custom implementation of map, instead of just mixing
|
125
|
+
# in Enumerable, we need to refine its map separately, even though we use
|
126
|
+
# the same code.
|
127
|
+
#
|
128
|
+
def map(*args, &blk)
|
129
|
+
blk = blk ? blk : args.to_proc
|
130
|
+
super(&blk)
|
131
|
+
end
|
132
|
+
|
133
|
+
def tail
|
134
|
+
drop(1)
|
135
|
+
end
|
136
|
+
|
137
|
+
def init
|
138
|
+
drop(-1)
|
139
|
+
end
|
140
|
+
|
141
|
+
# TODO: reduce in place
|
142
|
+
#
|
143
|
+
def right_reduce(init = nil, sym = nil, &blk)
|
144
|
+
reverse.reduce(init, sym, &blk)
|
145
|
+
end
|
146
|
+
|
147
|
+
# TODO: make in place
|
148
|
+
#
|
149
|
+
def rscan(fn = nil, &blk)
|
150
|
+
reverse.scan(fn, &blk)
|
151
|
+
end
|
152
|
+
|
153
|
+
def scan(fn = nil, &blk)
|
154
|
+
no_args = !fn && !blk
|
155
|
+
return partial_seqs if no_args
|
156
|
+
blk = fn ? fn.to_proc : blk
|
157
|
+
self.drop(1).reduce([self.first]) do |m, x|
|
158
|
+
m << blk.(m.last, x)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def nesting_level
|
163
|
+
0.step.find { |n| flatten(n).none?(Array) }
|
164
|
+
end
|
165
|
+
|
166
|
+
class NDimMatrix < Array
|
167
|
+
|
168
|
+
module PrivateArray
|
169
|
+
refine Array do
|
170
|
+
using PrettyRuby
|
171
|
+
|
172
|
+
def aligned_cols(col_maxs)
|
173
|
+
nesting_level == 1 ?
|
174
|
+
aligned_cols_2d(col_maxs) :
|
175
|
+
map{ |x| x.aligned_cols(col_maxs) }
|
176
|
+
end
|
177
|
+
|
178
|
+
def aligned_cols_2d(col_widths)
|
179
|
+
transpose.zip(col_widths).map do |col, width|
|
180
|
+
col.map{ |x| sprintf("%#{width}s", x) }
|
181
|
+
end.transpose
|
182
|
+
end
|
183
|
+
|
184
|
+
def joined_records(nesting)
|
185
|
+
nesting == 0 ?
|
186
|
+
join(' ') :
|
187
|
+
map{ |x| x.joined_records(nesting - 1) }.join("\n" * nesting)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
using PrivateArray
|
193
|
+
|
194
|
+
def to_s
|
195
|
+
nest_lev = nesting_level
|
196
|
+
matrix_2d = flatten(nest_lev - 1)
|
197
|
+
cols = matrix_2d.transpose
|
198
|
+
col_maxs = cols.map([:map, :to_s >> :size] >> :max)
|
199
|
+
aligned_cols(col_maxs)
|
200
|
+
.joined_records(nest_lev)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def formatted_matrix
|
205
|
+
# make ordinary arrays work without special casing them
|
206
|
+
#
|
207
|
+
matrix = nesting_level > 0 ? self : [self]
|
208
|
+
NDimMatrix.new(matrix).to_s
|
209
|
+
end
|
210
|
+
|
211
|
+
private
|
212
|
+
|
213
|
+
def partial_seqs
|
214
|
+
self.drop(1).reduce([[self.first]]) do |m, x|
|
215
|
+
m << m.last + [x]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
#TODO: add separate tests for this
|
222
|
+
refine ::Enumerable do
|
223
|
+
|
224
|
+
def to_proc
|
225
|
+
fn = first.to_proc
|
226
|
+
args = drop(1)
|
227
|
+
# TODO: document better
|
228
|
+
# handles stuff like
|
229
|
+
# maxs = cols.map([:map, :to_s >> :size] >> :max)
|
230
|
+
if args.first.is_a?(Proc)
|
231
|
+
->(x) { fn.(x, &args.first) }
|
232
|
+
else
|
233
|
+
->(x) { fn.(x, *args) }
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def map(*args, &blk)
|
238
|
+
return super unless args_given?(args, blk)
|
239
|
+
super(&smart_block(args, blk))
|
240
|
+
end
|
241
|
+
|
242
|
+
def max_by(*args, &blk)
|
243
|
+
return super unless args_given?(args, blk)
|
244
|
+
return super(args.first, &blk) if n_given?(args)
|
245
|
+
super(&smart_block(args, blk))
|
246
|
+
end
|
247
|
+
|
248
|
+
def min_by(*args, &blk)
|
249
|
+
return super unless args_given?(args, blk)
|
250
|
+
return super(args.first, &blk) if n_given?(args)
|
251
|
+
super(&smart_block(args, blk))
|
252
|
+
end
|
253
|
+
|
254
|
+
def sort_by(*args, &blk)
|
255
|
+
return super unless args_given?(args, blk)
|
256
|
+
super(&smart_block(args, blk))
|
257
|
+
end
|
258
|
+
|
259
|
+
private
|
260
|
+
|
261
|
+
def args_given?(args, blk)
|
262
|
+
blk || !args.empty?
|
263
|
+
end
|
264
|
+
|
265
|
+
def n_given?(args)
|
266
|
+
args && args.first.is_a?(Integer)
|
267
|
+
end
|
268
|
+
|
269
|
+
def smart_block(args, blk)
|
270
|
+
blk ? blk : args.to_proc
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
refine TrueClass do
|
275
|
+
def to_i
|
276
|
+
1
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
refine FalseClass do
|
281
|
+
def to_i
|
282
|
+
0
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
metadata
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pretty_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonah Goldstein
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-23 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/pretty_ruby.rb
|
20
|
+
homepage: https://github.com/jonahx/pretty_ruby
|
21
|
+
licenses:
|
22
|
+
- MIT
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.7.6
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: Syntax improvements and other useful methods for ruby
|
44
|
+
test_files: []
|