fancy 0.6.0 → 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.
- data/LICENSE +1 -1
- data/README.md +4 -1
- data/Rakefile +0 -52
- data/bin/fspec +22 -12
- data/bin/ifancy +1 -1
- data/boot/fancy_ext/class.rb +1 -0
- data/boot/fancy_ext/object.rb +8 -6
- data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/parser.y +9 -0
- data/doc/api/fancy.jsonp +1 -1
- data/examples/stupid_quicksort.fy +11 -9
- data/lib/array.fy +26 -58
- data/lib/block.fy +0 -1
- data/lib/boot.fy +2 -2
- data/lib/class.fy +85 -0
- data/lib/compiler/ast/class_def.fy +1 -1
- data/lib/compiler/ast/expression_list.fy +4 -12
- data/lib/compiler/ast/identifier.fy +3 -3
- data/lib/compiler/ast/method_def.fy +3 -1
- data/lib/compiler/ast/singleton_method_def.fy +4 -1
- data/lib/contracts.fy +53 -56
- data/lib/dynamic_slot_object.fy +39 -3
- data/lib/enumerable.fy +144 -47
- data/lib/fancy_spec.fy +2 -6
- data/lib/file.fy +67 -0
- data/lib/future.fy +42 -3
- data/lib/hash.fy +35 -29
- data/lib/html.fy +1 -1
- data/lib/integer.fy +34 -0
- data/lib/main.fy +13 -7
- data/lib/message_sink.fy +1 -1
- data/lib/number.fy +10 -0
- data/lib/object.fy +27 -1
- data/lib/package.fy +2 -0
- data/lib/package/handler.fy +56 -0
- data/lib/package/installer.fy +21 -51
- data/lib/package/specification.fy +12 -5
- data/lib/package/uninstaller.fy +22 -3
- data/lib/parser/ext/parser.y +9 -0
- data/lib/proxy.fy +25 -2
- data/lib/rbx.fy +2 -1
- data/lib/rbx/array.fy +16 -1
- data/lib/rbx/class.fy +34 -9
- data/lib/rbx/file.fy +2 -2
- data/lib/rbx/fixnum.fy +1 -11
- data/lib/rbx/io.fy +4 -0
- data/lib/rbx/module.fy +11 -0
- data/lib/rbx/object.fy +12 -12
- data/lib/rbx/proc.fy +7 -0
- data/lib/rbx/string.fy +5 -1
- data/lib/rbx/symbol.fy +9 -0
- data/lib/string.fy +1 -1
- data/lib/tuple.fy +37 -35
- data/lib/version.fy +6 -5
- data/tests/array.fy +14 -2
- data/tests/class.fy +79 -0
- data/tests/dynamic_key_hash.fy +16 -0
- data/tests/dynamic_slot_object.fy +28 -0
- data/tests/dynamic_value_array.fy +12 -0
- data/tests/enumerable.fy +46 -0
- data/tests/file.fy +38 -0
- data/tests/fixnum.fy +22 -0
- data/tests/future.fy +40 -0
- data/tests/hash.fy +8 -7
- data/tests/object.fy +31 -5
- data/tests/set.fy +1 -1
- data/tests/string.fy +18 -2
- data/tests/tuple.fy +7 -0
- data/tools/fancy-mode.el +10 -0
- metadata +9 -12
- data/examples/99bottles.fy +0 -5
- data/examples/conditions_exceptions.fy +0 -9
- data/examples/conditions_parsing.fy +0 -68
- data/examples/dynamic.fy +0 -8
- data/examples/greeter.fy +0 -9
- data/examples/parsing.fy +0 -1
- data/lib/rbx/process.fy +0 -13
- data/lib/remote_object.fy +0 -59
data/tests/file.fy
CHANGED
@@ -102,4 +102,42 @@ FancySpec describe: File with: {
|
|
102
102
|
File directory?: "README" . is: false
|
103
103
|
File directory?: "src/bootstrap/Makefile" . is: false
|
104
104
|
}
|
105
|
+
|
106
|
+
it: "evals a file" with: 'eval: when: {
|
107
|
+
"/tmp/test_#{Time now to_i}.fy" tap: |filename| {
|
108
|
+
File tap: @{
|
109
|
+
write: filename with: @{ print: "2 * 3 to_s inspect" }
|
110
|
+
eval: filename . is: $ 6 to_s inspect
|
111
|
+
delete: filename
|
112
|
+
}
|
113
|
+
# File write: filename with: @{ print: "2 * 3 to_s inspect" }
|
114
|
+
# File eval: filename . is: $ 6 to_s inspect
|
115
|
+
# File delete: filename
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
it: "reads a config file" with: 'read_config: when: {
|
120
|
+
contents = """
|
121
|
+
{
|
122
|
+
test: 'value
|
123
|
+
other: 123
|
124
|
+
more: {
|
125
|
+
again: 'foo
|
126
|
+
yup: [1,2,3]
|
127
|
+
}
|
128
|
+
}
|
129
|
+
"""
|
130
|
+
|
131
|
+
filename = "/tmp/#{Time now to_i random}_fy_test.txt"
|
132
|
+
File write: filename with: @{ write: contents }
|
133
|
+
File read_config: filename . is: <[
|
134
|
+
'test => 'value,
|
135
|
+
'other => 123,
|
136
|
+
'more => <[
|
137
|
+
'again => 'foo,
|
138
|
+
'yup => [1,2,3]
|
139
|
+
]>
|
140
|
+
]>
|
141
|
+
File delete: filename
|
142
|
+
}
|
105
143
|
}
|
data/tests/fixnum.fy
CHANGED
@@ -117,4 +117,26 @@ FancySpec describe: Fixnum with: {
|
|
117
117
|
times_called is: 10
|
118
118
|
sum is: ((10..19) sum)
|
119
119
|
}
|
120
|
+
|
121
|
+
it: "tries to run a code block self amount of times or fails" with: 'try_times: when: {
|
122
|
+
{ -2 times_try: { 2 / 0 } } does_not raise: Exception
|
123
|
+
{ -1 times_try: { 2 / 0 } } does_not raise: Exception
|
124
|
+
{ 0 times_try: { 2 / 0 } } does_not raise: Exception
|
125
|
+
{ 1 times_try: { 2 / 0 } } raises: ZeroDivisionError
|
126
|
+
{ 2 times_try: { 2 / 0 } } raises: ZeroDivisionError
|
127
|
+
|
128
|
+
tries = 0
|
129
|
+
{
|
130
|
+
2 times_try: {
|
131
|
+
tries = tries + 1
|
132
|
+
2 / 0
|
133
|
+
}
|
134
|
+
} raises: ZeroDivisionError
|
135
|
+
tries is: 2
|
136
|
+
|
137
|
+
2 times_try: { 2 } . is: 2
|
138
|
+
|
139
|
+
i = 0
|
140
|
+
2 times_try: { 2 / i } retry_with: { i = 1 } . is: 2
|
141
|
+
}
|
120
142
|
}
|
data/tests/future.fy
CHANGED
@@ -53,4 +53,44 @@ FancySpec describe: FutureSend with: {
|
|
53
53
|
f failure message is: "error!"
|
54
54
|
f failed? is: true
|
55
55
|
}
|
56
|
+
|
57
|
+
it: "calls a block when done" with: 'when_done: when: {
|
58
|
+
called? = false
|
59
|
+
failed? = false
|
60
|
+
val = 0
|
61
|
+
f = { Thread sleep: 0.01; 2 } @ call
|
62
|
+
f when_done: |v| {
|
63
|
+
val = v
|
64
|
+
called? = true
|
65
|
+
}
|
66
|
+
f when_failed: |err| {
|
67
|
+
val = err
|
68
|
+
failed? = true
|
69
|
+
}
|
70
|
+
|
71
|
+
f value
|
72
|
+
called? is: true
|
73
|
+
val is: 2
|
74
|
+
}
|
75
|
+
|
76
|
+
it: "calls a block when failed" with: 'when_failed: when: {
|
77
|
+
called? = false
|
78
|
+
failed? = false
|
79
|
+
val = 0
|
80
|
+
f = { Thread sleep: 0.01; "Fail!" raise! } @ call
|
81
|
+
f when_done: |v| {
|
82
|
+
val = v
|
83
|
+
called? = true
|
84
|
+
}
|
85
|
+
f when_failed: |err| {
|
86
|
+
val = err
|
87
|
+
failed? = true
|
88
|
+
}
|
89
|
+
|
90
|
+
f value
|
91
|
+
called? is: false
|
92
|
+
failed? is: true
|
93
|
+
val message is: "Fail!"
|
94
|
+
val is_a?: Exception
|
95
|
+
}
|
56
96
|
}
|
data/tests/hash.fy
CHANGED
@@ -42,6 +42,14 @@ FancySpec describe: Hash with: {
|
|
42
42
|
hash at: 'foo1 else: { "hello" } . is: "hello"
|
43
43
|
}
|
44
44
|
|
45
|
+
it: "calls the block if it can't find the key and inserts the return value" with: 'at:else_put: when: {
|
46
|
+
hash = <['foo => "bar", 'bar => nil]>
|
47
|
+
hash at: 'foo else_put: { "hello" } . is: "bar"
|
48
|
+
hash at: 'bar else_put: { "hello" } . is: nil
|
49
|
+
hash at: 'foo1 else_put: { "hello" } . is: "hello"
|
50
|
+
hash['foo1] is: "hello"
|
51
|
+
}
|
52
|
+
|
45
53
|
it: "returns all keys" with: 'keys when: {
|
46
54
|
hash = <['foo => "bar", 'bar => "baz", 'foobar => 112.21]>
|
47
55
|
hash keys is =? ['foo, 'bar, 'foobar]
|
@@ -123,13 +131,6 @@ FancySpec describe: Hash with: {
|
|
123
131
|
h includes?: nil . is: false
|
124
132
|
}
|
125
133
|
|
126
|
-
it: "fetches a value or calls a given alternative block" for: 'fetch:else: when: {
|
127
|
-
<['foo => 'bar]> fetch: 'foo else: { 42 } . is: 'bar
|
128
|
-
<['foo => 'bar]> fetch: 'unknown else: { 42 } . is: 42
|
129
|
-
<['nil => nil]> fetch: 'nil else: { 'not_found } . is: nil
|
130
|
-
<['nila => nil]> fetch: 'nil else: { 'not_found } . is: 'not_found
|
131
|
-
}
|
132
|
-
|
133
134
|
it: "returns an object with slots based on key-value pairs in Hash" for: 'to_object when: {
|
134
135
|
<[]> to_object slots empty? is: true
|
135
136
|
<['name => "Chris"]> to_object tap: @{
|
data/tests/object.fy
CHANGED
@@ -171,9 +171,7 @@ FancySpec describe: Object with: {
|
|
171
171
|
}
|
172
172
|
MyClass new do_wacky_things is: false
|
173
173
|
|
174
|
-
{
|
175
|
-
true is: false
|
176
|
-
} call_with_receiver: (MyClass new)
|
174
|
+
@{ true is: false } call: [MyClass new]
|
177
175
|
}
|
178
176
|
|
179
177
|
it: "overrides nil" with: 'nil when: {
|
@@ -183,7 +181,7 @@ FancySpec describe: Object with: {
|
|
183
181
|
}
|
184
182
|
}
|
185
183
|
|
186
|
-
{ nil is: true }
|
184
|
+
@{ nil is: true } call: [MyClass new]
|
187
185
|
}
|
188
186
|
|
189
187
|
it: "overrides false" with: 'false when: {
|
@@ -193,7 +191,7 @@ FancySpec describe: Object with: {
|
|
193
191
|
}
|
194
192
|
}
|
195
193
|
|
196
|
-
{ false is: true }
|
194
|
+
@{ false is: true } call: [MyClass2 new]
|
197
195
|
}
|
198
196
|
|
199
197
|
it: "implicitly sends a message to self if no receiver is specified" when: {
|
@@ -278,4 +276,32 @@ FancySpec describe: Object with: {
|
|
278
276
|
bar: [1,2,3] values: v . is: 1
|
279
277
|
v is: [1]
|
280
278
|
}
|
279
|
+
|
280
|
+
it: "provides temporarily mutable slots" with: 'with_mutable_slots: when: {
|
281
|
+
class Student {
|
282
|
+
read_slots: ('name, 'age, 'city)
|
283
|
+
def initialize: block {
|
284
|
+
with_mutable_slots: ('name, 'age, 'city) do: block
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
p = Student new: @{
|
289
|
+
name: "Chris"
|
290
|
+
age: 24
|
291
|
+
city: "Osnabrück"
|
292
|
+
}
|
293
|
+
|
294
|
+
p name is: "Chris"
|
295
|
+
p age is: 24
|
296
|
+
p city is: "Osnabrück"
|
297
|
+
|
298
|
+
{ p name: "New Name" } raises: NoMethodError
|
299
|
+
{ p age: 25 } raises: NoMethodError
|
300
|
+
{ p city: "New City" } raises: NoMethodError
|
301
|
+
|
302
|
+
# no changes
|
303
|
+
p name is: "Chris"
|
304
|
+
p age is: 24
|
305
|
+
p city is: "Osnabrück"
|
306
|
+
}
|
281
307
|
}
|
data/tests/set.fy
CHANGED
data/tests/string.fy
CHANGED
@@ -41,9 +41,9 @@ FancySpec describe: String with: {
|
|
41
41
|
}
|
42
42
|
}
|
43
43
|
|
44
|
-
it: "behaves like a collection/sequence via each:" with: '
|
44
|
+
it: "behaves like a collection/sequence via each:" with: 'unique when: {
|
45
45
|
str = "Hello, World!"
|
46
|
-
str
|
46
|
+
str unique join: "" . is: "Helo, Wrd!"
|
47
47
|
}
|
48
48
|
|
49
49
|
it: "has all its characters as instances of String class" with: 'all?: when: {
|
@@ -126,6 +126,22 @@ FancySpec describe: String with: {
|
|
126
126
|
s is: "Good day. Hello."
|
127
127
|
}
|
128
128
|
|
129
|
+
it: "returns the character at a given index" with: '[] when: {
|
130
|
+
s = "hello"
|
131
|
+
s[0] is: "h"
|
132
|
+
s[1] is: "e"
|
133
|
+
s[2] is: "l"
|
134
|
+
s[3] is: "l"
|
135
|
+
s[4] is: "o"
|
136
|
+
# out of bounds yields nil:
|
137
|
+
s[5] is: nil
|
138
|
+
s[s size] is: nil
|
139
|
+
s[s size + 1] is: nil
|
140
|
+
"" at: 0 . is: nil
|
141
|
+
"" at: 1 . is: nil
|
142
|
+
"" at: -1 . is: nil
|
143
|
+
}
|
144
|
+
|
129
145
|
it: "contains a substring" with: 'includes?: when: {
|
130
146
|
"foo bar baz" includes?: "foo" . is: true
|
131
147
|
"foo bar baz" includes?: "bar" . is: true
|
data/tests/tuple.fy
CHANGED
@@ -65,4 +65,11 @@ FancySpec describe: Tuple with: {
|
|
65
65
|
sum is: 6
|
66
66
|
vals is: [3,2,1]
|
67
67
|
}
|
68
|
+
|
69
|
+
it: "returns an array of all elements between two indices" with: 'from:to: when: {
|
70
|
+
(1,2) from: 2 to: 3 . is: []
|
71
|
+
(1,2,3) from: 0 to: 2 . is: [1,2,3]
|
72
|
+
(4,5,6,7,8,9) from: 3 to: 5 . is: [7,8,9]
|
73
|
+
(1,2,3) from: 1 to: -1 . is: [2,3]
|
74
|
+
}
|
68
75
|
}
|
data/tools/fancy-mode.el
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
;;; fancy-mode.el --- Major mode for programming with the Fancy language.
|
2
|
+
;;
|
3
|
+
;; URL: http://www.fancy-lang.org
|
4
|
+
;; Version: 0.1
|
5
|
+
;; Author: Christopher Bertels <chris@fancy-lang.org>
|
6
|
+
|
7
|
+
|
1
8
|
(require 'generic-x)
|
2
9
|
|
3
10
|
(define-generic-mode
|
@@ -40,6 +47,7 @@
|
|
40
47
|
|
41
48
|
(add-to-list 'auto-mode-alist '("\\.fy\\'" . fancy-mode))
|
42
49
|
(add-to-list 'auto-mode-alist '("\\.fancypack\\'" . fancy-mode))
|
50
|
+
(add-to-list 'auto-mode-alist '("\\Fakefile\\'" . fancy-mode))
|
43
51
|
|
44
52
|
(add-to-list 'interpreter-mode-alist '("fancy" . fancy-mode))
|
45
53
|
|
@@ -65,3 +73,5 @@
|
|
65
73
|
(setq indent-line-function 'fancy-indent-line)
|
66
74
|
|
67
75
|
(provide 'fancy-mode)
|
76
|
+
|
77
|
+
;;; fancy-mode.el ends here
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fancy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3845972432426844170
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 7
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.7.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christopher Bertels
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: ruby_lib
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-05-05 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: |
|
@@ -88,7 +88,6 @@ files:
|
|
88
88
|
- lib/proxy.fy
|
89
89
|
- lib/range.fy
|
90
90
|
- lib/rbx.fy
|
91
|
-
- lib/remote_object.fy
|
92
91
|
- lib/set.fy
|
93
92
|
- lib/stack.fy
|
94
93
|
- lib/string.fy
|
@@ -107,6 +106,7 @@ files:
|
|
107
106
|
- lib/compiler/stages.fy
|
108
107
|
- lib/package/dependency.fy
|
109
108
|
- lib/package/dependency_installer.fy
|
109
|
+
- lib/package/handler.fy
|
110
110
|
- lib/package/installer.fy
|
111
111
|
- lib/package/list.fy
|
112
112
|
- lib/package/specification.fy
|
@@ -140,7 +140,7 @@ files:
|
|
140
140
|
- lib/rbx/name_error.fy
|
141
141
|
- lib/rbx/no_method_error.fy
|
142
142
|
- lib/rbx/object.fy
|
143
|
-
- lib/rbx/
|
143
|
+
- lib/rbx/proc.fy
|
144
144
|
- lib/rbx/range.fy
|
145
145
|
- lib/rbx/regexp.fy
|
146
146
|
- lib/rbx/string.fy
|
@@ -185,6 +185,9 @@ files:
|
|
185
185
|
- tests/class.fy
|
186
186
|
- tests/control_flow.fy
|
187
187
|
- tests/documentation.fy
|
188
|
+
- tests/dynamic_key_hash.fy
|
189
|
+
- tests/dynamic_slot_object.fy
|
190
|
+
- tests/dynamic_value_array.fy
|
188
191
|
- tests/enumerable.fy
|
189
192
|
- tests/enumerator.fy
|
190
193
|
- tests/exception.fy
|
@@ -214,7 +217,6 @@ files:
|
|
214
217
|
- bin/fyi
|
215
218
|
- bin/ifancy
|
216
219
|
- bin/fspec
|
217
|
-
- examples/99bottles.fy
|
218
220
|
- examples/actor_bunnies.fy
|
219
221
|
- examples/actors.fy
|
220
222
|
- examples/actors_primitive.fy
|
@@ -229,14 +231,11 @@ files:
|
|
229
231
|
- examples/call_with_receiver.fy
|
230
232
|
- examples/class.fy
|
231
233
|
- examples/closures.fy
|
232
|
-
- examples/conditions_exceptions.fy
|
233
|
-
- examples/conditions_parsing.fy
|
234
234
|
- examples/constant_access.fy
|
235
235
|
- examples/default_args.fy
|
236
236
|
- examples/define_methods.fy
|
237
237
|
- examples/documentation.fy
|
238
238
|
- examples/documentation_formatters.fy
|
239
|
-
- examples/dynamic.fy
|
240
239
|
- examples/dynamic_output.fy
|
241
240
|
- examples/echo.fy
|
242
241
|
- examples/empty_catch.fy
|
@@ -249,7 +248,6 @@ files:
|
|
249
248
|
- examples/future_composition.fy
|
250
249
|
- examples/futures.fy
|
251
250
|
- examples/game_of_life.fy
|
252
|
-
- examples/greeter.fy
|
253
251
|
- examples/hashes.fy
|
254
252
|
- examples/hello_world.fy
|
255
253
|
- examples/html_generator.fy
|
@@ -259,7 +257,6 @@ files:
|
|
259
257
|
- examples/nested_classes.fy
|
260
258
|
- examples/nested_try.fy
|
261
259
|
- examples/numbers.fy
|
262
|
-
- examples/parsing.fy
|
263
260
|
- examples/pattern_matching.fy
|
264
261
|
- examples/person.fy
|
265
262
|
- examples/regex.fy
|
data/examples/99bottles.fy
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
class MalformedLogEntry : Error {
|
2
|
-
read_slot: 'text
|
3
|
-
def initialize: @text
|
4
|
-
}
|
5
|
-
|
6
|
-
class LogEntry {
|
7
|
-
read_write_slots: ('word, 'number)
|
8
|
-
|
9
|
-
def LogEntry parse_entry: text {
|
10
|
-
word, number = text split: "|"
|
11
|
-
number = number to_i
|
12
|
-
if: (word && number) then: {
|
13
|
-
LogEntry new do: {
|
14
|
-
word: word
|
15
|
-
number: number
|
16
|
-
}
|
17
|
-
} else: {
|
18
|
-
MalformedLogEntry new: text signal!
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
|
-
|
23
|
-
class LogFile {
|
24
|
-
read_slots: ('filename, 'entries)
|
25
|
-
def initialize: @filename entries: @entries ([]);
|
26
|
-
def parse {
|
27
|
-
@text = File read: @filename
|
28
|
-
with_restarts: {
|
29
|
-
skip_entry: { nil }
|
30
|
-
} do: {
|
31
|
-
@text lines each: |line| {
|
32
|
-
@entries << (LogEntry parse_entry: line)
|
33
|
-
}
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
class LogAnalyzer {
|
39
|
-
read_slots: ('words, 'numbers)
|
40
|
-
def initialize: @logfiles {
|
41
|
-
@words = <[]>
|
42
|
-
@numbers = <[]>
|
43
|
-
}
|
44
|
-
def analyze_all {
|
45
|
-
@entries = @logfiles map: |f| {
|
46
|
-
LogFile new: f . do: { parse } . entries
|
47
|
-
} flatten
|
48
|
-
|
49
|
-
@entries each: |e| { analyze: e }
|
50
|
-
}
|
51
|
-
def analyze: entry {
|
52
|
-
if: (@words[entry word]) then: |val| {
|
53
|
-
@words[entry word]: (val + 1)
|
54
|
-
} else: {
|
55
|
-
@words[entry word]: 1
|
56
|
-
}
|
57
|
-
if: (@numbers[entry number]) then: |val| {
|
58
|
-
@numbers[entry number]: (val + 1)
|
59
|
-
} else: {
|
60
|
-
@numbers[entry number]: 1
|
61
|
-
}
|
62
|
-
}
|
63
|
-
}
|
64
|
-
|
65
|
-
l = LogAnalyzer new: ["examples/conditions_parsing_log.log"]
|
66
|
-
l analyze_all
|
67
|
-
" words: #{l words to_a sort_by: 'second reverse inspect}" println
|
68
|
-
"numbers: #{l numbers to_a sort_by: 'second reverse inspect}" println
|