fancy 0.5.0 → 0.6.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/AUTHORS +2 -0
- data/README.md +6 -1
- data/bin/fancy +6 -0
- data/bin/ifancy +44 -3
- data/boot/fancy_ext/module.rb +4 -0
- data/boot/fancy_ext/object.rb +4 -0
- data/boot/rbx-compiler/compiler/ast/block.rb +29 -1
- data/boot/rbx-compiler/compiler/ast/identifier.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/message_send.rb +1 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.lex +2 -0
- data/boot/rbx-compiler/parser/parser.rb +6 -0
- data/boot/rbx-compiler/parser/parser.y +14 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/features.md +24 -0
- data/examples/99bottles.fy +5 -0
- data/examples/conditions_exceptions.fy +9 -0
- data/examples/conditions_parsing.fy +68 -0
- data/examples/greeter.fy +9 -0
- data/examples/html_generator.fy +59 -29
- data/examples/webserver/webserver.fy +8 -11
- data/lib/argv.fy +6 -0
- data/lib/array.fy +17 -35
- data/lib/block.fy +82 -1
- data/lib/boot.fy +4 -2
- data/lib/compiler.fy +2 -2
- data/lib/compiler/ast/block.fy +24 -20
- data/lib/compiler/ast/message_send.fy +11 -0
- data/lib/contracts.fy +60 -0
- data/lib/dynamic_slot_object.fy +61 -0
- data/lib/enumerable.fy +432 -394
- data/lib/enumerator.fy +152 -150
- data/lib/fdoc.fy +4 -17
- data/lib/fiber.fy +4 -10
- data/lib/file.fy +33 -25
- data/lib/future.fy +59 -5
- data/lib/hash.fy +54 -1
- data/lib/html.fy +107 -0
- data/lib/kvo.fy +173 -0
- data/lib/main.fy +6 -2
- data/lib/message_sink.fy +19 -0
- data/lib/number.fy +48 -0
- data/lib/object.fy +65 -13
- data/lib/package.fy +12 -2
- data/lib/package/dependency.fy +13 -0
- data/lib/package/dependency_installer.fy +27 -0
- data/lib/package/installer.fy +4 -10
- data/lib/package/uninstaller.fy +1 -3
- data/lib/parser/ext/lexer.lex +8 -3
- data/lib/parser/ext/parser.y +4 -1
- data/lib/parser/methods.fy +7 -3
- data/lib/range.fy +1 -1
- data/lib/rbx.fy +2 -1
- data/lib/rbx/array.fy +28 -12
- data/lib/rbx/bignum.fy +1 -1
- data/lib/rbx/block.fy +27 -0
- data/lib/rbx/console.fy +6 -6
- data/lib/rbx/date.fy +6 -1
- data/lib/rbx/documentation.fy +8 -3
- data/lib/rbx/exception.fy +5 -0
- data/lib/rbx/file.fy +40 -7
- data/lib/rbx/fixnum.fy +12 -1
- data/lib/rbx/method.fy +9 -2
- data/lib/rbx/module.fy +24 -0
- data/lib/rbx/regexp.fy +8 -0
- data/lib/rbx/string.fy +23 -7
- data/lib/rbx/tcp_server.fy +4 -2
- data/lib/rbx/tcp_socket.fy +14 -0
- data/lib/remote_object.fy +59 -0
- data/lib/set.fy +15 -4
- data/lib/string.fy +38 -5
- data/lib/stringio.fy +1 -0
- data/lib/symbol.fy +4 -0
- data/lib/system.fy +22 -0
- data/lib/thread_pool.fy +2 -2
- data/lib/tuple.fy +18 -1
- data/lib/vars.fy +17 -0
- data/lib/version.fy +1 -1
- data/ruby_lib/fancy +6 -0
- data/tests/array.fy +30 -0
- data/tests/block.fy +106 -0
- data/tests/class.fy +19 -0
- data/tests/enumerable.fy +1 -1
- data/tests/enumerator.fy +5 -5
- data/tests/file.fy +28 -0
- data/tests/fixnum.fy +0 -50
- data/tests/future.fy +9 -24
- data/tests/hash.fy +35 -0
- data/tests/html.fy +33 -0
- data/tests/kvo.fy +101 -0
- data/tests/number.fy +75 -0
- data/tests/object.fy +50 -3
- data/tests/string.fy +19 -10
- data/tests/symbol.fy +5 -0
- data/tests/tuple.fy +7 -0
- data/tools/fancy-mode.el +5 -1
- metadata +22 -21
- data/boot/compiler/parser/ext/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/Makefile +0 -156
- data/boot/rbx-compiler/parser/lexer.c +0 -2310
- data/boot/rbx-compiler/parser/lexer.h +0 -315
- data/boot/rbx-compiler/parser/parser.c +0 -2946
- data/boot/rbx-compiler/parser/parser.h +0 -151
- data/lib/fiber_pool.fy +0 -78
- data/lib/method.fy +0 -6
- data/lib/parser/ext/Makefile +0 -156
- data/lib/parser/ext/fancy_parser.bundle +0 -0
- data/lib/parser/ext/lexer.c +0 -2392
- data/lib/parser/ext/lexer.h +0 -315
- data/lib/parser/ext/parser.c +0 -3251
- data/lib/parser/ext/parser.h +0 -161
data/lib/enumerator.fy
CHANGED
|
@@ -1,184 +1,186 @@
|
|
|
1
|
-
class
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def initialize: @collection with: @iterator {
|
|
15
|
-
"""
|
|
16
|
-
@collection Collection to iterate over.
|
|
17
|
-
@iterator Selector to use to iterate over @collection.
|
|
18
|
-
|
|
19
|
-
Initializes a new FancyEnumerator with a given @collection
|
|
20
|
-
and @iterator selector to be used for iteration.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
rewind
|
|
24
|
-
}
|
|
1
|
+
class Fancy {
|
|
2
|
+
class Enumerator {
|
|
3
|
+
def initialize: @collection {
|
|
4
|
+
"""
|
|
5
|
+
@collection Collection to iterate over.
|
|
6
|
+
|
|
7
|
+
Initializes a new Enumerator with a given @collection,
|
|
8
|
+
using #each: for iteration.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@iterator = 'each:
|
|
12
|
+
rewind
|
|
13
|
+
}
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
def initialize: @collection with: @iterator {
|
|
16
|
+
"""
|
|
17
|
+
@collection Collection to iterate over.
|
|
18
|
+
@iterator Selector to use to iterate over @collection.
|
|
29
19
|
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
Initializes a new Enumerator with a given @collection
|
|
21
|
+
and @iterator selector to be used for iteration.
|
|
22
|
+
"""
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
e = a to_enum
|
|
36
|
-
e next # => 1
|
|
37
|
-
e next # => 2
|
|
38
|
-
e next # => 3
|
|
39
|
-
e next # => raises Fancy StopIteration
|
|
40
|
-
"""
|
|
24
|
+
rewind
|
|
25
|
+
}
|
|
41
26
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
27
|
+
def next {
|
|
28
|
+
"""
|
|
29
|
+
@return Next element in the collection this enumerator is attached to.
|
|
30
|
+
|
|
31
|
+
Returns the next element in the collection this enumerator is attached to.
|
|
32
|
+
It will move the internal position forward (compared to e.g. #peek, which doesn't).
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
a = [1,2,3]
|
|
36
|
+
e = a to_enum
|
|
37
|
+
e next # => 1
|
|
38
|
+
e next # => 2
|
|
39
|
+
e next # => 3
|
|
40
|
+
e next # => raises Fancy StopIteration
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
if: @peeked then: {
|
|
44
|
+
@peeked = false
|
|
45
|
+
@peek
|
|
49
46
|
} else: {
|
|
50
|
-
|
|
47
|
+
result = @fiber resume
|
|
48
|
+
if: (@fiber alive?) then: {
|
|
49
|
+
return result
|
|
50
|
+
} else: {
|
|
51
|
+
(Fancy StopIteration new: result) raise!
|
|
52
|
+
}
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
def ended? {
|
|
56
|
-
"""
|
|
57
|
-
@return @true if the enumerator has ended (no more values left), @false otherwise.
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
def ended? {
|
|
57
|
+
"""
|
|
58
|
+
@return @true if the enumerator has ended (no more values left), @false otherwise.
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
Indicates if an enumerator has ended (no more values left).
|
|
61
|
+
"""
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
"""
|
|
67
|
-
Returns the next object in the FancyEnumerator, but doesn't move the
|
|
68
|
-
internal position forward.
|
|
69
|
-
When the position reaches the end, a Fancy StopIteration exception is
|
|
70
|
-
raised.
|
|
71
|
-
|
|
72
|
-
Example:
|
|
73
|
-
a = [1,2,3]
|
|
74
|
-
e = a to_enum
|
|
75
|
-
e next p #=> 1
|
|
76
|
-
e peek p #=> 2
|
|
77
|
-
e peek p #=> 2
|
|
78
|
-
e peek p #=> 2
|
|
79
|
-
e next p #=> 2
|
|
80
|
-
e next p #=> 3
|
|
81
|
-
e next p #=> raises Fancy StopIteration
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
unless: @peeked do: {
|
|
85
|
-
@peeked = true
|
|
86
|
-
@peek = @fiber resume
|
|
87
|
-
if: (@fiber alive?) then: {
|
|
88
|
-
return @peek
|
|
89
|
-
} else: {
|
|
90
|
-
(Fancy StopIteration new: result) raise!
|
|
91
|
-
}
|
|
63
|
+
@fiber alive? not
|
|
92
64
|
}
|
|
93
65
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
66
|
+
def peek {
|
|
67
|
+
"""
|
|
68
|
+
Returns the next object in the Enumerator, but doesn't move the
|
|
69
|
+
internal position forward.
|
|
70
|
+
When the position reaches the end, a Fancy StopIteration exception is
|
|
71
|
+
raised.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
a = [1,2,3]
|
|
75
|
+
e = a to_enum
|
|
76
|
+
e next p #=> 1
|
|
77
|
+
e peek p #=> 2
|
|
78
|
+
e peek p #=> 2
|
|
79
|
+
e peek p #=> 2
|
|
80
|
+
e next p #=> 2
|
|
81
|
+
e next p #=> 3
|
|
82
|
+
e next p #=> raises Fancy StopIteration
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
unless: @peeked do: {
|
|
86
|
+
@peeked = true
|
|
87
|
+
@peek = @fiber resume
|
|
88
|
+
if: (@fiber alive?) then: {
|
|
89
|
+
return @peek
|
|
90
|
+
} else: {
|
|
91
|
+
(Fancy StopIteration new: result) raise!
|
|
92
|
+
}
|
|
93
|
+
}
|
|
104
94
|
|
|
105
|
-
|
|
106
|
-
param = |element| { yield: element }
|
|
107
|
-
@collection receive_message: @iterator with_params: [param]
|
|
95
|
+
return @peek
|
|
108
96
|
}
|
|
109
|
-
}
|
|
110
97
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
98
|
+
def rewind {
|
|
99
|
+
"""
|
|
100
|
+
Resets the enumerator to start from the collection's beginning.
|
|
101
|
+
"""
|
|
115
102
|
|
|
116
|
-
|
|
117
|
-
|
|
103
|
+
@peeked = false
|
|
104
|
+
@peek = nil
|
|
118
105
|
|
|
119
|
-
|
|
120
|
-
|
|
106
|
+
@fiber = Fiber new: {
|
|
107
|
+
param = |element| { yield: element }
|
|
108
|
+
@collection receive_message: @iterator with_params: [param]
|
|
109
|
+
}
|
|
121
110
|
}
|
|
122
111
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"""
|
|
128
|
-
@block @Block@ to be called with each element in the collection (iteration).
|
|
112
|
+
def with: object each: block {
|
|
113
|
+
"""
|
|
114
|
+
@object Object to pass along to @block with each element in the collection.
|
|
115
|
+
@block A @Block@ to be called with each element in the collection and @object.
|
|
129
116
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"""
|
|
117
|
+
Similar to #each: but also passing in a given @object to each invocation of @block.
|
|
118
|
+
"""
|
|
133
119
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
block call: [next]
|
|
137
|
-
} catch (Fancy StopIteration) => ex {
|
|
138
|
-
return self
|
|
120
|
+
each: |element| {
|
|
121
|
+
block call: [element, object]
|
|
139
122
|
}
|
|
123
|
+
|
|
124
|
+
return object
|
|
140
125
|
}
|
|
141
|
-
}
|
|
142
126
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
127
|
+
def each: block {
|
|
128
|
+
"""
|
|
129
|
+
@block @Block@ to be called with each element in the collection (iteration).
|
|
130
|
+
|
|
131
|
+
Calls a given @Block@ with each element in the collection this enumerator is attached to.
|
|
132
|
+
Used for iterating over the collection using this enumerator.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
loop: {
|
|
136
|
+
try {
|
|
137
|
+
block call: [next]
|
|
138
|
+
} catch (Fancy StopIteration) => ex {
|
|
139
|
+
return self
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
149
143
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
def chunk: block {
|
|
145
|
+
Generator new: |inner_block| {
|
|
146
|
+
enums = []
|
|
147
|
+
last = nil
|
|
148
|
+
previous = nil
|
|
149
|
+
stack = []
|
|
150
|
+
|
|
151
|
+
each: |element| {
|
|
152
|
+
result = (block call: [element]) not not
|
|
153
|
+
if: (previous == result) then: {
|
|
154
|
+
stack << element
|
|
157
155
|
} else: {
|
|
158
|
-
|
|
156
|
+
previous if_nil: {
|
|
157
|
+
# wait one gap to call
|
|
158
|
+
} else: {
|
|
159
|
+
inner_block call: [[previous, stack]]
|
|
160
|
+
}
|
|
161
|
+
previous = result
|
|
162
|
+
stack = [element]
|
|
163
|
+
last = [result, stack]
|
|
164
|
+
enums << last
|
|
159
165
|
}
|
|
160
|
-
previous = result
|
|
161
|
-
stack = [element]
|
|
162
|
-
last = [result, stack]
|
|
163
|
-
enums << last
|
|
164
166
|
}
|
|
165
|
-
}
|
|
166
167
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
self
|
|
169
|
+
} . to_enum
|
|
170
|
+
}
|
|
170
171
|
|
|
171
|
-
|
|
172
|
-
|
|
172
|
+
class Generator {
|
|
173
|
+
def initialize: @block {}
|
|
173
174
|
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
def each: block {
|
|
176
|
+
@block call: [block]
|
|
177
|
+
}
|
|
176
178
|
}
|
|
177
|
-
}
|
|
178
179
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
def to_a {
|
|
181
|
+
output = []
|
|
182
|
+
each: |element| { output << element }
|
|
183
|
+
output
|
|
184
|
+
}
|
|
183
185
|
}
|
|
184
|
-
}
|
|
186
|
+
}
|
data/lib/fdoc.fy
CHANGED
|
@@ -208,50 +208,37 @@ class Fancy FDoc {
|
|
|
208
208
|
def self create_class_references: str {
|
|
209
209
|
"""
|
|
210
210
|
Creates class references for Fancy class names.
|
|
211
|
-
|
|
212
211
|
A docstring may contain class names sorounded by @
|
|
213
212
|
without space between the @.
|
|
214
213
|
|
|
215
214
|
Nested classes can be indicated by using :: like
|
|
216
|
-
|
|
217
|
-
Foo::Bar
|
|
218
|
-
|
|
215
|
+
Foo::Bar
|
|
219
216
|
This will create references for both, @Foo and @Bar
|
|
220
217
|
|
|
221
218
|
Instance methods should be written:
|
|
222
|
-
|
|
223
|
-
Foo::Bar#baz
|
|
219
|
+
Foo::Bar#baz
|
|
224
220
|
|
|
225
221
|
Class methods should be written:
|
|
226
|
-
|
|
227
|
-
Foo::Bar.baz
|
|
222
|
+
Foo::Bar.baz
|
|
228
223
|
|
|
229
224
|
Some examples:
|
|
230
|
-
|
|
231
225
|
A simple class reference:
|
|
232
|
-
|
|
233
226
|
@Fancy@
|
|
234
227
|
|
|
235
228
|
Nested class reference:
|
|
236
|
-
|
|
237
229
|
@Fancy::FDoc@
|
|
238
230
|
|
|
239
231
|
A fancy method without arguments:
|
|
240
|
-
|
|
241
232
|
@Fancy::FDoc::JSON#:generate_map@
|
|
242
233
|
|
|
243
234
|
A ruby method reference (will link to ruby docs if available)
|
|
244
|
-
|
|
245
235
|
@String#split@
|
|
246
236
|
|
|
247
237
|
A fancy method with many arguments:
|
|
248
|
-
|
|
249
238
|
@Fancy::Package::Installer#initialize:version:install_path:@
|
|
250
239
|
|
|
251
240
|
A singleton method:
|
|
252
|
-
|
|
253
241
|
@Fancy::FDoc::Formatter~format:@
|
|
254
|
-
|
|
255
242
|
"""
|
|
256
243
|
str gsub(/@[A-Z][^\r\n\s]+?@/) |cstr| {
|
|
257
244
|
names = cstr slice(1, cstr size() - 2) split("::")
|
|
@@ -319,7 +306,7 @@ class Fancy FDoc {
|
|
|
319
306
|
}
|
|
320
307
|
|
|
321
308
|
def self create_code: str {
|
|
322
|
-
str gsub(/@([^\s,\]\)\}\.]+)/,
|
|
309
|
+
str gsub(/@([^\s,\]\)\{\}\.]+)/,
|
|
323
310
|
"<code data-lang=\"fancy\">\\1</code>")
|
|
324
311
|
}
|
|
325
312
|
|
data/lib/fiber.fy
CHANGED
|
@@ -6,17 +6,11 @@ class Fiber {
|
|
|
6
6
|
There is no preemptive scheduler.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
def sleep: seconds {
|
|
10
|
-
@sleep_end = Time now + seconds
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
def asleep? {
|
|
14
|
-
if: @sleep_end then: {
|
|
15
|
-
Time now < @sleep_end
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
9
|
def Fiber name {
|
|
20
10
|
"Fiber"
|
|
21
11
|
}
|
|
12
|
+
|
|
13
|
+
def Fiber inspect {
|
|
14
|
+
name
|
|
15
|
+
}
|
|
22
16
|
}
|
data/lib/file.fy
CHANGED
|
@@ -4,33 +4,29 @@ class File {
|
|
|
4
4
|
system on which Fancy is running.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# }
|
|
17
|
-
|
|
18
|
-
def self read: filename {
|
|
19
|
-
"""
|
|
20
|
-
Reads all the contens (in ASCII mode) of a given file and returns
|
|
21
|
-
them as an Array of lines being read.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
lines = []
|
|
25
|
-
File open: filename modes: ['read] with: |f| {
|
|
26
|
-
{ f eof? } while_false: {
|
|
27
|
-
lines << (f readln)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
lines join
|
|
7
|
+
def File write: filename with: block {
|
|
8
|
+
"""
|
|
9
|
+
@filename Filename of @File@ to write to.
|
|
10
|
+
@block @Block@ called with a @File@ object to write to.
|
|
11
|
+
|
|
12
|
+
Opens a @File@ for writing and calls @block with it.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
File open: filename modes: ['write] with: block
|
|
31
16
|
}
|
|
32
17
|
|
|
33
|
-
def
|
|
18
|
+
def File read: filename with: block {
|
|
19
|
+
"""
|
|
20
|
+
@filename Filename of @File@ to read from.
|
|
21
|
+
@block @Block@ called with a @File@ object to read from.
|
|
22
|
+
|
|
23
|
+
Opens a @File@ for reading and calls @block with it.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
File open: filename modes: ['read] with: block
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def File touch: filename {
|
|
34
30
|
"""
|
|
35
31
|
@filename Name of @File@ to be created, if not already existant.
|
|
36
32
|
|
|
@@ -55,4 +51,16 @@ class File {
|
|
|
55
51
|
|
|
56
52
|
alias_method: 'print: for: 'write:
|
|
57
53
|
alias_method: 'println: for: 'writeln:
|
|
54
|
+
|
|
55
|
+
def expanded_path {
|
|
56
|
+
"""
|
|
57
|
+
@return Expanded (absolute) path of @self.
|
|
58
|
+
|
|
59
|
+
Example:
|
|
60
|
+
f = File open: \"README.txt\"
|
|
61
|
+
f expanded_path # => \"/path/to/README.txt\" (when run from /path/to/)
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
File expand_path: path
|
|
65
|
+
}
|
|
58
66
|
}
|