pure 0.1.0 → 0.2.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/CHANGES.rdoc +7 -0
- data/MANIFEST +44 -20
- data/README.rdoc +553 -16
- data/Rakefile +25 -2
- data/devel/jumpstart.rb +606 -253
- data/install.rb +1 -2
- data/lib/pure.rb +38 -16
- data/lib/pure/bundled_parsers.rb +4 -0
- data/lib/pure/bundled_plugin.rb +49 -0
- data/lib/pure/compiler/ruby_parser.rb +63 -0
- data/lib/pure/delegate.rb +16 -0
- data/lib/pure/driver.rb +33 -0
- data/lib/pure/dsl.rb +2 -0
- data/lib/pure/dsl_definition.rb +11 -0
- data/lib/pure/error.rb +89 -0
- data/lib/pure/extracted_functions.rb +11 -0
- data/lib/pure/extractor.rb +59 -0
- data/lib/pure/names.rb +9 -0
- data/lib/pure/native_worker.rb +27 -0
- data/lib/pure/parser/impl/base_parser.rb +21 -0
- data/lib/pure/parser/impl/internal.rb +31 -0
- data/lib/pure/parser/impl/ripper.rb +96 -0
- data/lib/pure/parser/impl/ruby_parser.rb +77 -0
- data/lib/pure/parser/internal.rb +4 -0
- data/lib/pure/parser/ripper.rb +2 -0
- data/lib/pure/parser/ruby_parser.rb +2 -0
- data/lib/pure/pure.rb +32 -0
- data/lib/pure/pure_module.rb +141 -0
- data/lib/pure/util.rb +15 -0
- data/lib/pure/version.rb +4 -0
- data/spec/compiler_ruby_parser_spec.rb +79 -0
- data/spec/compute_overrides_spec.rb +99 -0
- data/spec/compute_spec.rb +86 -0
- data/spec/compute_thread_spec.rb +29 -0
- data/spec/compute_timed_spec.rb +40 -0
- data/spec/delegate_spec.rb +141 -0
- data/spec/fstat_example.rb +26 -0
- data/spec/parser_sexp_spec.rb +100 -0
- data/spec/parser_spec.rb +18 -31
- data/spec/pure_combine_spec.rb +77 -0
- data/spec/pure_def_spec.rb +186 -0
- data/spec/pure_define_method_spec.rb +24 -0
- data/spec/pure_eval_spec.rb +18 -0
- data/spec/pure_fun_spec.rb +243 -0
- data/spec/pure_nested_spec.rb +35 -0
- data/spec/pure_parser_spec.rb +50 -0
- data/spec/pure_spec.rb +81 -0
- data/spec/pure_spec_base.rb +106 -0
- data/spec/pure_splat_spec.rb +18 -0
- data/spec/pure_two_defs_spec.rb +20 -0
- data/spec/pure_worker_spec.rb +33 -0
- data/spec/readme_spec.rb +36 -32
- data/spec/splat_spec.rb +12 -11
- data/spec/worker_spec.rb +89 -0
- metadata +157 -41
- data/devel/jumpstart/lazy_attribute.rb +0 -38
- data/devel/jumpstart/ruby.rb +0 -44
- data/devel/jumpstart/simple_installer.rb +0 -85
- data/lib/pure/pure_private/creator.rb +0 -27
- data/lib/pure/pure_private/driver.rb +0 -48
- data/lib/pure/pure_private/error.rb +0 -32
- data/lib/pure/pure_private/extractor.rb +0 -79
- data/lib/pure/pure_private/extractor_ripper.rb +0 -95
- data/lib/pure/pure_private/extractor_ruby_parser.rb +0 -47
- data/lib/pure/pure_private/function_database.rb +0 -10
- data/lib/pure/pure_private/singleton_features.rb +0 -67
- data/lib/pure/pure_private/util.rb +0 -23
- data/spec/basic_spec.rb +0 -38
- data/spec/combine_spec.rb +0 -62
- data/spec/common.rb +0 -44
- data/spec/error_spec.rb +0 -146
- data/spec/fun_spec.rb +0 -122
- data/spec/lazy_spec.rb +0 -22
- data/spec/subseqent_spec.rb +0 -42
- data/spec/timed_spec.rb +0 -30
data/spec/parser_spec.rb
CHANGED
@@ -1,36 +1,23 @@
|
|
1
|
-
require File.dirname(__FILE__) +
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
5
|
-
pure do
|
6
|
-
|
3
|
+
describe "parser" do
|
4
|
+
describe "provided by user" do
|
5
|
+
it "should be accepted by pure" do
|
6
|
+
memo = nil
|
7
|
+
parser = Class.new do
|
8
|
+
define_method :extract do |*args|
|
9
|
+
memo = args
|
10
|
+
Hash.new
|
11
|
+
end
|
12
|
+
def name
|
13
|
+
"SampleParser"
|
14
|
+
end
|
15
|
+
end.new
|
16
|
+
mod = pure(parser) do
|
17
|
+
def f(x, y)
|
18
|
+
end
|
7
19
|
end
|
8
|
-
|
9
|
-
lambda {
|
10
|
-
Pure.parser
|
11
|
-
}.should_not raise_error
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should be swappable" do
|
15
|
-
previous = Pure.parser
|
16
|
-
begin
|
17
|
-
Pure.parser = "ruby_parser"
|
18
|
-
Pure.parser.should == "ruby_parser"
|
19
|
-
ensure
|
20
|
-
Pure.parser = previous
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should have a default unless Method#parameters available" do
|
25
|
-
Pure.parser = nil
|
26
|
-
pure do
|
27
|
-
def f
|
28
|
-
end
|
29
|
-
end.compute(:f, 3)
|
30
|
-
if Method.instance_methods.include?(:parameters)
|
31
|
-
Pure.parser.should == nil
|
32
|
-
else
|
33
|
-
Pure.parser.should_not == nil
|
20
|
+
memo.should == [mod, :f, __FILE__, 17]
|
34
21
|
end
|
35
22
|
end
|
36
23
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
# factor out due to parsers changing
|
4
|
+
module PureCombineSpec
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def create_mod_a
|
8
|
+
pure do
|
9
|
+
def area(width, height)
|
10
|
+
width*height
|
11
|
+
end
|
12
|
+
|
13
|
+
def border
|
14
|
+
5
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_mod_b
|
20
|
+
pure do
|
21
|
+
def width(border)
|
22
|
+
20 + border
|
23
|
+
end
|
24
|
+
|
25
|
+
def height(border)
|
26
|
+
30 + border
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_combined
|
32
|
+
mod_a = create_mod_a
|
33
|
+
mod_b = create_mod_b
|
34
|
+
pure do
|
35
|
+
include mod_a
|
36
|
+
include mod_b
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "pure" do
|
42
|
+
describe "modules combined with other pure modules" do
|
43
|
+
max_threads = 5
|
44
|
+
|
45
|
+
it "should work with modules included into empty module" do
|
46
|
+
combined = PureCombineSpec.create_combined
|
47
|
+
(1..max_threads).each { |n|
|
48
|
+
combined.compute(n).area.should == (20 + 5)*(30 + 5)
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should work with modules included into overriding module" do
|
53
|
+
combined = PureCombineSpec.create_combined
|
54
|
+
combined_override = pure do
|
55
|
+
include combined
|
56
|
+
def border
|
57
|
+
99
|
58
|
+
end
|
59
|
+
end
|
60
|
+
(1..max_threads).each { |n|
|
61
|
+
combined_override.compute(n).area.should == (20 + 99)*(30 + 99)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should work with one module included into another" do
|
66
|
+
mod_a = PureCombineSpec.create_mod_a
|
67
|
+
mod_b = PureCombineSpec.create_mod_b
|
68
|
+
mod_a.module_eval do
|
69
|
+
include mod_b
|
70
|
+
end
|
71
|
+
(1..max_threads).each { |n|
|
72
|
+
mod_a.compute(n).area.should == (20 + 5)*(30 + 5)
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "`def' definitions" do
|
5
|
+
it "should be parsed with 1 arg default" do
|
6
|
+
lambda {
|
7
|
+
pure do
|
8
|
+
def f(x = 99)
|
9
|
+
x
|
10
|
+
end
|
11
|
+
end
|
12
|
+
}.should raise_error(
|
13
|
+
Pure::DefaultArgumentError,
|
14
|
+
"cannot use default argument in pure function at #{__FILE__}:8"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be parsed with non-paren 1 arg" do
|
19
|
+
pure do
|
20
|
+
def f x
|
21
|
+
x + 33
|
22
|
+
end
|
23
|
+
end.compute(3, :x => 44).f.should == 77
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be parsed with non-paren 1 arg splat" do
|
27
|
+
lambda {
|
28
|
+
pure do
|
29
|
+
def f *x
|
30
|
+
x + 33
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}.should raise_error(Pure::SplatError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be parsed with non-paren 2 arg splat" do
|
37
|
+
lambda {
|
38
|
+
pure do
|
39
|
+
def f x, *y
|
40
|
+
x + 33
|
41
|
+
end
|
42
|
+
end
|
43
|
+
}.should raise_error(Pure::SplatError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be parsed with non-paren 2 args" do
|
47
|
+
pure do
|
48
|
+
def f x, y
|
49
|
+
x + y
|
50
|
+
end
|
51
|
+
end.compute(3, :x => 33, :y => 44).f.should == 77
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be parsed with 2 arg default" do
|
55
|
+
lambda {
|
56
|
+
pure do
|
57
|
+
def f(x, y = 99)
|
58
|
+
x + y
|
59
|
+
end
|
60
|
+
end
|
61
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be parsed with non-paren 1 arg default" do
|
65
|
+
lambda {
|
66
|
+
pure do
|
67
|
+
def f x = 99
|
68
|
+
x + 44
|
69
|
+
end
|
70
|
+
end
|
71
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should be parsed with non-paren 2 arg 1 default" do
|
75
|
+
lambda {
|
76
|
+
pure do
|
77
|
+
def f x, y = 99
|
78
|
+
x + y
|
79
|
+
end
|
80
|
+
end
|
81
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be parsed with non-paren 2 arg 2 default" do
|
85
|
+
lambda {
|
86
|
+
pure do
|
87
|
+
def f x = 77, y = 99
|
88
|
+
x + y
|
89
|
+
end
|
90
|
+
end
|
91
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should ignore &block" do
|
95
|
+
pure do
|
96
|
+
def f(&block)
|
97
|
+
33
|
98
|
+
end
|
99
|
+
end.compute(4).f.should == 33
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should ignore &block with 1 arg" do
|
103
|
+
pure do
|
104
|
+
def f(x, &block)
|
105
|
+
x + 44
|
106
|
+
end
|
107
|
+
end.compute(4, :x => 33).f.should == 77
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should ignore &block with 2 arg" do
|
111
|
+
pure do
|
112
|
+
def f(x, y, &block)
|
113
|
+
x + 44
|
114
|
+
end
|
115
|
+
end.compute(4, :x => 33, :y => nil).f.should == 77
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should ignore &block with 1 arg default" do
|
119
|
+
lambda {
|
120
|
+
pure do
|
121
|
+
def f(x = 11, &block)
|
122
|
+
x + 44
|
123
|
+
end
|
124
|
+
end
|
125
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should ignore no-paren &block" do
|
129
|
+
pure do
|
130
|
+
def f &block
|
131
|
+
33
|
132
|
+
end
|
133
|
+
end.compute(4).f.should == 33
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should ignore no-paren &block with 1 arg" do
|
137
|
+
pure do
|
138
|
+
def f x, &block
|
139
|
+
x + 44
|
140
|
+
end
|
141
|
+
end.compute(4, :x => 33).f.should == 77
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should ignore no-paren &block with 2 arg" do
|
145
|
+
pure do
|
146
|
+
def f x, y, &block
|
147
|
+
x + 44
|
148
|
+
end
|
149
|
+
end.compute(4, :x => 33, :y => nil).f.should == 77
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should ignore no-paren &block with 1 arg default" do
|
153
|
+
lambda {
|
154
|
+
pure do
|
155
|
+
def f x = 11, &block
|
156
|
+
x + 44
|
157
|
+
end
|
158
|
+
end
|
159
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should have fun_name and arg_names" do
|
163
|
+
pure do
|
164
|
+
def f(x, y)
|
165
|
+
[fun_name, arg_names, x + y]
|
166
|
+
end
|
167
|
+
end.compute(:x => 11, :y => 22).f.should == [:f, [:x, :y], 33]
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should have fun_name and arg_names, given 1 arg" do
|
171
|
+
pure do
|
172
|
+
def f(x)
|
173
|
+
[fun_name, arg_names, x]
|
174
|
+
end
|
175
|
+
end.compute(:x => 11).f.should == [:f, [:x], 11]
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should have fun_name and arg_names, given no args" do
|
179
|
+
pure do
|
180
|
+
def f
|
181
|
+
[fun_name, arg_names]
|
182
|
+
end
|
183
|
+
end.compute.f.should == [:f, []]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
it "should raise error when define_method called" do
|
5
|
+
lambda {
|
6
|
+
pure do
|
7
|
+
define_method :area do |width, height|
|
8
|
+
width*height
|
9
|
+
end
|
10
|
+
|
11
|
+
def width
|
12
|
+
5
|
13
|
+
end
|
14
|
+
|
15
|
+
def height
|
16
|
+
7
|
17
|
+
end
|
18
|
+
end.compute :area, 3
|
19
|
+
}.should raise_error(
|
20
|
+
Pure::DefineMethodError,
|
21
|
+
%r!cannot use define_method.* at #{__FILE__}:7!
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "defined inside eval" do
|
5
|
+
it "should raise an error" do
|
6
|
+
lambda {
|
7
|
+
code = %{
|
8
|
+
pure do
|
9
|
+
def f
|
10
|
+
33
|
11
|
+
end
|
12
|
+
end
|
13
|
+
}
|
14
|
+
eval(code)
|
15
|
+
}.should raise_error(Pure::EvalError, %r!#{__FILE__}:14!)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
require 'jumpstart'
|
4
|
+
|
5
|
+
describe "pure" do
|
6
|
+
describe "`fun' definitions" do
|
7
|
+
it "should work with symbols" do
|
8
|
+
pure do
|
9
|
+
fun :area => [:width, :height] do |w, h|
|
10
|
+
w*h
|
11
|
+
end
|
12
|
+
|
13
|
+
fun :width => [:border] do |b|
|
14
|
+
20 + b
|
15
|
+
end
|
16
|
+
|
17
|
+
fun :height => :border do |b|
|
18
|
+
30 + b
|
19
|
+
end
|
20
|
+
|
21
|
+
fun :border do
|
22
|
+
5
|
23
|
+
end
|
24
|
+
end.compute(4).area.should == (20 + 5)*(30 + 5)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should work with symbols and parens" do
|
28
|
+
pure do
|
29
|
+
fun(:area => [:width, :height]) do |w, h|
|
30
|
+
w*h
|
31
|
+
end
|
32
|
+
|
33
|
+
fun(:width => [:border]) do |b|
|
34
|
+
20 + b
|
35
|
+
end
|
36
|
+
|
37
|
+
fun(:height => :border) do |b|
|
38
|
+
30 + b
|
39
|
+
end
|
40
|
+
|
41
|
+
fun(:border) do
|
42
|
+
5
|
43
|
+
end
|
44
|
+
end.compute(4).area.should == (20 + 5)*(30 + 5)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should work with mixed symbols and strings" do
|
48
|
+
pure do
|
49
|
+
fun :area => [:width, "height"] do |w, h|
|
50
|
+
w*h
|
51
|
+
end
|
52
|
+
|
53
|
+
fun "width" => [:border] do |b|
|
54
|
+
20 + b
|
55
|
+
end
|
56
|
+
|
57
|
+
fun :height => "border" do |b|
|
58
|
+
30 + b
|
59
|
+
end
|
60
|
+
|
61
|
+
fun :border do
|
62
|
+
5
|
63
|
+
end
|
64
|
+
end.compute(4).area.should == (20 + 5)*(30 + 5)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should work with `def' definitions" do
|
68
|
+
pure do
|
69
|
+
fun :width do
|
70
|
+
33
|
71
|
+
end
|
72
|
+
|
73
|
+
def height
|
74
|
+
44
|
75
|
+
end
|
76
|
+
|
77
|
+
fun :area => [:width, :height] do |w, h|
|
78
|
+
w*h
|
79
|
+
end
|
80
|
+
end.compute(3).area.should == 33*44
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should be overwritten by later `def' definitions" do
|
84
|
+
Jumpstart::Ruby.no_warnings {
|
85
|
+
pure do
|
86
|
+
fun :f do
|
87
|
+
44
|
88
|
+
end
|
89
|
+
|
90
|
+
def f
|
91
|
+
33
|
92
|
+
end
|
93
|
+
end.compute(10).f.should == 33
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should overwrite earlier `def' definitions" do
|
98
|
+
Jumpstart::Ruby.no_warnings {
|
99
|
+
pure do
|
100
|
+
def f
|
101
|
+
33
|
102
|
+
end
|
103
|
+
|
104
|
+
fun :f do
|
105
|
+
44
|
106
|
+
end
|
107
|
+
end.compute(10).f.should == 44
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should support splat in block args" do
|
112
|
+
pure do
|
113
|
+
fun :area => [:width, :height] do |*a|
|
114
|
+
a[0]*a[1]
|
115
|
+
end
|
116
|
+
|
117
|
+
def width
|
118
|
+
3
|
119
|
+
end
|
120
|
+
|
121
|
+
def height
|
122
|
+
4
|
123
|
+
end
|
124
|
+
end.compute(3).area.should == 12
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should support splat with single-element array" do
|
128
|
+
pure do
|
129
|
+
name = [:f]
|
130
|
+
fun(*name) do
|
131
|
+
33
|
132
|
+
end
|
133
|
+
end.compute(3).f.should == 33
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should not preclude `def' definitions called `fun'" do
|
137
|
+
pure do
|
138
|
+
def misery(fun)
|
139
|
+
fun**2
|
140
|
+
end
|
141
|
+
|
142
|
+
def fun(a, b)
|
143
|
+
a + b
|
144
|
+
end
|
145
|
+
|
146
|
+
def a
|
147
|
+
3
|
148
|
+
end
|
149
|
+
|
150
|
+
def b
|
151
|
+
5
|
152
|
+
end
|
153
|
+
end.compute(3).misery.should == 64
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should raise error when given hash of size != 1" do
|
157
|
+
lambda {
|
158
|
+
pure do
|
159
|
+
fun :x => 1, :y => 2 do
|
160
|
+
end
|
161
|
+
end
|
162
|
+
}.should raise_error(ArgumentError)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should raise error given more than 1 argument" do
|
166
|
+
lambda {
|
167
|
+
pure do
|
168
|
+
fun :x, :y do
|
169
|
+
end
|
170
|
+
end
|
171
|
+
}.should raise_error(ArgumentError)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should raise error with &block unless Pure::Parser::Internal is used" do
|
175
|
+
code = lambda {
|
176
|
+
pure do
|
177
|
+
fun :f, &lambda { 33 }
|
178
|
+
end.compute(4).f.should == 33
|
179
|
+
}
|
180
|
+
if Pure.parser.name == "Pure::Parser::Internal"
|
181
|
+
code.should_not raise_error
|
182
|
+
else
|
183
|
+
code.should raise_error(Pure::ParseError)
|
184
|
+
end
|
185
|
+
|
186
|
+
code = lambda {
|
187
|
+
pure do
|
188
|
+
t = lambda { 33 }
|
189
|
+
fun :f, &t
|
190
|
+
end.compute(4).f.should == 33
|
191
|
+
}
|
192
|
+
if Pure.parser.name == "Pure::Parser::Internal"
|
193
|
+
code.should_not raise_error
|
194
|
+
else
|
195
|
+
code.should raise_error(Pure::ParseError)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should allow function names containing any characters" do
|
200
|
+
%w[- / ? : ; . ! [ ] ( )].each { |char|
|
201
|
+
pure do
|
202
|
+
fun "f#{char}f" do
|
203
|
+
33
|
204
|
+
end
|
205
|
+
end.compute[:"f#{char}f"].should == 33
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should have fun_name and arg_names, given multiple args" do
|
210
|
+
pure do
|
211
|
+
fun :f => [:x, :y] do |x, y|
|
212
|
+
[fun_name, arg_names, x + y]
|
213
|
+
end
|
214
|
+
end.compute(:x => 11, :y => 22).f.should == [:f, [:x, :y], 33]
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should have fun_name and fun_args, given 1 arg" do
|
218
|
+
pure do
|
219
|
+
fun :f => :x do |x|
|
220
|
+
[fun_name, arg_names, x]
|
221
|
+
end
|
222
|
+
end.compute(:x => 11).f.should == [:f, [:x], 11]
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should have fun_name and fun_args, given no args" do
|
226
|
+
pure do
|
227
|
+
fun :f do
|
228
|
+
[fun_name, arg_names]
|
229
|
+
end
|
230
|
+
end.compute.f.should == [:f, []]
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should not see internals of the compiler" do
|
234
|
+
lambda {
|
235
|
+
pure do
|
236
|
+
fun :f do
|
237
|
+
spec
|
238
|
+
end
|
239
|
+
end.compute.f
|
240
|
+
}.should raise_error(NameError)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|