fancy 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +5 -4
- data/bin/fspec +19 -1
- data/bin/ifancy +139 -35
- data/boot/README +2 -9
- data/boot/extconf.rb +0 -1
- data/boot/fancy_ext/module.rb +5 -15
- data/boot/fancy_ext/thread.rb +22 -9
- data/boot/rbx-compiler/README +0 -4
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/parser.y +1 -0
- data/doc/api/fancy.css +1 -6
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +2 -4
- data/doc/api/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/doc/api/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
- data/doc/api/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
- data/doc/api/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/doc/api/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/doc/api/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
- data/doc/api/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
- data/doc/api/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
- data/doc/api/images/ui-icons_0073ea_256x240.png +0 -0
- data/doc/api/images/ui-icons_454545_256x240.png +0 -0
- data/doc/api/images/ui-icons_666666_256x240.png +0 -0
- data/doc/api/images/ui-icons_ff0084_256x240.png +0 -0
- data/doc/api/images/ui-icons_ffffff_256x240.png +0 -0
- data/doc/api/index.html +5 -4
- data/doc/api/jquery-1.8.2.min.js +2 -0
- data/doc/api/jquery-ui-1.9.0.custom.min.css +5 -0
- data/doc/api/jquery-ui-1.9.0.custom.min.js +6 -0
- data/doc/features.md +8 -3
- data/examples/argv.fy +1 -1
- data/examples/closures.fy +1 -4
- data/examples/echo.fy +2 -2
- data/examples/guess_number.fy +18 -0
- data/examples/nested_classes.fy +3 -15
- data/lib/argv.fy +23 -18
- data/lib/array.fy +18 -37
- data/lib/block.fy +125 -0
- data/lib/boot.fy +1 -0
- data/lib/compiler/ast/block.fy +1 -1
- data/lib/compiler/ast/identifier.fy +1 -1
- data/lib/compiler/ast/message_send.fy +0 -13
- data/lib/compiler/ast/method_def.fy +1 -1
- data/lib/compiler/ast/singleton_method_def.fy +1 -0
- data/lib/compiler/ast/tuple_literal.fy +1 -1
- data/lib/compiler/command.fy +1 -1
- data/lib/compiler/compiler.fy +8 -6
- data/lib/contracts.fy +1 -1
- data/lib/directory.fy +1 -1
- data/lib/dynamic_slot_object.fy +1 -1
- data/lib/enumerable.fy +316 -25
- data/lib/enumerator.fy +11 -8
- data/lib/eval.fy +0 -3
- data/lib/fancy_spec.fy +27 -0
- data/lib/fdoc.fy +8 -8
- data/lib/file.fy +25 -1
- data/lib/hash.fy +91 -0
- data/lib/html.fy +40 -11
- data/lib/integer.fy +4 -0
- data/lib/main.fy +18 -11
- data/lib/object.fy +33 -7
- data/lib/option_parser.fy +20 -1
- data/lib/package/dependency.fy +8 -0
- data/lib/package/dependency_installer.fy +3 -6
- data/lib/package/handler.fy +4 -4
- data/lib/package/installer.fy +2 -5
- data/lib/package/list.fy +3 -4
- data/lib/parser/ext/parser.y +1 -0
- data/lib/proxies.fy +0 -2
- data/lib/queue.fy +7 -0
- data/lib/rbx.fy +1 -0
- data/lib/rbx/actor.fy +3 -1
- data/lib/rbx/alpha.fy +24 -0
- data/lib/rbx/array.fy +3 -1
- data/lib/rbx/class.fy +5 -8
- data/lib/rbx/date_time.fy +14 -0
- data/lib/rbx/file.fy +6 -0
- data/lib/rbx/hash.fy +42 -0
- data/lib/rbx/thread.fy +5 -7
- data/lib/string.fy +56 -4
- data/lib/symbol.fy +29 -1
- data/lib/time.fy +17 -0
- data/lib/vars.fy +4 -3
- data/lib/version.fy +1 -1
- data/ruby_lib/interactive/hilight.rb +125 -0
- data/tests/array.fy +19 -7
- data/tests/block.fy +103 -4
- data/tests/class.fy +31 -26
- data/tests/control_flow.fy +0 -1
- data/tests/dynamic_key_hash.fy +22 -1
- data/tests/enumerable.fy +239 -7
- data/tests/enumerator.fy +7 -0
- data/tests/file.fy +16 -0
- data/tests/future.fy +1 -11
- data/tests/future_proxy.fy +8 -0
- data/tests/hash.fy +132 -9
- data/tests/html.fy +30 -13
- data/tests/integer.fy +3 -0
- data/tests/method.fy +6 -11
- data/tests/object.fy +12 -5
- data/tests/option_parser.fy +12 -3
- data/tests/string.fy +69 -1
- data/tests/symbol.fy +24 -0
- metadata +42 -12
- data/boot/rsexp_pretty_printer.rb +0 -76
- data/doc/api/jquery-ui.min.js +0 -401
- data/doc/api/jquery.tools.min.js +0 -192
- data/doc/api/themeswitchertool.js +0 -250
- data/examples/future_sends.fy +0 -15
data/lib/string.fy
CHANGED
@@ -57,10 +57,9 @@ class String {
|
|
57
57
|
Indicates, if a @String@ consists only of whitespace.
|
58
58
|
"""
|
59
59
|
|
60
|
-
self
|
61
|
-
true
|
62
|
-
|
63
|
-
false
|
60
|
+
match self {
|
61
|
+
case /^\s*$/ -> true
|
62
|
+
case _ -> false
|
64
63
|
}
|
65
64
|
}
|
66
65
|
|
@@ -232,4 +231,57 @@ class String {
|
|
232
231
|
|
233
232
|
if: main? then: main_block else: else_block
|
234
233
|
}
|
234
|
+
|
235
|
+
def snake_cased {
|
236
|
+
"""
|
237
|
+
Returns a snake cased version of @self.
|
238
|
+
"""
|
239
|
+
|
240
|
+
r1 = Regexp new("([A-Z]+)([A-Z][a-z])")
|
241
|
+
r2 = Regexp new("([a-z\d])([A-Z])")
|
242
|
+
gsub(r1,"\1_\2") gsub(r2,"\1_\2") tr("-", "_") lowercase
|
243
|
+
}
|
244
|
+
|
245
|
+
def camel_cased {
|
246
|
+
"""
|
247
|
+
Returns camel cased version of @self which is expected
|
248
|
+
to be a snake cased @String@.
|
249
|
+
"""
|
250
|
+
|
251
|
+
self split: "_" . map: @{ capitalize } . join
|
252
|
+
}
|
253
|
+
|
254
|
+
def uppercase? {
|
255
|
+
"""
|
256
|
+
@return @true if @self is completely uppercase, @false otherwise.
|
257
|
+
|
258
|
+
Example:
|
259
|
+
\"F\" uppercase? # => true
|
260
|
+
\"FOO\" uppercase? # => true
|
261
|
+
\"f\” uppercase? # => false
|
262
|
+
\"Foo\" uppercase? # => false
|
263
|
+
"""
|
264
|
+
|
265
|
+
{ return false } if: blank?
|
266
|
+
uppercase == self
|
267
|
+
}
|
268
|
+
|
269
|
+
def lowercase? {
|
270
|
+
"""
|
271
|
+
@return @true if @self is completely lowercase, @false otherwise.
|
272
|
+
|
273
|
+
Example:
|
274
|
+
\"f\” lowercase? # => true
|
275
|
+
\"foo\" lowercase? # => true
|
276
|
+
\"F\" lowercase? # => false
|
277
|
+
\"Foo\" lowercase? # => false
|
278
|
+
"""
|
279
|
+
|
280
|
+
{ return false } if: blank?
|
281
|
+
lowercase == self
|
282
|
+
}
|
283
|
+
|
284
|
+
def starts_with?: string {
|
285
|
+
from: 0 to: (string size - 1) == string
|
286
|
+
}
|
235
287
|
}
|
data/lib/symbol.fy
CHANGED
@@ -45,11 +45,39 @@ class Symbol {
|
|
45
45
|
recv receive_message: self
|
46
46
|
}
|
47
47
|
|
48
|
+
def call_with_receiver: receiver {
|
49
|
+
call: [receiver]
|
50
|
+
}
|
51
|
+
|
52
|
+
def call: args with_receiver: receiver {
|
53
|
+
call: $ args unshift: receiver
|
54
|
+
}
|
55
|
+
|
48
56
|
def arity {
|
49
|
-
|
57
|
+
m = message_name to_s
|
58
|
+
match m {
|
59
|
+
case /^:[a-zA-Z0-9_]+$/ -> m count: |c| { c == ":" }
|
60
|
+
case /^:\W+$/ -> 2
|
61
|
+
case _ -> m count: |c| { c == ":" } + 1
|
62
|
+
}
|
50
63
|
}
|
51
64
|
|
52
65
|
def to_sym {
|
53
66
|
self
|
54
67
|
}
|
68
|
+
|
69
|
+
def to_block {
|
70
|
+
"""
|
71
|
+
@return @Block@ that sends @self to its first argument, passing along any remaining arguments.
|
72
|
+
|
73
|
+
Example:
|
74
|
+
'inspect to_block
|
75
|
+
# is equal to:
|
76
|
+
@{ inspect }
|
77
|
+
"""
|
78
|
+
|
79
|
+
|args| {
|
80
|
+
call: args
|
81
|
+
}
|
82
|
+
}
|
55
83
|
}
|
data/lib/time.fy
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Time {
|
2
|
+
def Time duration: block {
|
3
|
+
"""
|
4
|
+
@block @Block to be called & timed.
|
5
|
+
@return @Float@ that is the duration (in seconds) of calling @block.
|
6
|
+
|
7
|
+
Calls @block and times the runtime duration of doing so in seconds.
|
8
|
+
|
9
|
+
Example:
|
10
|
+
Time duration: { Thread sleep: 1 } # => >= 1.0
|
11
|
+
"""
|
12
|
+
|
13
|
+
start = Time now
|
14
|
+
block call
|
15
|
+
Time now - start
|
16
|
+
}
|
17
|
+
}
|
data/lib/vars.fy
CHANGED
data/lib/version.fy
CHANGED
@@ -0,0 +1,125 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module CodeRay
|
3
|
+
module Scanners
|
4
|
+
|
5
|
+
# Fancy scanner by swarley.
|
6
|
+
class Fancy < Scanner
|
7
|
+
|
8
|
+
register_for :fancy
|
9
|
+
file_extension 'fy'
|
10
|
+
|
11
|
+
SPECIAL_FORMS = %w[
|
12
|
+
def throw try catch class
|
13
|
+
] # :nodoc:
|
14
|
+
|
15
|
+
CORE_FORMS = %w[
|
16
|
+
+ - > < == != >= <= % ** * = && || =~
|
17
|
+
] # :nodoc:
|
18
|
+
|
19
|
+
PREDEFINED_CONSTANTS = %w[
|
20
|
+
true false nil
|
21
|
+
] # :nodoc:
|
22
|
+
|
23
|
+
IDENT_KIND = WordList.new(:ident).
|
24
|
+
add(SPECIAL_FORMS, :keyword).
|
25
|
+
add(CORE_FORMS, :keyword).
|
26
|
+
add(PREDEFINED_CONSTANTS, :predefined_constant)
|
27
|
+
|
28
|
+
KEYWORD_NEXT_TOKEN_KIND = WordList.new(nil).
|
29
|
+
add(%w[ def defn defn- definline defmacro defmulti defmethod defstruct defonce declare ], :function).
|
30
|
+
add(%w[ ns ], :namespace).
|
31
|
+
add(%w[ defprotocol defrecord ], :class)
|
32
|
+
|
33
|
+
BASIC_IDENTIFIER = /[a-zA-Z$%*\/_+!?&<>\-=]=?[a-zA-Z0-9$&*+!\/_?<>\-\#]*/
|
34
|
+
CLASS_IDENTIFIER = /[A-Z]+[A-Za-z0-9]*|[A-Z]+[A-Za-z0-9]\:\:|\:\:[A-Z]+[A-Za-z0-9]*/
|
35
|
+
IDENTIFIER = /(?!-\d)(?:(?:#{BASIC_IDENTIFIER}\.)*#{BASIC_IDENTIFIER}(?:\/#{BASIC_IDENTIFIER})?\.?)|\.\.?/
|
36
|
+
SYMBOL = /\'[A-z]+[A-z0-9\:\!\%\^\&\*\_\-\+\=\|\?\\\/\>\<\.]*/o
|
37
|
+
DIGIT = /\d+/
|
38
|
+
DIGIT10 = DIGIT
|
39
|
+
DIGIT16 = /[0-9a-f]/i
|
40
|
+
DIGIT8 = /[0-7]/
|
41
|
+
DIGIT2 = /[01]/
|
42
|
+
DECIMAL = /#{DIGIT}\.#{DIGIT}|-#{DIGIT}\.#{DIGIT}/
|
43
|
+
NUM = /(?:\-)*(?:#{DIGIT}|#{DIGIT16}|#{DIGIT8}|#{DIGIT2}|#{DECIMAL})/
|
44
|
+
MESSAGE = /[A-Za-z0-9\&\_]+?(?:\:|\?\:)/
|
45
|
+
CAPTURE = /\|.+?\|/
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def scan_tokens(encoder, options)
|
50
|
+
state = :initial
|
51
|
+
kind = nil
|
52
|
+
|
53
|
+
until eos?
|
54
|
+
case state
|
55
|
+
when :initial
|
56
|
+
if match = scan(/ \s+ | \n | , /x)
|
57
|
+
encoder.text_token match, :space
|
58
|
+
elsif match = scan(/\#.+?$/)
|
59
|
+
encoder.text_token match, :comment
|
60
|
+
elsif match = scan(/\{|\}|\@\{|\[|\]|\(|\)/)
|
61
|
+
encoder.text_token match, :operator
|
62
|
+
elsif match = scan(Regexp.new((%W(+ - @ > < == != >= <= % ** * = && || =~).map {|x| Regexp.escape x }).join '|'))
|
63
|
+
encoder.text_token match, :operator
|
64
|
+
elsif match = scan(/\.|\$/)
|
65
|
+
encoder.text_token match, :predefined_constant
|
66
|
+
elsif match = scan(CAPTURE)
|
67
|
+
encoder.text_token match, :predefined_constant
|
68
|
+
elsif match = scan(CLASS_IDENTIFIER)
|
69
|
+
encoder.text_token match, :constant
|
70
|
+
elsif match = scan(/\:\:/)
|
71
|
+
encoder.text_token match, :constant
|
72
|
+
elsif match = scan(MESSAGE)
|
73
|
+
encoder.text_token match, :keyword
|
74
|
+
elsif match = scan(/#{IDENTIFIER}/o)
|
75
|
+
kind = IDENT_KIND[match]
|
76
|
+
encoder.text_token match, kind
|
77
|
+
if rest? && kind == :keyword
|
78
|
+
if kind = KEYWORD_NEXT_TOKEN_KIND[match]
|
79
|
+
encoder.text_token match, :space if match = scan(/\s+/o)
|
80
|
+
encoder.text_token match, kind if match = scan(/#{IDENTIFIER}/o)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
elsif match = scan(MESSAGE)
|
84
|
+
encoder.text_token match, :keyword
|
85
|
+
elsif match = scan(/#{SYMBOL}/o)
|
86
|
+
encoder.text_token match, :symbol
|
87
|
+
elsif match = scan(/\./)
|
88
|
+
encoder.text_token match, :operator
|
89
|
+
elsif match = scan(/ \# \^ #{IDENTIFIER} /ox)
|
90
|
+
encoder.text_token match, :type
|
91
|
+
elsif match = scan(/ (\#)? " /x)
|
92
|
+
state = self[1] ? :regexp : :string
|
93
|
+
encoder.begin_group state
|
94
|
+
encoder.text_token match, :delimiter
|
95
|
+
elsif match = scan(/#{NUM}/o) and not matched.empty?
|
96
|
+
encoder.text_token match, match[/[.e\/]/i] ? :float : :integer
|
97
|
+
else
|
98
|
+
encoder.text_token getch, :error
|
99
|
+
end
|
100
|
+
|
101
|
+
when :string, :regexp
|
102
|
+
if match = scan(/[^"\\]+|\\.?/)
|
103
|
+
encoder.text_token match, :content
|
104
|
+
elsif match = scan(/"/)
|
105
|
+
encoder.text_token match, :delimiter
|
106
|
+
encoder.end_group state
|
107
|
+
state = :initial
|
108
|
+
else
|
109
|
+
raise_inspect "else case \" reached; %p not handled." % peek(1),
|
110
|
+
encoder, state
|
111
|
+
end
|
112
|
+
else
|
113
|
+
raise 'else case reached'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
if [:string, :regexp].include? state
|
118
|
+
encoder.end_group state
|
119
|
+
end
|
120
|
+
|
121
|
+
encoder
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/tests/array.fy
CHANGED
@@ -356,10 +356,6 @@ FancySpec describe: Array with: {
|
|
356
356
|
[1,2,3,4] any?: |x| { x > 4 } . is: false
|
357
357
|
}
|
358
358
|
|
359
|
-
it: "is selected from it with each index" with: 'select_with_index: when: {
|
360
|
-
["yooo",2,3,1,'foo,"bar"] select_with_index: |x i| { x is_a?: Fixnum } . is: [[2,1], [3,2], [1,3]]
|
361
|
-
}
|
362
|
-
|
363
359
|
it: "returns its remaining (all but the first) elements as a new Array" with: 'rest when: {
|
364
360
|
[1,2,3,4] rest is: [2,3,4]
|
365
361
|
[] rest is: []
|
@@ -529,15 +525,20 @@ FancySpec describe: Array with: {
|
|
529
525
|
arr is: [1,5,4,2,3]
|
530
526
|
}
|
531
527
|
|
532
|
-
it: "sorts the array with a given comparison block" with: '
|
528
|
+
it: "sorts the array with a given comparison block" with: 'sort: when: {
|
533
529
|
arr = [1,5,4,2,3]
|
534
530
|
sorted = [1,2,3,4,5]
|
535
|
-
arr
|
531
|
+
arr sort: |a b| { a <=> b } . is: sorted
|
536
532
|
arr is: [1,5,4,2,3]
|
537
533
|
|
538
534
|
arr = [(1,2), (0,1), (3,0)]
|
539
535
|
sorted = [(3,0), (0,1), (1,2)]
|
540
|
-
arr
|
536
|
+
arr sort: |a b| { a second <=> (b second) } . is: sorted
|
537
|
+
}
|
538
|
+
|
539
|
+
it: "sorts the array by a given block" with: 'sort_by: when: {
|
540
|
+
arr = [(1,2), (0,1), (3,0)]
|
541
|
+
sorted = [(3,0), (0,1), (1,2)]
|
541
542
|
arr sort_by: 'second . is: sorted
|
542
543
|
}
|
543
544
|
|
@@ -550,4 +551,15 @@ FancySpec describe: Array with: {
|
|
550
551
|
[] to_hash: @{ size } . is: <[]>
|
551
552
|
[[1,2],[3,4,5]] to_hash: @{ size } . is: <[2 => [1,2], 3 => [3,4,5]]>
|
552
553
|
}
|
554
|
+
|
555
|
+
it: "returns an sub-array within a given range" with: 'from:to: when: {
|
556
|
+
[] from: 0 to: 1 . is: []
|
557
|
+
[1] from: 0 to: 0 . is: [1]
|
558
|
+
[1] from: 0 to: 1 . is: [1]
|
559
|
+
[1] from: 0 to: 2 . is: [1]
|
560
|
+
[1] from: 0 to: -1 . is: [1]
|
561
|
+
[1] from: 0 to: -2 . is: []
|
562
|
+
[0,1,2,3] from: 0 to: 3 . is: [0,1,2,3]
|
563
|
+
[0,1,2,3] from: -1 to: 3 . is: [3]
|
564
|
+
}
|
553
565
|
}
|
data/tests/block.fy
CHANGED
@@ -32,6 +32,24 @@ FancySpec describe: Block with: {
|
|
32
32
|
i is be: { i >= 10 }
|
33
33
|
}
|
34
34
|
|
35
|
+
it: "calls a block while another is true or calls the alternative" with: 'while_true:else: when: {
|
36
|
+
i = 0
|
37
|
+
{ i < 10 } while_true: {
|
38
|
+
i = i + 1
|
39
|
+
} else: {
|
40
|
+
i = "nope"
|
41
|
+
}
|
42
|
+
i is: 10
|
43
|
+
|
44
|
+
i = 0
|
45
|
+
{ i > 10 } while_true: {
|
46
|
+
i = i + 1
|
47
|
+
} else: {
|
48
|
+
i = "nope"
|
49
|
+
}
|
50
|
+
i is: "nope"
|
51
|
+
}
|
52
|
+
|
35
53
|
it: "calls a block while another is not true (boolean false)" with: 'while_false: when: {
|
36
54
|
i = 0
|
37
55
|
{i == 10} while_false: {
|
@@ -206,17 +224,17 @@ FancySpec describe: Block with: {
|
|
206
224
|
block call: [42] with_receiver: (ClassD new) . is: "in ClassD#inspect: 42"
|
207
225
|
}
|
208
226
|
|
209
|
-
it: "calls a block using
|
227
|
+
it: "calls a block using []" with: '[] when: {
|
210
228
|
b = |x y| {
|
211
229
|
x + y
|
212
230
|
}
|
213
231
|
|
214
232
|
b call: [2,3] . is: 5
|
215
|
-
b(2,3) . is: 5
|
233
|
+
b[(2,3)] . is: 5
|
216
234
|
|
217
235
|
b2 = |x| { x * 5 }
|
218
|
-
b2
|
219
|
-
b2
|
236
|
+
b2["hello"] is: ("hello" * 5)
|
237
|
+
b2["foo"] is: (b2 call: ["foo"])
|
220
238
|
}
|
221
239
|
|
222
240
|
it: "dynamically creates a object with slots defined in a Block" with: 'to_object when: {
|
@@ -239,6 +257,26 @@ FancySpec describe: Block with: {
|
|
239
257
|
}
|
240
258
|
}
|
241
259
|
|
260
|
+
it: "dynamically creates a new object with slots recursively defined in blocks" with: 'to_object_deep when: {
|
261
|
+
o = {
|
262
|
+
name: "Sarah Connor"
|
263
|
+
age: 42
|
264
|
+
city: "Los Angeles"
|
265
|
+
persecuted_by: {
|
266
|
+
name: "The Terminator"
|
267
|
+
age: 'unknown
|
268
|
+
}
|
269
|
+
} to_object_deep
|
270
|
+
|
271
|
+
o name is: "Sarah Connor"
|
272
|
+
o age is: 42
|
273
|
+
o city is: "Los Angeles"
|
274
|
+
o persecuted_by do: {
|
275
|
+
name is: "The Terminator"
|
276
|
+
age is: 'unknown
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
242
280
|
it: "dynamically creates a hash with keys and values defined in a Block" with: 'to_hash when: {
|
243
281
|
{ } to_hash is: <[]>
|
244
282
|
{ foo: "bar" } to_hash is: <['foo => "bar"]>
|
@@ -302,4 +340,65 @@ FancySpec describe: Block with: {
|
|
302
340
|
['city, "San Francisco"],
|
303
341
|
'male, 'programmer, 'happy]
|
304
342
|
}
|
343
|
+
|
344
|
+
it: "returns a Block that calls self then a given Block" with: 'then: when: {
|
345
|
+
a = []
|
346
|
+
block = { a << 1 } then: { a << 2 }
|
347
|
+
block call
|
348
|
+
a is: [1,2]
|
349
|
+
block call
|
350
|
+
a is: [1,2,1,2]
|
351
|
+
}
|
352
|
+
|
353
|
+
it: "returns a Block that calls itself after a given Block" with: 'after: when: {
|
354
|
+
a = []
|
355
|
+
block = { a << 1 } after: { a << 2}
|
356
|
+
block call
|
357
|
+
a is: [2,1]
|
358
|
+
block call
|
359
|
+
a is: [2,1,2,1]
|
360
|
+
}
|
361
|
+
|
362
|
+
it: "calls itself while logging errors to *stdout*" with: 'call_with_errors_logged when: {
|
363
|
+
io = StringIO new
|
364
|
+
let: '*stdout* be: io in: {
|
365
|
+
{
|
366
|
+
"hello" println
|
367
|
+
2 / 0
|
368
|
+
} call_with_errors_logged
|
369
|
+
}
|
370
|
+
io string is: "hello\ndivided by 0\n"
|
371
|
+
}
|
372
|
+
|
373
|
+
it: "calls itself with arguments while logging errors to *stdout*" with: 'call_with_errors_logged: when: {
|
374
|
+
io = StringIO new
|
375
|
+
let: '*stdout* be: io in: {
|
376
|
+
|x y| {
|
377
|
+
"x: #{x} y: #{y}" println
|
378
|
+
2 / 0
|
379
|
+
} call_with_errors_logged: [10, 20]
|
380
|
+
}
|
381
|
+
io string is: "x: 10 y: 20\ndivided by 0\n"
|
382
|
+
}
|
383
|
+
|
384
|
+
it: "calls itself while logging errors to a given IO object" with: 'call_with_errors_logged_to: when: {
|
385
|
+
io = StringIO new
|
386
|
+
{
|
387
|
+
2 / 0
|
388
|
+
} call_with_errors_logged_to: io
|
389
|
+
io string is: "divided by 0\n"
|
390
|
+
|
391
|
+
io = StringIO new
|
392
|
+
{ "fail!" raise! } call_with_errors_logged_to: io
|
393
|
+
io string is: "fail!\n"
|
394
|
+
}
|
395
|
+
|
396
|
+
it: "calls itself with arguments while logging errors to a given IO object" with: 'call:with_errors_logged_to: when: {
|
397
|
+
io = StringIO new
|
398
|
+
|x y| {
|
399
|
+
io println: "x: #{x} y: #{y}"
|
400
|
+
2 / 0
|
401
|
+
} call: [10, 20] with_errors_logged_to: io
|
402
|
+
io string is: "x: 10 y: 20\ndivided by 0\n"
|
403
|
+
}
|
305
404
|
}
|