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.
Files changed (75) hide show
  1. data/CHANGES.rdoc +7 -0
  2. data/MANIFEST +44 -20
  3. data/README.rdoc +553 -16
  4. data/Rakefile +25 -2
  5. data/devel/jumpstart.rb +606 -253
  6. data/install.rb +1 -2
  7. data/lib/pure.rb +38 -16
  8. data/lib/pure/bundled_parsers.rb +4 -0
  9. data/lib/pure/bundled_plugin.rb +49 -0
  10. data/lib/pure/compiler/ruby_parser.rb +63 -0
  11. data/lib/pure/delegate.rb +16 -0
  12. data/lib/pure/driver.rb +33 -0
  13. data/lib/pure/dsl.rb +2 -0
  14. data/lib/pure/dsl_definition.rb +11 -0
  15. data/lib/pure/error.rb +89 -0
  16. data/lib/pure/extracted_functions.rb +11 -0
  17. data/lib/pure/extractor.rb +59 -0
  18. data/lib/pure/names.rb +9 -0
  19. data/lib/pure/native_worker.rb +27 -0
  20. data/lib/pure/parser/impl/base_parser.rb +21 -0
  21. data/lib/pure/parser/impl/internal.rb +31 -0
  22. data/lib/pure/parser/impl/ripper.rb +96 -0
  23. data/lib/pure/parser/impl/ruby_parser.rb +77 -0
  24. data/lib/pure/parser/internal.rb +4 -0
  25. data/lib/pure/parser/ripper.rb +2 -0
  26. data/lib/pure/parser/ruby_parser.rb +2 -0
  27. data/lib/pure/pure.rb +32 -0
  28. data/lib/pure/pure_module.rb +141 -0
  29. data/lib/pure/util.rb +15 -0
  30. data/lib/pure/version.rb +4 -0
  31. data/spec/compiler_ruby_parser_spec.rb +79 -0
  32. data/spec/compute_overrides_spec.rb +99 -0
  33. data/spec/compute_spec.rb +86 -0
  34. data/spec/compute_thread_spec.rb +29 -0
  35. data/spec/compute_timed_spec.rb +40 -0
  36. data/spec/delegate_spec.rb +141 -0
  37. data/spec/fstat_example.rb +26 -0
  38. data/spec/parser_sexp_spec.rb +100 -0
  39. data/spec/parser_spec.rb +18 -31
  40. data/spec/pure_combine_spec.rb +77 -0
  41. data/spec/pure_def_spec.rb +186 -0
  42. data/spec/pure_define_method_spec.rb +24 -0
  43. data/spec/pure_eval_spec.rb +18 -0
  44. data/spec/pure_fun_spec.rb +243 -0
  45. data/spec/pure_nested_spec.rb +35 -0
  46. data/spec/pure_parser_spec.rb +50 -0
  47. data/spec/pure_spec.rb +81 -0
  48. data/spec/pure_spec_base.rb +106 -0
  49. data/spec/pure_splat_spec.rb +18 -0
  50. data/spec/pure_two_defs_spec.rb +20 -0
  51. data/spec/pure_worker_spec.rb +33 -0
  52. data/spec/readme_spec.rb +36 -32
  53. data/spec/splat_spec.rb +12 -11
  54. data/spec/worker_spec.rb +89 -0
  55. metadata +157 -41
  56. data/devel/jumpstart/lazy_attribute.rb +0 -38
  57. data/devel/jumpstart/ruby.rb +0 -44
  58. data/devel/jumpstart/simple_installer.rb +0 -85
  59. data/lib/pure/pure_private/creator.rb +0 -27
  60. data/lib/pure/pure_private/driver.rb +0 -48
  61. data/lib/pure/pure_private/error.rb +0 -32
  62. data/lib/pure/pure_private/extractor.rb +0 -79
  63. data/lib/pure/pure_private/extractor_ripper.rb +0 -95
  64. data/lib/pure/pure_private/extractor_ruby_parser.rb +0 -47
  65. data/lib/pure/pure_private/function_database.rb +0 -10
  66. data/lib/pure/pure_private/singleton_features.rb +0 -67
  67. data/lib/pure/pure_private/util.rb +0 -23
  68. data/spec/basic_spec.rb +0 -38
  69. data/spec/combine_spec.rb +0 -62
  70. data/spec/common.rb +0 -44
  71. data/spec/error_spec.rb +0 -146
  72. data/spec/fun_spec.rb +0 -122
  73. data/spec/lazy_spec.rb +0 -22
  74. data/spec/subseqent_spec.rb +0 -42
  75. data/spec/timed_spec.rb +0 -30
@@ -1,62 +0,0 @@
1
- require File.dirname(__FILE__) + "/common"
2
-
3
- describe "combining pure modules" do
4
- before :all do
5
- mod_a = @mod_a = pure do
6
- def area(width, height)
7
- width*height
8
- end
9
-
10
- def border
11
- 5
12
- end
13
- end
14
-
15
- mod_b = @mod_b = pure do
16
- def width(border)
17
- 20 + border
18
- end
19
-
20
- def height(border)
21
- 30 + border
22
- end
23
- end
24
-
25
- combined = @combined = pure do
26
- include mod_a
27
- include mod_b
28
- end
29
-
30
- @combined_override = pure do
31
- include combined
32
- def border
33
- 99
34
- end
35
- end
36
- end
37
-
38
- max_threads = 5
39
-
40
- it "should work with modules included into empty module" do
41
- (1..max_threads).each { |n|
42
- @combined.compute(:area, n).should == (20 + 5)*(30 + 5)
43
- }
44
- end
45
-
46
- it "should work with modules included into overriding module" do
47
- (1..max_threads).each { |n|
48
- @combined_override.compute(:area, n).should == (20 + 99)*(30 + 99)
49
- }
50
- end
51
-
52
- it "should work with one module included into another" do
53
- mod_b = @mod_b
54
- @mod_a.module_eval {
55
- include mod_b
56
- }
57
- (1..max_threads).each { |n|
58
- @mod_a.compute(:area, n).should == (20 + 5)*(30 + 5)
59
- }
60
- end
61
- end
62
-
@@ -1,44 +0,0 @@
1
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
2
-
3
- require 'rubygems'
4
- require 'pure'
5
- require 'pathname'
6
- require 'spec'
7
-
8
- include Pure
9
-
10
- AVAILABLE_PARSERS = ["ruby_parser"] + (
11
- begin
12
- require 'ripper'
13
- ["ripper"]
14
- rescue LoadError
15
- []
16
- end
17
- ) + (
18
- if Method.instance_methods.include? :parameters
19
- [nil]
20
- else
21
- []
22
- end
23
- )
24
-
25
- module Spec::Example::ExampleGroupMethods
26
- alias_method :example__original, :example
27
-
28
- def example(*args, &block)
29
- AVAILABLE_PARSERS.each { |parser|
30
- parser_desc = parser || "no parser"
31
- describe "(#{parser_desc})" do
32
- before :each do
33
- Pure.parser = parser
34
- end
35
- example__original(*args, &block)
36
- end
37
- }
38
- end
39
-
40
- [:it, :specify].each { |method_name|
41
- remove_method method_name
42
- alias_method method_name, :example
43
- }
44
- end
@@ -1,146 +0,0 @@
1
- require File.dirname(__FILE__) + "/common"
2
-
3
- describe "two defs on the same line:" do
4
- it "should raise error unless Method#parameters is used" do
5
- code = lambda {
6
- pure do
7
- def x ; end ; def y ; end
8
- end
9
- }
10
- if Pure.parser.nil?
11
- code.should_not raise_error
12
- else
13
- code.should raise_error(Pure::PurePrivate::ParseError)
14
- end
15
- end
16
- end
17
-
18
- describe "function missing:" do
19
- it "should raise error" do
20
- lambda {
21
- pure do
22
- def area(width, height)
23
- width*height
24
- end
25
-
26
- def width
27
- 33
28
- end
29
- end.compute :area, :threads => 3
30
- }.should raise_error(Pure::PurePrivate::NoFunctionError)
31
- end
32
- end
33
-
34
- describe "bad arguments:" do
35
- it "should raise error when given nil" do
36
- lambda {
37
- pure do
38
- def f
39
- end
40
- end.compute nil, 33
41
- }.should raise_error(Pure::PurePrivate::ArgumentError)
42
- end
43
-
44
- it "should raise error when given something random" do
45
- lambda {
46
- pure do
47
- def f
48
- end
49
- end.compute 33, 33
50
- }.should raise_error(Pure::PurePrivate::ArgumentError)
51
- end
52
-
53
- it "should raise error when given a string" do
54
- lambda {
55
- pure do
56
- def f
57
- end
58
- end.compute "f", 33
59
- }.should raise_error(Pure::PurePrivate::ArgumentError)
60
- end
61
- end
62
-
63
- describe "`fun'" do
64
- describe "given hash of size != 1" do
65
- it "should raise error" do
66
- lambda {
67
- pure do
68
- fun :x => 1, :y => 2 do
69
- end
70
- end
71
- }.should raise_error(Pure::PurePrivate::ArgumentError)
72
- end
73
- end
74
-
75
- describe "given more than 1 argument" do
76
- it "should raise error" do
77
- lambda {
78
- pure do
79
- fun :x, :y do
80
- end
81
- end
82
- }.should raise_error(Pure::PurePrivate::ArgumentError)
83
- end
84
- end
85
-
86
- describe "with &block" do
87
- it "should raise error unless Method#parameters is used" do
88
- code = lambda {
89
- pure do
90
- fun :f, &lambda { 33 }
91
- end.compute(:f, :threads => 4).should == 33
92
- }
93
- if Pure.parser.nil?
94
- code.should_not raise_error
95
- else
96
- code.should raise_error(Pure::PurePrivate::ParseError)
97
- end
98
-
99
- code = lambda {
100
- pure do
101
- t = lambda { 33 }
102
- fun :f, &t
103
- end.compute(:f, :threads => 4).should == 33
104
- }
105
- if Pure.parser.nil?
106
- code.should_not raise_error
107
- else
108
- code.should raise_error(Pure::PurePrivate::ParseError)
109
- end
110
- end
111
- end
112
- end
113
-
114
- describe "calling define_method" do
115
- it "should raise error" do
116
- lambda {
117
- pure do
118
- define_method :area do |width, height|
119
- width*height
120
- end
121
-
122
- def width
123
- 5
124
- end
125
-
126
- def height
127
- 7
128
- end
129
- end.compute :area, 3
130
- }.should raise_error(Pure::PurePrivate::NotImplementedError)
131
- end
132
- end
133
-
134
- describe "parse engine" do
135
- it "should raise error when not installed" do
136
- lambda {
137
- Pure.parser = "z"*99
138
- }.should raise_error(LoadError)
139
- end
140
-
141
- it "should raise error when unsupported" do
142
- lambda {
143
- Pure.parser = "fileutils"
144
- }.should raise_error(Pure::PurePrivate::NotImplementedError)
145
- end
146
- end
@@ -1,122 +0,0 @@
1
- require File.dirname(__FILE__) + "/common"
2
-
3
- describe "`fun' definitions" do
4
- it "should work with symbols only" do
5
- pure do
6
- fun :area => [:width, :height] do |w, h|
7
- w*h
8
- end
9
-
10
- fun :width => [:border] do |b|
11
- 20 + b
12
- end
13
-
14
- fun :height => :border do |b|
15
- 30 + b
16
- end
17
-
18
- fun :border do
19
- 5
20
- end
21
- end.compute(:area, :threads => 4).should == (20 + 5)*(30 + 5)
22
- end
23
-
24
- it "should work with symbols and parens only" do
25
- pure do
26
- fun(:area => [:width, :height]) do |w, h|
27
- w*h
28
- end
29
-
30
- fun(:width => [:border]) do |b|
31
- 20 + b
32
- end
33
-
34
- fun(:height => :border) do |b|
35
- 30 + b
36
- end
37
-
38
- fun(:border) do
39
- 5
40
- end
41
- end.compute(:area, :threads => 4).should == (20 + 5)*(30 + 5)
42
- end
43
-
44
- it "should work with mixed symbols and strings" do
45
- pure do
46
- fun :area => [:width, "height"] do |w, h|
47
- w*h
48
- end
49
-
50
- fun "width" => [:border] do |b|
51
- 20 + b
52
- end
53
-
54
- fun :height => "border" do |b|
55
- 30 + b
56
- end
57
-
58
- fun :border do
59
- 5
60
- end
61
- end.compute(:area, :threads => 4).should == (20 + 5)*(30 + 5)
62
- end
63
-
64
- it "should work with `def' definitions" do
65
- pure do
66
- fun :width do
67
- 33
68
- end
69
-
70
- def height
71
- 44
72
- end
73
-
74
- fun :area => [:width, :height] do |w, h|
75
- w*h
76
- end
77
- end.compute(:area, 3).should == 33*44
78
- end
79
-
80
- it "should be lower precedence than `def' definitions" do
81
- pure do
82
- fun :f do
83
- 44
84
- end
85
- end.compute(:f, 10).should == 44
86
-
87
- pure do
88
- fun :f do
89
- 44
90
- end
91
-
92
- def f
93
- 33
94
- end
95
- end.compute(:f, 10).should == 33
96
- end
97
-
98
- it "should support splat in block args" do
99
- pure do
100
- fun :area => [:width, :height] do |*a|
101
- a[0]*a[1]
102
- end
103
-
104
- def width
105
- 3
106
- end
107
-
108
- def height
109
- 4
110
- end
111
- end.compute(:area, 3).should == 12
112
- end
113
-
114
- it "should support splat with single-element array" do
115
- pure do
116
- name = [:f]
117
- fun(*name) do
118
- name
119
- end
120
- end.compute(:f, 3).should == [:f]
121
- end
122
- end
@@ -1,22 +0,0 @@
1
- require File.dirname(__FILE__) + "/common"
2
-
3
- LAZY_SPEC_COUNTER = Struct.new(:value).new
4
-
5
- describe "laziness" do
6
- it "should be lazy" do
7
- LAZY_SPEC_COUNTER.value = 0
8
-
9
- mod = pure do
10
- def square(n)
11
- n*n
12
- end
13
-
14
- def n
15
- LAZY_SPEC_COUNTER.value += 1
16
- 3
17
- end
18
- end.compute :square, :threads => 4
19
-
20
- LAZY_SPEC_COUNTER.value.should == 1
21
- end
22
- end
@@ -1,42 +0,0 @@
1
- require File.dirname(__FILE__) + "/common"
2
-
3
- describe "subsequent `def' definitions" do
4
- it "should be accepted" do
5
- mod = pure do
6
- def f
7
- 33
8
- end
9
- end
10
-
11
- mod.compute(:f, 4).should == 33
12
-
13
- mod.module_eval do
14
- def g
15
- 44
16
- end
17
- end
18
-
19
- mod.compute(:g, 4).should == 44
20
- end
21
- end
22
-
23
- describe "subsequent `fun' definitions" do
24
- it "should be accepted" do
25
- mod = pure do
26
- fun :f do
27
- 33
28
- end
29
- end
30
-
31
- mod.compute(:f, 4).should == 33
32
-
33
- mod.module_eval do
34
- fun :g do
35
- 44
36
- end
37
- end
38
-
39
- mod.compute(:g, 4).should == 44
40
- end
41
- end
42
-
@@ -1,30 +0,0 @@
1
- require File.dirname(__FILE__) + "/common"
2
- require 'benchmark'
3
-
4
- describe "timed example" do
5
- before :all do
6
- @mod = pure do
7
- def root(a, b)
8
- end
9
-
10
- def a
11
- sleep(0.25)
12
- end
13
-
14
- def b
15
- sleep(0.25)
16
- end
17
- end
18
- @compute = lambda { |n|
19
- @mod.compute :root, n
20
- }
21
- end
22
-
23
- it "should run with 1 thread" do
24
- Benchmark.measure { @compute.call(1) }.real.should be_close(0.5, 0.1)
25
- end
26
-
27
- it "should be 2x faster with 2 threads" do
28
- Benchmark.measure { @compute.call(2) }.real.should be_close(0.25, 0.05)
29
- end
30
- end