fancy 0.3.3 → 0.4.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/README.md +14 -14
- data/Rakefile +16 -4
- data/bin/fancy +3 -0
- data/bin/fspec +20 -0
- data/bin/fyi +27 -11
- data/bin/ifancy +1 -1
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/block_env.rb +1 -9
- data/boot/fancy_ext/delegator.rb +64 -0
- data/boot/fancy_ext/object.rb +4 -0
- data/boot/fancy_ext/thread.rb +4 -0
- data/boot/load.rb +5 -1
- data/boot/rbx-compiler/compiler/ast.rb +0 -1
- data/boot/rbx-compiler/compiler/ast/class_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +10 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +12 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +2 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.lex +5 -11
- data/boot/rbx-compiler/parser/parser.rb +16 -5
- data/boot/rbx-compiler/parser/parser.y +39 -24
- data/doc/api/fancy.css +1 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +22 -4
- data/doc/api/index.html +5 -6
- data/doc/api/jquery-ui.min.js +401 -0
- data/doc/api/jquery.tools.min.js +192 -0
- data/doc/api/themeswitchertool.js +250 -0
- data/doc/features.md +17 -0
- data/examples/actor_bunnies.fy +32 -0
- data/examples/actors.fy +26 -0
- data/examples/actors_primitive.fy +27 -0
- data/examples/actors_ring.fy +37 -0
- data/examples/armstrong_numbers.fy +1 -1
- data/examples/array.fy +7 -9
- data/examples/async_send.fy +1 -2
- data/examples/blocks.fy +4 -4
- data/examples/call_with_receiver.fy +1 -1
- data/examples/class.fy +1 -1
- data/examples/default_args.fy +4 -1
- data/examples/define_methods.fy +2 -2
- data/examples/echo.fy +1 -1
- data/examples/factorial.fy +1 -1
- data/examples/future_composition.fy +2 -2
- data/examples/futures.fy +0 -5
- data/examples/game_of_life.fy +1 -1
- data/examples/person.fy +1 -1
- data/lib/argv.fy +7 -2
- data/lib/array.fy +109 -42
- data/lib/block.fy +39 -14
- data/lib/boot.fy +2 -0
- data/lib/class.fy +2 -0
- data/lib/compiler/ast.fy +2 -1
- data/lib/compiler/ast/assign.fy +2 -3
- data/lib/compiler/ast/async_send.fy +1 -15
- data/lib/compiler/ast/class_def.fy +2 -1
- data/lib/compiler/ast/expression_list.fy +4 -5
- data/lib/compiler/ast/future_send.fy +1 -10
- data/lib/compiler/ast/goto.fy +46 -0
- data/lib/compiler/ast/identifier.fy +9 -7
- data/lib/compiler/ast/literals.fy +8 -1
- data/lib/compiler/ast/match.fy +14 -4
- data/lib/compiler/ast/message_send.fy +34 -6
- data/lib/compiler/ast/method_def.fy +6 -6
- data/lib/compiler/ast/node.fy +3 -3
- data/lib/compiler/ast/range.fy +1 -0
- data/lib/compiler/ast/script.fy +0 -2
- data/lib/compiler/ast/singleton_method_def.fy +2 -4
- data/lib/compiler/ast/string_interpolation.fy +17 -0
- data/lib/compiler/ast/super.fy +5 -4
- data/lib/compiler/ast/try_catch.fy +8 -6
- data/lib/compiler/ast/tuple_literal.fy +3 -2
- data/lib/compiler/command.fy +0 -1
- data/lib/compiler/compiler.fy +1 -5
- data/lib/compiler/stages.fy +6 -14
- data/lib/documentation.fy +57 -46
- data/lib/enumerable.fy +257 -23
- data/lib/enumerator.fy +122 -15
- data/lib/false_class.fy +10 -1
- data/lib/fancy_spec.fy +263 -61
- data/lib/fdoc.fy +11 -25
- data/lib/fiber.fy +11 -0
- data/lib/file.fy +8 -11
- data/lib/future.fy +84 -5
- data/lib/hash.fy +65 -14
- data/lib/integer.fy +35 -0
- data/lib/iteration.fy +54 -29
- data/lib/message.fy +6 -0
- data/lib/method.fy +0 -16
- data/lib/nil_class.fy +58 -8
- data/lib/number.fy +49 -22
- data/lib/object.fy +371 -65
- data/lib/package.fy +24 -1
- data/lib/package/installer.fy +5 -9
- data/lib/package/specification.fy +2 -2
- data/lib/parser/ext/lexer.lex +15 -11
- data/lib/parser/ext/parser.y +70 -23
- data/lib/parser/methods.fy +33 -14
- data/lib/proxy.fy +33 -3
- data/lib/range.fy +28 -0
- data/lib/rbx.fy +3 -1
- data/lib/rbx/actor.fy +53 -0
- data/lib/rbx/alpha.fy +31 -0
- data/lib/rbx/array.fy +21 -12
- data/lib/rbx/bignum.fy +6 -2
- data/lib/rbx/block.fy +23 -26
- data/lib/rbx/class.fy +54 -2
- data/lib/rbx/code_loader.fy +8 -4
- data/lib/rbx/date.fy +9 -0
- data/lib/rbx/directory.fy +18 -0
- data/lib/rbx/environment_variables.fy +1 -0
- data/lib/rbx/exception.fy +9 -2
- data/lib/rbx/fiber.fy +22 -4
- data/lib/rbx/file.fy +5 -5
- data/lib/rbx/fixnum.fy +5 -0
- data/lib/rbx/float.fy +11 -3
- data/lib/rbx/hash.fy +31 -16
- data/lib/rbx/integer.fy +1 -0
- data/lib/rbx/io.fy +17 -7
- data/lib/rbx/match_data.fy +15 -4
- data/lib/rbx/method.fy +40 -7
- data/lib/rbx/name_error.fy +4 -0
- data/lib/rbx/object.fy +92 -24
- data/lib/rbx/range.fy +20 -6
- data/lib/rbx/regexp.fy +11 -3
- data/lib/rbx/string.fy +51 -1
- data/lib/rbx/stringio.fy +17 -0
- data/lib/rbx/symbol.fy +15 -1
- data/lib/rbx/system.fy +20 -2
- data/lib/rbx/tcp_server.fy +4 -1
- data/lib/rbx/tcp_socket.fy +11 -0
- data/lib/rbx/time.fy +6 -0
- data/lib/rbx/tuple.fy +14 -5
- data/lib/set.fy +144 -29
- data/lib/stack.fy +42 -11
- data/lib/string.fy +118 -8
- data/lib/struct.fy +13 -3
- data/lib/symbol.fy +21 -2
- data/lib/thread_pool.fy +2 -1
- data/lib/true_class.fy +45 -7
- data/lib/tuple.fy +27 -9
- data/lib/version.fy +2 -2
- data/ruby_lib/fancy +43 -0
- data/ruby_lib/fdoc +23 -0
- data/ruby_lib/fspec +3 -0
- data/ruby_lib/fyi +3 -0
- data/ruby_lib/ifancy +3 -0
- data/tests/argv.fy +5 -9
- data/tests/array.fy +323 -196
- data/tests/assignment.fy +29 -29
- data/tests/block.fy +72 -59
- data/tests/class.fy +227 -138
- data/tests/control_flow.fy +83 -51
- data/tests/documentation.fy +8 -8
- data/tests/enumerable.fy +8 -0
- data/tests/enumerator.fy +47 -29
- data/tests/exception.fy +49 -32
- data/tests/file.fy +28 -28
- data/tests/fixnum.fy +170 -0
- data/tests/future.fy +24 -7
- data/tests/hash.fy +55 -38
- data/tests/method.fy +50 -43
- data/tests/nil_class.fy +37 -37
- data/tests/object.fy +152 -70
- data/tests/pattern_matching.fy +67 -31
- data/tests/range.fy +6 -6
- data/tests/set.fy +101 -4
- data/tests/stack.fy +14 -5
- data/tests/string.fy +115 -61
- data/tests/stringio.fy +18 -0
- data/tests/struct.fy +27 -0
- data/tests/symbol.fy +19 -6
- data/tests/true_class.fy +34 -34
- data/tests/tuple.fy +30 -12
- metadata +103 -81
- data/boot/rbx-compiler/compiler/ast/require.rb +0 -20
- data/examples/actor.fy +0 -37
- data/examples/curl_async.fy +0 -37
- data/lib/compiler/ast/require.fy +0 -15
- data/tests/number.fy +0 -135
- data/tests/parsing/sexp.fy +0 -50
data/tests/assignment.fy
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
FancySpec describe: "Assignment" with: {
|
|
2
|
-
it: "
|
|
2
|
+
it: "correctly assigns multiple values at once" when: {
|
|
3
3
|
x, y, z = 1, 10, 100
|
|
4
|
-
x
|
|
5
|
-
y
|
|
6
|
-
z
|
|
4
|
+
x is: 1
|
|
5
|
+
y is: 10
|
|
6
|
+
z is: 100
|
|
7
7
|
|
|
8
8
|
x, y, z = 'foo, 'bar
|
|
9
|
-
x
|
|
10
|
-
y
|
|
11
|
-
z
|
|
9
|
+
x is: 'foo
|
|
10
|
+
y is: 'bar
|
|
11
|
+
z is: nil
|
|
12
12
|
|
|
13
13
|
x = 'foo
|
|
14
14
|
y = 'bar
|
|
15
15
|
x, y = y, x
|
|
16
|
-
x
|
|
17
|
-
y
|
|
16
|
+
x is: 'bar
|
|
17
|
+
y is: 'foo
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
it: "
|
|
20
|
+
it: "handles multiple assignment for any collection type implementing 'at:" when: {
|
|
21
21
|
x, y, z = (1, 2, 3)
|
|
22
|
-
x
|
|
23
|
-
y
|
|
24
|
-
z
|
|
22
|
+
x is: 1
|
|
23
|
+
y is: 2
|
|
24
|
+
z is: 3
|
|
25
25
|
|
|
26
26
|
a, b, c = ["a", "b", "c"]
|
|
27
|
-
a
|
|
28
|
-
b
|
|
29
|
-
c
|
|
27
|
+
a is: "a"
|
|
28
|
+
b is: "b"
|
|
29
|
+
c is: "c"
|
|
30
30
|
|
|
31
31
|
e, f = ([1,2], "foo")
|
|
32
|
-
e
|
|
33
|
-
f
|
|
32
|
+
e is: [1,2]
|
|
33
|
+
f is: "foo"
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
it: "
|
|
36
|
+
it: "handles multiple assignment with splat-identifiers" when: {
|
|
37
37
|
x,y,z,*rest = [1,2,3,4,5,6,7]
|
|
38
|
-
x
|
|
39
|
-
y
|
|
40
|
-
z
|
|
41
|
-
rest
|
|
38
|
+
x is: 1
|
|
39
|
+
y is: 2
|
|
40
|
+
z is: 3
|
|
41
|
+
rest is: [4,5,6,7]
|
|
42
42
|
|
|
43
43
|
a,b,*c,*d,e = [1,2,3,4,5,6,7,8]
|
|
44
|
-
a
|
|
45
|
-
b
|
|
46
|
-
c
|
|
47
|
-
d
|
|
48
|
-
e
|
|
44
|
+
a is: 1
|
|
45
|
+
b is: 2
|
|
46
|
+
c is: [3,4,5,6,7,8]
|
|
47
|
+
d is: [4,5,6,7,8]
|
|
48
|
+
e is: 5
|
|
49
49
|
|
|
50
50
|
_,_,*z = "hello, world!" # ignore first 2 characters
|
|
51
|
-
z
|
|
51
|
+
z is: "llo, world!"
|
|
52
52
|
}
|
|
53
53
|
}
|
data/tests/block.fy
CHANGED
|
@@ -1,146 +1,146 @@
|
|
|
1
1
|
FancySpec describe: Block with: {
|
|
2
|
-
it: "
|
|
2
|
+
it: "returns the value of the last expression" when: {
|
|
3
3
|
block = {
|
|
4
4
|
a = "a"
|
|
5
5
|
empty = " "
|
|
6
6
|
str = "String!"
|
|
7
7
|
a ++ empty ++ str
|
|
8
8
|
}
|
|
9
|
-
block call
|
|
9
|
+
block call is: "a String!"
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
it: "
|
|
12
|
+
it: "closes over a value and change it internally" when: {
|
|
13
13
|
x = 0
|
|
14
14
|
{ x < 10 } while_true: {
|
|
15
|
-
x
|
|
15
|
+
x is be: |x| { x < 10 }
|
|
16
16
|
x = x + 1
|
|
17
17
|
}
|
|
18
|
-
x
|
|
18
|
+
x is: 10
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
it: "
|
|
22
|
-
{ }
|
|
23
|
-
|x| { }
|
|
24
|
-
|x y z| { }
|
|
21
|
+
it: "returns the argument count" with: 'arity when: {
|
|
22
|
+
{ } arity . is: 0
|
|
23
|
+
|x| { } arity . is: 1
|
|
24
|
+
|x y z| { } arity . is: 3
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
it: "
|
|
27
|
+
it: "calls a block while another is true" with: 'while_true: when: {
|
|
28
28
|
i = 0
|
|
29
29
|
{i < 10} while_true: {
|
|
30
30
|
i = i + 1
|
|
31
31
|
}
|
|
32
|
-
i
|
|
32
|
+
i is be: { i >= 10 }
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
it: "
|
|
35
|
+
it: "calls a block while another is not true (boolean false)" with: 'while_false: when: {
|
|
36
36
|
i = 0
|
|
37
37
|
{i == 10} while_false: {
|
|
38
38
|
i = i + 1
|
|
39
39
|
}
|
|
40
|
-
i
|
|
40
|
+
i is: 10
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
# again for while_nil
|
|
44
|
-
it: "
|
|
44
|
+
it: "calls a block while another is nil" with: 'while_nil: when: {
|
|
45
45
|
i = 0
|
|
46
46
|
{i == 10} while_nil: {
|
|
47
47
|
i = i + 1
|
|
48
48
|
}
|
|
49
|
-
i
|
|
49
|
+
i is: 10
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
it: "
|
|
52
|
+
it: "calls a block while another one is true-ish" with: 'while_do: when: {
|
|
53
53
|
x = 0
|
|
54
54
|
{ x < 10 } while_do: |val| {
|
|
55
|
-
val
|
|
55
|
+
val is: true
|
|
56
56
|
x = x + 1
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
it: "
|
|
60
|
+
it: "calls another block while a block yields false" with: 'until_do: when: {
|
|
61
61
|
i = 0
|
|
62
|
-
{ i > 10 } until_do: { i <= 10
|
|
63
|
-
i
|
|
62
|
+
{ i > 10 } until_do: { i <= 10 is: true; i = i + 1 }
|
|
63
|
+
i is: 11
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
it: "
|
|
66
|
+
it: "calls a block until another yields true" with: 'until: when: {
|
|
67
67
|
i = 0
|
|
68
|
-
{ i <= 10
|
|
69
|
-
i
|
|
68
|
+
{ i <= 10 is: true; i = i + 1 } until: { i > 10 }
|
|
69
|
+
i is: 11
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
it: "
|
|
72
|
+
it: "calls itself only when the argument is nil" with: 'unless: when: {
|
|
73
73
|
try {
|
|
74
74
|
{ StdError new: "got_run!" . raise! } unless: nil
|
|
75
75
|
StdError new: "didnt_run!" . raise!
|
|
76
76
|
} catch StdError => e {
|
|
77
|
-
e message
|
|
77
|
+
e message is: "got_run!"
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
it: "
|
|
81
|
+
it: "calls itself only when the argument is true" with: 'if: when: {
|
|
82
82
|
try {
|
|
83
83
|
{ StdError new: "got_run!" . raise! } if: true
|
|
84
84
|
StdError new: "didnt_run!" . raise!
|
|
85
85
|
} catch StdError => e {
|
|
86
|
-
e message
|
|
86
|
+
e message is: "got_run!"
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
it: "
|
|
90
|
+
it: "also is able to take arguments seperated by comma" with: 'call: when: {
|
|
91
91
|
block = |x, y| { x + y }
|
|
92
|
-
block call: [1,2] .
|
|
92
|
+
block call: [1,2] . is: 3
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
it: "
|
|
96
|
-
{ false } && { false }
|
|
97
|
-
{ true } && { false }
|
|
98
|
-
{ false } && { true }
|
|
99
|
-
{ true } && { true }
|
|
95
|
+
it: "evaluates the blocks in a short-circuiting manner" with: '&& when: {
|
|
96
|
+
{ false } && { false } is: false
|
|
97
|
+
{ true } && { false } is: false
|
|
98
|
+
{ false } && { true } is: false
|
|
99
|
+
{ true } && { true } is: true
|
|
100
100
|
|
|
101
|
-
{ false } || { false }
|
|
102
|
-
{ false } || { true }
|
|
103
|
-
{ true } || { false }
|
|
104
|
-
{ true } || { true }
|
|
101
|
+
{ false } || { false } is: false
|
|
102
|
+
{ false } || { true } is: true
|
|
103
|
+
{ true } || { false } is: true
|
|
104
|
+
{ true } || { true } is: true
|
|
105
105
|
|
|
106
106
|
# TODO: Add more useful tests here...
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
it: "
|
|
110
|
-
[1,2,3] map: @{upto: 3} .
|
|
111
|
-
[1,2,3] map: @{+ 3} .
|
|
112
|
-
[1,2,3] map: @{to_s} .
|
|
113
|
-
[1,2,3] map: @{to_s * 3} .
|
|
109
|
+
it: "calls the block as a partial block" when: {
|
|
110
|
+
[1,2,3] map: @{upto: 3} . is: [[1,2,3], [2,3], [3]]
|
|
111
|
+
[1,2,3] map: @{+ 3} . is: [4,5,6]
|
|
112
|
+
[1,2,3] map: @{to_s} . is: ["1", "2", "3"]
|
|
113
|
+
[1,2,3] map: @{to_s * 3} . is: ["111", "222", "333"]
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
it: "
|
|
116
|
+
it: "executes a match clause if the block returns a true-ish value" with: '=== when: {
|
|
117
117
|
def do_match: val {
|
|
118
118
|
match val {
|
|
119
119
|
case |x| { x even? } -> "yup, it's even"
|
|
120
120
|
case _ -> "nope, not even"
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
do_match: 2 .
|
|
124
|
-
do_match: 1 .
|
|
123
|
+
do_match: 2 . is: "yup, it's even"
|
|
124
|
+
do_match: 1 . is: "nope, not even"
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
it: "
|
|
127
|
+
it: "returns the receiver of a block" with: 'receiver when: {
|
|
128
128
|
class Foo { def foo { { self } } } # return block
|
|
129
129
|
f = Foo new
|
|
130
|
-
f foo receiver
|
|
130
|
+
f foo receiver is: f
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
it: "
|
|
133
|
+
it: "sets the receiver correctly to a new value" with: 'receiver: when: {
|
|
134
134
|
b = { "hey" }
|
|
135
135
|
|
|
136
136
|
b receiver: 10
|
|
137
|
-
b receiver
|
|
137
|
+
b receiver is: 10
|
|
138
138
|
|
|
139
139
|
b receiver: "Hello, World!"
|
|
140
|
-
b receiver
|
|
140
|
+
b receiver is: "Hello, World!"
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
it: "
|
|
143
|
+
it: "calls a block with a different receiver" with: 'call_with_receiver: when: {
|
|
144
144
|
class ClassA {
|
|
145
145
|
def inspect {
|
|
146
146
|
"in ClassA#inspect"
|
|
@@ -157,12 +157,12 @@ FancySpec describe: Block with: {
|
|
|
157
157
|
block = {
|
|
158
158
|
self inspect
|
|
159
159
|
}
|
|
160
|
-
block call
|
|
161
|
-
block call_with_receiver: (ClassA new) .
|
|
162
|
-
block call_with_receiver: (ClassB new) .
|
|
160
|
+
block call is: "in self#inspect"
|
|
161
|
+
block call_with_receiver: (ClassA new) . is: "in ClassA#inspect"
|
|
162
|
+
block call_with_receiver: (ClassB new) . is: "in ClassB#inspect"
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
it: "
|
|
165
|
+
it: "calls a block with arguments and a different receiver" with: 'call:with_receiver: when: {
|
|
166
166
|
class ClassC {
|
|
167
167
|
def inspect: x {
|
|
168
168
|
"in ClassC#inspect: #{x}"
|
|
@@ -179,8 +179,21 @@ FancySpec describe: Block with: {
|
|
|
179
179
|
block = |arg| {
|
|
180
180
|
self inspect: arg
|
|
181
181
|
}
|
|
182
|
-
block call: [42] .
|
|
183
|
-
block call: [42] with_receiver: (ClassC new) .
|
|
184
|
-
block call: [42] with_receiver: (ClassD new) .
|
|
182
|
+
block call: [42] . is: "in self#inspect: 42"
|
|
183
|
+
block call: [42] with_receiver: (ClassC new) . is: "in ClassC#inspect: 42"
|
|
184
|
+
block call: [42] with_receiver: (ClassD new) . is: "in ClassD#inspect: 42"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
it: "calls a block using the ruby-send syntax" with: 'call: when: {
|
|
188
|
+
b = |x y| {
|
|
189
|
+
x + y
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
b call: [2,3] . is: 5
|
|
193
|
+
b(2,3) . is: 5
|
|
194
|
+
|
|
195
|
+
b2 = |x| { x * 5 }
|
|
196
|
+
b2("hello") is: ("hello" * 5)
|
|
197
|
+
b2("foo") is: (b2 call: ["foo"])
|
|
185
198
|
}
|
|
186
199
|
}
|
data/tests/class.fy
CHANGED
|
@@ -25,98 +25,100 @@ class ClassWithPrivate {
|
|
|
25
25
|
"public!"
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
def
|
|
28
|
+
def protected_method {
|
|
29
29
|
"protected!"
|
|
30
30
|
}
|
|
31
|
+
protected: 'protected_method
|
|
31
32
|
|
|
32
|
-
def
|
|
33
|
+
def private_method {
|
|
33
34
|
"private!"
|
|
34
35
|
}
|
|
36
|
+
private: 'private_method
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
FancySpec describe: Class with: {
|
|
38
|
-
it: "
|
|
40
|
+
it: "does NOT find the method when not mixed-in" with: 'responds_to?: when: {
|
|
39
41
|
instance = ClassWithMixin new
|
|
40
|
-
instance normal_method .
|
|
41
|
-
instance responds_to?: 'normal_method .
|
|
42
|
-
instance responds_to?: 'mixin_method .
|
|
42
|
+
instance normal_method . is: 'normal_found
|
|
43
|
+
instance responds_to?: 'normal_method . is: true
|
|
44
|
+
instance responds_to?: 'mixin_method . is: false
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
it: "
|
|
47
|
+
it: "finds the method when mixed-in" with: 'include: when: {
|
|
46
48
|
# => include Mixin into ClassWithMixin
|
|
47
49
|
class ClassWithMixin {
|
|
48
50
|
include: Mixin
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
instance = ClassWithMixin new
|
|
52
|
-
instance responds_to?: 'normal_method .
|
|
53
|
-
instance responds_to?: 'mixin_method .
|
|
54
|
-
instance normal_method .
|
|
55
|
-
instance mixin_method .
|
|
54
|
+
instance responds_to?: 'normal_method . is: true
|
|
55
|
+
instance responds_to?: 'mixin_method . is: true
|
|
56
|
+
instance normal_method . is: 'normal_found
|
|
57
|
+
instance mixin_method . is: 'mixed_in_found
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
it: "
|
|
60
|
+
it: "rebinds the old class name with ClassWithNoMixin and replace the old normal_method" when: {
|
|
59
61
|
instance = ClassWithMixin new
|
|
60
|
-
instance normal_method
|
|
62
|
+
instance normal_method is: 'normal_found
|
|
61
63
|
# rebind the class to the other class
|
|
62
64
|
ClassWithMixin = ClassWithNoMixin
|
|
63
65
|
instance = ClassWithMixin new
|
|
64
|
-
instance normal_method
|
|
66
|
+
instance normal_method is: 'new_normal_found
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
it: "
|
|
69
|
+
it: "has dynamically generated getter and setter methods" with: 'responds_to?: when: {
|
|
68
70
|
instance = ClassWithNoMixin new
|
|
69
|
-
instance responds_to?: 'foo .
|
|
70
|
-
instance responds_to?: 'bar .
|
|
71
|
-
instance responds_to?: 'baz .
|
|
72
|
-
instance responds_to?: "hello:" .
|
|
73
|
-
instance responds_to?: "world:" .
|
|
74
|
-
instance responds_to?: 'oh .
|
|
75
|
-
instance responds_to?: ":oh" .
|
|
76
|
-
instance responds_to?: 'noes .
|
|
77
|
-
instance responds_to?: "noes:" .
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
it: "
|
|
71
|
+
instance responds_to?: 'foo . is: true
|
|
72
|
+
instance responds_to?: 'bar . is: true
|
|
73
|
+
instance responds_to?: 'baz . is: true
|
|
74
|
+
instance responds_to?: "hello:" . is: true
|
|
75
|
+
instance responds_to?: "world:" . is: true
|
|
76
|
+
instance responds_to?: 'oh . is: true
|
|
77
|
+
instance responds_to?: ":oh" . is: true
|
|
78
|
+
instance responds_to?: 'noes . is: true
|
|
79
|
+
instance responds_to?: "noes:" . is: true
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
it: "defines getter methods for single slots" with: 'read_slot: when: {
|
|
81
83
|
class Getters {
|
|
82
84
|
read_slot: 'foo
|
|
83
85
|
read_slot: 'bar
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
g = Getters new
|
|
87
|
-
g responds_to?: 'foo .
|
|
88
|
-
g responds_to?: 'foo: .
|
|
89
|
-
g responds_to?: 'bar .
|
|
90
|
-
g responds_to?: 'bar: .
|
|
89
|
+
g responds_to?: 'foo . is: true
|
|
90
|
+
g responds_to?: 'foo: . is: false
|
|
91
|
+
g responds_to?: 'bar . is: true
|
|
92
|
+
g responds_to?: 'bar: . is: false
|
|
91
93
|
}
|
|
92
94
|
|
|
93
|
-
it: "
|
|
95
|
+
it: "defines setter methods for single slots" with: 'write_slot: when: {
|
|
94
96
|
class Setters {
|
|
95
97
|
write_slot: 'foo
|
|
96
98
|
write_slot: 'bar
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
s = Setters new
|
|
100
|
-
s responds_to?: 'foo .
|
|
101
|
-
s responds_to?: 'foo: .
|
|
102
|
-
s responds_to?: 'bar .
|
|
103
|
-
s responds_to?: 'bar: .
|
|
102
|
+
s responds_to?: 'foo . is: false
|
|
103
|
+
s responds_to?: 'foo: . is: true
|
|
104
|
+
s responds_to?: 'bar . is: false
|
|
105
|
+
s responds_to?: 'bar: . is: true
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
it: "
|
|
108
|
+
it: "defines getter & setter methods for single slots" with: 'read_write_slot: when: {
|
|
107
109
|
class GettersAndSetters {
|
|
108
110
|
read_write_slot: 'foo
|
|
109
111
|
read_write_slot: 'bar
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
gs = GettersAndSetters new
|
|
113
|
-
gs responds_to?: 'foo .
|
|
114
|
-
gs responds_to?: 'foo: .
|
|
115
|
-
gs responds_to?: 'bar .
|
|
116
|
-
gs responds_to?: 'bar: .
|
|
115
|
+
gs responds_to?: 'foo . is: true
|
|
116
|
+
gs responds_to?: 'foo: . is: true
|
|
117
|
+
gs responds_to?: 'bar . is: true
|
|
118
|
+
gs responds_to?: 'bar: . is: true
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
it: "
|
|
121
|
+
it: "finds the instance variable correctly" when: {
|
|
120
122
|
class AClass {
|
|
121
123
|
def initialize: foo {
|
|
122
124
|
@foo = foo
|
|
@@ -128,11 +130,11 @@ FancySpec describe: Class with: {
|
|
|
128
130
|
|
|
129
131
|
str = "instance value"
|
|
130
132
|
instance = AClass new: str
|
|
131
|
-
instance foo
|
|
132
|
-
AClass new foo
|
|
133
|
+
instance foo is: str
|
|
134
|
+
AClass new foo is: nil
|
|
133
135
|
}
|
|
134
136
|
|
|
135
|
-
it: "
|
|
137
|
+
it: "finds the class variable correctly" when: {
|
|
136
138
|
class AClass {
|
|
137
139
|
def foo: foo {
|
|
138
140
|
@@foo = foo
|
|
@@ -146,17 +148,17 @@ FancySpec describe: Class with: {
|
|
|
146
148
|
instance2 = AClass new
|
|
147
149
|
str = "class value"
|
|
148
150
|
instance1 foo: str
|
|
149
|
-
instance1 foo
|
|
150
|
-
instance2 foo
|
|
151
|
-
instance2 foo
|
|
151
|
+
instance1 foo is: str
|
|
152
|
+
instance2 foo is: str
|
|
153
|
+
instance2 foo is: (instance1 foo)
|
|
152
154
|
|
|
153
155
|
str2 = "another value"
|
|
154
156
|
instance2 foo: str2
|
|
155
|
-
instance2 foo
|
|
156
|
-
instance1 foo
|
|
157
|
+
instance2 foo is: str2
|
|
158
|
+
instance1 foo is: str2
|
|
157
159
|
}
|
|
158
160
|
|
|
159
|
-
it: "
|
|
161
|
+
it: "has correct method overloading for method names with and without an argument" when: {
|
|
160
162
|
class AClass {
|
|
161
163
|
def foo {
|
|
162
164
|
foo: "None!"
|
|
@@ -168,11 +170,11 @@ FancySpec describe: Class with: {
|
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
instance = AClass new
|
|
171
|
-
instance foo
|
|
172
|
-
instance foo: "Test!" .
|
|
173
|
+
instance foo is: "In AClass#foo: with bar = None!"
|
|
174
|
+
instance foo: "Test!" . is: "In AClass#foo: with bar = Test!"
|
|
173
175
|
}
|
|
174
176
|
|
|
175
|
-
it: "
|
|
177
|
+
it: "calls a superclass method by using super" when: {
|
|
176
178
|
class SuperClass {
|
|
177
179
|
read_slots: ['name]
|
|
178
180
|
def initialize: name {
|
|
@@ -193,76 +195,76 @@ FancySpec describe: Class with: {
|
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
sub = SubClass new: 42
|
|
196
|
-
sub name
|
|
197
|
-
sub age
|
|
198
|
+
sub name is: "SubClass"
|
|
199
|
+
sub age is: 42
|
|
198
200
|
|
|
199
201
|
sub2 = SubClass new
|
|
200
|
-
sub2 name
|
|
201
|
-
sub2 age
|
|
202
|
+
sub2 name is: "SubClass"
|
|
203
|
+
sub2 age is: 0
|
|
202
204
|
}
|
|
203
205
|
|
|
204
|
-
it: "
|
|
205
|
-
Fixnum superclass
|
|
206
|
-
Symbol superclass
|
|
207
|
-
StdError superclass
|
|
208
|
-
Class superclass
|
|
209
|
-
Object superclass
|
|
206
|
+
it: "returns its superclass" when: {
|
|
207
|
+
Fixnum superclass is: Integer
|
|
208
|
+
Symbol superclass is: Object
|
|
209
|
+
StdError superclass is: Exception
|
|
210
|
+
Class superclass is: Module
|
|
211
|
+
Object superclass is: nil
|
|
210
212
|
|
|
211
|
-
IOError superclass
|
|
212
|
-
NoMethodError superclass
|
|
213
|
+
IOError superclass is: StandardError
|
|
214
|
+
NoMethodError superclass is: NameError
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
it: "
|
|
217
|
+
it: "creates a new Class dynamically" when: {
|
|
216
218
|
x = Class new
|
|
217
|
-
x is_a?: Class .
|
|
218
|
-
x new is_a?: x .
|
|
219
|
-
x new is_a?: Object .
|
|
220
|
-
x new class
|
|
219
|
+
x is_a?: Class . is: true
|
|
220
|
+
x new is_a?: x . is: true
|
|
221
|
+
x new is_a?: Object . is: true
|
|
222
|
+
x new class is: x
|
|
221
223
|
|
|
222
224
|
# Symbol as superclass
|
|
223
225
|
y = Class new: String
|
|
224
|
-
y is_a?: Class .
|
|
225
|
-
y new is_a?: String .
|
|
226
|
-
|
|
226
|
+
y is_a?: Class . is: true
|
|
227
|
+
y new is_a?: String . is: true
|
|
228
|
+
y new is_a?: Object . is: true
|
|
227
229
|
}
|
|
228
230
|
|
|
229
|
-
it: "
|
|
231
|
+
it: "only is able to call the public method from outside the Class" when: {
|
|
230
232
|
x = ClassWithPrivate new
|
|
231
|
-
x public_method
|
|
233
|
+
x public_method is: "public!"
|
|
232
234
|
try {
|
|
233
|
-
x private_method
|
|
235
|
+
x private_method is: nil # is fail
|
|
234
236
|
} catch NoMethodError => e {
|
|
235
|
-
e method_name
|
|
237
|
+
e method_name is: 'private_method
|
|
236
238
|
}
|
|
237
239
|
try {
|
|
238
|
-
x protected_method
|
|
240
|
+
x protected_method is: nil # is fail
|
|
239
241
|
} catch NoMethodError => e {
|
|
240
|
-
e method_name
|
|
242
|
+
e method_name is: 'protected_method
|
|
241
243
|
}
|
|
242
244
|
}
|
|
243
245
|
|
|
244
|
-
it: "
|
|
246
|
+
it: "is a subclass of another Class" with: 'subclass?: when: {
|
|
245
247
|
class Super {
|
|
246
248
|
}
|
|
247
249
|
class Sub : Super {
|
|
248
250
|
}
|
|
249
251
|
|
|
250
|
-
Super subclass?: Object .
|
|
251
|
-
Sub subclass?: Object .
|
|
252
|
-
Sub subclass?: Super .
|
|
253
|
-
Super subclass?: Sub .
|
|
252
|
+
Super subclass?: Object . is: true
|
|
253
|
+
Sub subclass?: Object . is: true
|
|
254
|
+
Sub subclass?: Super . is: true
|
|
255
|
+
Super subclass?: Sub . is: nil
|
|
254
256
|
}
|
|
255
257
|
|
|
256
|
-
it: "
|
|
258
|
+
it: "dynamically creates a subclass of another class" with: 'is_a?: when: {
|
|
257
259
|
subclass = String subclass: {
|
|
258
260
|
def foo {
|
|
259
261
|
"hello, world!"
|
|
260
262
|
}
|
|
261
263
|
}
|
|
262
|
-
subclass is_a?: Class .
|
|
263
|
-
subclass subclass?: String .
|
|
264
|
-
subclass new is_a?: subclass .
|
|
265
|
-
subclass new foo
|
|
264
|
+
subclass is_a?: Class . is: true
|
|
265
|
+
subclass subclass?: String . is: true
|
|
266
|
+
subclass new is_a?: subclass . is: true
|
|
267
|
+
subclass new foo is: "hello, world!"
|
|
266
268
|
|
|
267
269
|
# now the same with Class##new:body:
|
|
268
270
|
subclass2 = Class superclass: String body: {
|
|
@@ -270,53 +272,53 @@ FancySpec describe: Class with: {
|
|
|
270
272
|
"hello, world, again!"
|
|
271
273
|
}
|
|
272
274
|
}
|
|
273
|
-
subclass2 is_a?: Class .
|
|
274
|
-
subclass2 subclass?: String .
|
|
275
|
-
subclass2 new is_a?: subclass2 .
|
|
276
|
-
subclass2 new foo
|
|
275
|
+
subclass2 is_a?: Class . is: true
|
|
276
|
+
subclass2 subclass?: String . is: true
|
|
277
|
+
subclass2 new is_a?: subclass2 . is: true
|
|
278
|
+
subclass2 new foo is: "hello, world, again!"
|
|
277
279
|
}
|
|
278
280
|
|
|
279
|
-
it: "
|
|
281
|
+
it: "undefines an instance method" with: 'undefine_method: when: {
|
|
280
282
|
class Foo {
|
|
281
283
|
def instance_method {
|
|
282
284
|
"instance method!"
|
|
283
285
|
}
|
|
284
286
|
}
|
|
285
287
|
f = Foo new
|
|
286
|
-
f instance_method
|
|
288
|
+
f instance_method is: "instance method!"
|
|
287
289
|
Foo undefine_method: 'instance_method
|
|
288
290
|
try {
|
|
289
|
-
f instance_method
|
|
291
|
+
f instance_method is: nil # is not get here
|
|
290
292
|
} catch NoMethodError => e {
|
|
291
|
-
e method_name
|
|
293
|
+
e method_name is: 'instance_method
|
|
292
294
|
}
|
|
293
295
|
}
|
|
294
296
|
|
|
295
|
-
it: "
|
|
297
|
+
it: "undefines a class method" with: 'undefine_class_method: when: {
|
|
296
298
|
class Foo {
|
|
297
299
|
def self class_method {
|
|
298
300
|
"class method!"
|
|
299
301
|
}
|
|
300
302
|
}
|
|
301
|
-
Foo class_method
|
|
303
|
+
Foo class_method is: "class method!"
|
|
302
304
|
|
|
303
305
|
try {
|
|
304
306
|
Foo undefine_method: 'class_method
|
|
305
|
-
true
|
|
307
|
+
true is: nil # is not happen
|
|
306
308
|
} catch NameError {
|
|
307
|
-
true
|
|
309
|
+
true is: true
|
|
308
310
|
}
|
|
309
311
|
|
|
310
312
|
Foo undefine_class_method: 'class_method
|
|
311
313
|
|
|
312
314
|
try {
|
|
313
|
-
Foo class_method
|
|
315
|
+
Foo class_method is: nil # is not get here
|
|
314
316
|
} catch NoMethodError => e {
|
|
315
|
-
e method_name
|
|
317
|
+
e method_name is: 'class_method
|
|
316
318
|
}
|
|
317
319
|
}
|
|
318
320
|
|
|
319
|
-
it: "
|
|
321
|
+
it: "has nested classes" when: {
|
|
320
322
|
class Outer {
|
|
321
323
|
class Inner {
|
|
322
324
|
class InnerMost {
|
|
@@ -326,11 +328,11 @@ FancySpec describe: Class with: {
|
|
|
326
328
|
}
|
|
327
329
|
}
|
|
328
330
|
}
|
|
329
|
-
Outer is_a?: Class .
|
|
330
|
-
Outer
|
|
331
|
-
Outer
|
|
332
|
-
obj = Outer
|
|
333
|
-
obj foobar
|
|
331
|
+
Outer is_a?: Class . is: true
|
|
332
|
+
Outer Inner is_a?: Class . is: true
|
|
333
|
+
Outer Inner InnerMost is_a?: Class . is: true
|
|
334
|
+
obj = Outer Inner InnerMost new
|
|
335
|
+
obj foobar is: "foobar!"
|
|
334
336
|
|
|
335
337
|
# change InnerMost#foobar
|
|
336
338
|
class Outer::Inner::InnerMost {
|
|
@@ -338,10 +340,10 @@ FancySpec describe: Class with: {
|
|
|
338
340
|
"oh no!"
|
|
339
341
|
}
|
|
340
342
|
}
|
|
341
|
-
obj foobar
|
|
343
|
+
obj foobar is: "oh no!"
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
it: "
|
|
346
|
+
it: "does not override existing classes with the same name in a nested class" when: {
|
|
345
347
|
StdArray = Array
|
|
346
348
|
class NameSpace {
|
|
347
349
|
class Array {
|
|
@@ -351,29 +353,29 @@ FancySpec describe: Class with: {
|
|
|
351
353
|
}
|
|
352
354
|
}
|
|
353
355
|
|
|
354
|
-
NameSpace
|
|
355
|
-
NameSpace
|
|
356
|
+
NameSpace Array what_am_i is: "not the same as the standard Array class"
|
|
357
|
+
NameSpace Array is_not: Array
|
|
356
358
|
}
|
|
357
359
|
|
|
358
|
-
# it: "
|
|
360
|
+
# it: "returns all nested classes of a class" with: 'nested_classes when: {
|
|
359
361
|
# class Outer {
|
|
360
362
|
# }
|
|
361
|
-
# Outer nested_classes
|
|
363
|
+
# Outer nested_classes is: []
|
|
362
364
|
|
|
363
365
|
# class Outer {
|
|
364
366
|
# class Inner1 {
|
|
365
367
|
# }
|
|
366
368
|
# }
|
|
367
|
-
# Outer nested_classes
|
|
369
|
+
# Outer nested_classes is: [Outer::Inner1]
|
|
368
370
|
|
|
369
371
|
# class Outer {
|
|
370
372
|
# class Inner2 {
|
|
371
373
|
# }
|
|
372
374
|
# }
|
|
373
|
-
# Outer nested_classes
|
|
375
|
+
# Outer nested_classes is: [Outer Inner1, Outer Inner2]
|
|
374
376
|
# }
|
|
375
377
|
|
|
376
|
-
it: "
|
|
378
|
+
it: "finds other nested classes in the same parent class" when: {
|
|
377
379
|
class MyOuter {
|
|
378
380
|
class Inner1 {
|
|
379
381
|
def method1 {
|
|
@@ -388,12 +390,12 @@ FancySpec describe: Class with: {
|
|
|
388
390
|
}
|
|
389
391
|
}
|
|
390
392
|
|
|
391
|
-
MyOuter
|
|
392
|
-
MyOuter
|
|
393
|
-
MyOuter
|
|
393
|
+
MyOuter Inner1 new method1 is: 'method_1
|
|
394
|
+
MyOuter Inner2 new method1 is: 'method_1
|
|
395
|
+
MyOuter Inner2 new method2 is: 'method_2
|
|
394
396
|
}
|
|
395
397
|
|
|
396
|
-
it: "
|
|
398
|
+
it: "finds itself in it's own methods, even if nested into another class" when: {
|
|
397
399
|
class MyOuter {
|
|
398
400
|
class MyInner1 {
|
|
399
401
|
def method1 {
|
|
@@ -413,13 +415,13 @@ FancySpec describe: Class with: {
|
|
|
413
415
|
}
|
|
414
416
|
}
|
|
415
417
|
|
|
416
|
-
MyOuter
|
|
417
|
-
MyOuter
|
|
418
|
-
MyOuter
|
|
419
|
-
MyOuter
|
|
418
|
+
MyOuter MyInner1 new method1 is: MyOuter MyInner1
|
|
419
|
+
MyOuter MyInner2 new method2 is: [MyOuter MyInner1, MyOuter MyInner2]
|
|
420
|
+
MyOuter MyInner1 class_method1 is: MyOuter MyInner1
|
|
421
|
+
MyOuter MyInner2 class_method2 is: [MyOuter MyInner1, MyOuter MyInner2]
|
|
420
422
|
}
|
|
421
423
|
|
|
422
|
-
it: "
|
|
424
|
+
it: "has an alias method as defined" with: 'alias_method:for: when: {
|
|
423
425
|
class AClass {
|
|
424
426
|
def foo {
|
|
425
427
|
"in foo!"
|
|
@@ -429,25 +431,25 @@ FancySpec describe: Class with: {
|
|
|
429
431
|
}
|
|
430
432
|
|
|
431
433
|
obj = AClass new
|
|
432
|
-
obj foo
|
|
433
|
-
obj bar
|
|
434
|
+
obj foo is: "in foo!"
|
|
435
|
+
obj bar is: "in foo!"
|
|
434
436
|
}
|
|
435
437
|
|
|
436
|
-
it: "
|
|
438
|
+
it: "has an alias method for a ruby method defined" with: 'alias_method:for_ruby: when: {
|
|
437
439
|
try {
|
|
438
|
-
[] equal?: [1,2] .
|
|
440
|
+
[] equal?: [1,2] . is: true # is fail
|
|
439
441
|
} catch NoMethodError => e {
|
|
440
|
-
e method_name
|
|
442
|
+
e method_name is: 'equal?:
|
|
441
443
|
}
|
|
442
444
|
|
|
443
445
|
class Array {
|
|
444
446
|
alias_method: 'equal?: for_ruby: 'equal?
|
|
445
447
|
}
|
|
446
448
|
|
|
447
|
-
[] equal?: [1,2] .
|
|
449
|
+
[] equal?: [1,2] . is: false
|
|
448
450
|
}
|
|
449
451
|
|
|
450
|
-
it: "
|
|
452
|
+
it: "has the correct list of ancestors" with: 'ancestors when: {
|
|
451
453
|
class A {
|
|
452
454
|
}
|
|
453
455
|
class B : A {
|
|
@@ -455,8 +457,95 @@ FancySpec describe: Class with: {
|
|
|
455
457
|
class C : B {
|
|
456
458
|
}
|
|
457
459
|
|
|
458
|
-
A ancestors
|
|
459
|
-
B ancestors
|
|
460
|
-
C ancestors
|
|
460
|
+
A ancestors is: [A, Object, Kernel]
|
|
461
|
+
B ancestors is: [B, A, Object, Kernel]
|
|
462
|
+
C ancestors is: [C, B, A, Object, Kernel]
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
it: "makes methods private" with: 'private: when: {
|
|
466
|
+
class AClassWithPrivateMethods {
|
|
467
|
+
def a {
|
|
468
|
+
"in a"
|
|
469
|
+
}
|
|
470
|
+
def b {
|
|
471
|
+
"in b"
|
|
472
|
+
}
|
|
473
|
+
private: ['a, 'b]
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
x = AClassWithPrivateMethods new
|
|
477
|
+
{ x a } raises: NoMethodError
|
|
478
|
+
{ x b } raises: NoMethodError
|
|
479
|
+
AClassWithPrivateMethods instance_method: 'a . private? is: true
|
|
480
|
+
AClassWithPrivateMethods instance_method: 'b . private? is: true
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
it: "makes methods protected" with: 'protected: when: {
|
|
484
|
+
class AClassWithProtectedMethods {
|
|
485
|
+
def a {
|
|
486
|
+
"in a"
|
|
487
|
+
}
|
|
488
|
+
def b {
|
|
489
|
+
"in b"
|
|
490
|
+
}
|
|
491
|
+
protected: ['a, 'b]
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
x = AClassWithProtectedMethods new
|
|
495
|
+
{ x a } raises: NoMethodError
|
|
496
|
+
{ x b } raises: NoMethodError
|
|
497
|
+
AClassWithProtectedMethods instance_method: 'a . private? is: false
|
|
498
|
+
AClassWithProtectedMethods instance_method: 'b . private? is: false
|
|
499
|
+
AClassWithProtectedMethods instance_method: 'a . protected? is: true
|
|
500
|
+
AClassWithProtectedMethods instance_method: 'b . protected? is: true
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
it: "makes methods public" with: 'public: when: {
|
|
504
|
+
class AClassWithPublicMethods {
|
|
505
|
+
def a {
|
|
506
|
+
"in a"
|
|
507
|
+
}
|
|
508
|
+
def b {
|
|
509
|
+
"in b"
|
|
510
|
+
}
|
|
511
|
+
private: ['a, 'b]
|
|
512
|
+
public: ['a, 'b] # making sure Class#public: works.
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
x = AClassWithPublicMethods new
|
|
516
|
+
{ x a } does_not raise: NoMethodError
|
|
517
|
+
{ x b } does_not raise: NoMethodError
|
|
518
|
+
AClassWithPublicMethods instance_method: 'a . private? is: false
|
|
519
|
+
AClassWithPublicMethods instance_method: 'b . private? is: false
|
|
520
|
+
AClassWithPublicMethods instance_method: 'a . protected? is: false
|
|
521
|
+
AClassWithPublicMethods instance_method: 'b . protected? is: false
|
|
522
|
+
AClassWithPublicMethods instance_method: 'a . public? is: true
|
|
523
|
+
AClassWithPublicMethods instance_method: 'b . public? is: true
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
it: "defines a class without a body" when: {
|
|
527
|
+
class Foo
|
|
528
|
+
Foo is_a?: Class . is: true
|
|
529
|
+
Foo new is_a?: Foo . is: true
|
|
530
|
+
|
|
531
|
+
class FooNew : Foo
|
|
532
|
+
FooNew is_a?: Class . is: true
|
|
533
|
+
FooNew ancestors includes?: Foo . is: true
|
|
534
|
+
FooNew new is_a?: Foo . is: true
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
it: "defines a class with empty methods" when: {
|
|
538
|
+
class Foo
|
|
539
|
+
class Bar : Foo {
|
|
540
|
+
def initialize: @bar
|
|
541
|
+
def empty_method
|
|
542
|
+
def to_s {
|
|
543
|
+
@bar + "bar"
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
b = Bar new: "foo"
|
|
548
|
+
b to_s is: "foobar"
|
|
549
|
+
b empty_method is: nil
|
|
461
550
|
}
|
|
462
551
|
}
|