erubis 1.1.0 → 2.0.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/ChangeLog +45 -18
- data/README.txt +80 -0
- data/benchmark/erubybench-lib.rb +189 -0
- data/benchmark/erubybench.rb +364 -0
- data/benchmark/erubybench.rhtml +61 -0
- data/benchmark/erubybench.yaml +61 -0
- data/bin/erubis +4 -180
- data/contrib/erubis +2297 -0
- data/contrib/inline-require +151 -0
- data/doc-api/classes/Erubis.html +236 -0
- data/doc-api/classes/Erubis/ArrayBufferEnhancer.html +175 -0
- data/doc-api/classes/Erubis/ArrayBufferEruby.html +120 -0
- data/doc-api/classes/Erubis/ArrayEnhancer.html +174 -0
- data/doc-api/classes/Erubis/ArrayEruby.html +120 -0
- data/doc-api/classes/Erubis/BiPatternEnhancer.html +212 -0
- data/doc-api/classes/Erubis/BiPatternEruby.html +120 -0
- data/doc-api/classes/Erubis/CommandOptionError.html +113 -0
- data/doc-api/classes/Erubis/Context.html +249 -0
- data/doc-api/classes/Erubis/Ec.html +399 -0
- data/doc-api/classes/Erubis/Ejava.html +366 -0
- data/doc-api/classes/Erubis/Ejavascript.html +390 -0
- data/doc-api/classes/Erubis/Engine.html +711 -0
- data/doc-api/classes/Erubis/Eperl.html +350 -0
- data/doc-api/classes/Erubis/Ephp.html +308 -0
- data/doc-api/classes/Erubis/ErubisError.html +117 -0
- data/doc-api/classes/Erubis/Eruby.html +310 -0
- data/doc-api/classes/Erubis/EscapeEnhancer.html +167 -0
- data/doc-api/classes/Erubis/EscapedEc.html +120 -0
- data/doc-api/classes/Erubis/EscapedEjava.html +120 -0
- data/doc-api/classes/Erubis/EscapedEjavascript.html +120 -0
- data/doc-api/classes/Erubis/EscapedEperl.html +120 -0
- data/doc-api/classes/Erubis/EscapedEphp.html +120 -0
- data/doc-api/classes/Erubis/EscapedEruby.html +127 -0
- data/doc-api/classes/Erubis/EscapedEscheme.html +120 -0
- data/doc-api/classes/Erubis/Escheme.html +389 -0
- data/doc-api/classes/Erubis/HeaderFooterEnhancer.html +264 -0
- data/doc-api/classes/Erubis/HeaderFooterEruby.html +120 -0
- data/doc-api/classes/Erubis/Main.html +318 -0
- data/doc-api/classes/Erubis/NoTextEnhancer.html +159 -0
- data/doc-api/classes/Erubis/NoTextEruby.html +120 -0
- data/doc-api/classes/Erubis/OptimizedEruby.html +445 -0
- data/doc-api/classes/Erubis/OptimizedXmlEruby.html +163 -0
- data/doc-api/classes/Erubis/PercentLineEnhancer.html +174 -0
- data/doc-api/classes/Erubis/PercentLineEruby.html +120 -0
- data/doc-api/classes/Erubis/PrintEnabledEnhancer.html +212 -0
- data/doc-api/classes/Erubis/PrintEnabledEruby.html +120 -0
- data/doc-api/classes/Erubis/PrintOutEnhancer.html +244 -0
- data/doc-api/classes/Erubis/PrintOutEruby.html +120 -0
- data/doc-api/classes/Erubis/PrintOutSimplifiedEruby.html +121 -0
- data/doc-api/classes/Erubis/SimplifiedEruby.html +120 -0
- data/doc-api/classes/Erubis/SimplifyEnhancer.html +185 -0
- data/doc-api/classes/Erubis/StdoutEnhancer.html +173 -0
- data/doc-api/classes/Erubis/StdoutEruby.html +120 -0
- data/doc-api/classes/Erubis/StdoutSimplifiedEruby.html +121 -0
- data/doc-api/classes/Erubis/StringBufferEnhancer.html +174 -0
- data/doc-api/classes/Erubis/StringBufferEruby.html +120 -0
- data/doc-api/classes/Erubis/StringIOEruby.html +120 -0
- data/doc-api/classes/Erubis/TinyEruby.html +305 -0
- data/doc-api/classes/Erubis/XmlEruby.html +130 -0
- data/doc-api/classes/Erubis/XmlHelper.html +193 -0
- data/doc-api/created.rid +1 -0
- data/doc-api/files/__/README_txt.html +214 -0
- data/doc-api/files/erubis/engine/ec_rb.html +115 -0
- data/doc-api/files/erubis/engine/ejava_rb.html +115 -0
- data/doc-api/files/erubis/engine/ejavascript_rb.html +115 -0
- data/doc-api/files/erubis/engine/enhanced_rb.html +115 -0
- data/doc-api/files/erubis/engine/eperl_rb.html +115 -0
- data/doc-api/files/erubis/engine/ephp_rb.html +115 -0
- data/doc-api/files/erubis/engine/eruby_rb.html +115 -0
- data/doc-api/files/erubis/engine/escheme_rb.html +115 -0
- data/doc-api/files/erubis/engine/optimized_rb.html +114 -0
- data/doc-api/files/erubis/engine_rb.html +114 -0
- data/doc-api/files/erubis/enhancer_rb.html +114 -0
- data/doc-api/files/erubis/helper_rb.html +107 -0
- data/doc-api/files/erubis/local-setting_rb.html +107 -0
- data/doc-api/files/erubis/main_rb.html +125 -0
- data/doc-api/files/erubis/tiny_rb.html +107 -0
- data/doc-api/files/erubis_rb.html +118 -0
- data/doc-api/fr_class_index.html +77 -0
- data/doc-api/fr_file_index.html +43 -0
- data/doc-api/fr_method_index.html +157 -0
- data/doc-api/index.html +24 -0
- data/doc-api/rdoc-style.css +208 -0
- data/doc/users-guide.html +1507 -375
- data/examples/Makefile +53 -0
- data/examples/example.ec +24 -0
- data/examples/example.ejava +41 -0
- data/examples/example.ejavascript +16 -0
- data/examples/example.eperl +16 -0
- data/examples/example.ephp +17 -0
- data/examples/example.eruby +15 -0
- data/examples/example.escheme +26 -0
- data/lib/erubis.rb +37 -269
- data/lib/erubis/engine.rb +260 -0
- data/lib/erubis/engine/ec.rb +106 -0
- data/lib/erubis/engine/ejava.rb +101 -0
- data/lib/erubis/engine/ejavascript.rb +104 -0
- data/lib/erubis/engine/enhanced.rb +102 -0
- data/lib/erubis/engine/eperl.rb +83 -0
- data/lib/erubis/engine/ephp.rb +84 -0
- data/lib/erubis/engine/eruby.rb +91 -0
- data/lib/erubis/engine/escheme.rb +96 -0
- data/lib/erubis/engine/optimized.rb +114 -0
- data/lib/erubis/enhancer.rb +487 -0
- data/lib/erubis/helper.rb +53 -0
- data/lib/erubis/local-setting.rb +10 -0
- data/lib/erubis/main.rb +368 -0
- data/lib/erubis/tiny.rb +65 -0
- data/test/assert-text-equal.rb +45 -0
- data/test/test-bin.rb +222 -45
- data/test/test-engines.rb +343 -0
- data/test/test-erubis.rb +836 -501
- data/test/test.rb +27 -0
- data/test/testutil.rb +86 -0
- metadata +131 -8
- data/README +0 -50
data/ChangeLog
CHANGED
|
@@ -1,25 +1,52 @@
|
|
|
1
|
-
# $Rev$
|
|
2
|
-
# $Release:
|
|
1
|
+
# $Rev: 21 $
|
|
2
|
+
# $Release: 2.0.0 $
|
|
3
3
|
# copyright(c) 2006 kuwata-lab all rights reserved.
|
|
4
4
|
|
|
5
|
-
- release:
|
|
6
|
-
date:
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
5
|
+
- release: 2.0.0
|
|
6
|
+
date: 2006-05-20
|
|
7
|
+
changes:
|
|
8
|
+
- module 'PrintEnhancer' is renamed to 'PrintEnabledEnahncer'
|
|
9
|
+
- module 'FastEnhancer' and class 'FastEruby' is obsolete because they are integrated into Eruby class
|
|
10
|
+
- Eruby#evaluate() calls instance_eval() instead of eval()
|
|
11
|
+
- XmlEruby.escape_xml() is moved to XmlHelper.escape_xml()
|
|
12
|
+
enhances:
|
|
13
|
+
- multi programming language support (Ruby/PHP/C/Java/Scheme/Perl/Javascript)
|
|
14
|
+
- class Eruby runs very fast because FastEnhancer module is integrated into Eruby by default
|
|
15
|
+
- TinyEruby class (tiny.rb) is added
|
|
16
|
+
- module ArrayBufferEnhancer added
|
|
17
|
+
- module ArrayEnhancer added
|
|
18
|
+
- module BiPatternEnhancer added
|
|
19
|
+
- module EscapeEnhancer added
|
|
20
|
+
- module HeaderFooterEnhancer added
|
|
21
|
+
- module NoTextEnhancer added
|
|
22
|
+
- module PercentLineEnhancer added
|
|
23
|
+
- module PrintEnabledEnhancer added
|
|
24
|
+
- module PrintOutEnhancer added
|
|
25
|
+
- module SimplifyEnhancer added
|
|
26
|
+
- module StringBufferEnhancer added
|
|
27
|
+
- module StringIOEnhancer added
|
|
28
|
+
- command-line option '-b' (body only) added
|
|
29
|
+
- command-line option '-e' (escape) added
|
|
30
|
+
- command-line option '-l' (lang) added
|
|
31
|
+
- command-line option '-E' (enhancer) added
|
|
32
|
+
- command-line option '-I' (require path) added
|
|
33
|
+
- command-line option '-K' (kanji code) added
|
|
34
|
+
- command-line option '-S' (string to symbol) added
|
|
35
|
+
- command-line option '-B' (call result(binding())) added
|
|
36
|
+
|
|
37
|
+
- release: 1.1.0
|
|
38
|
+
date: 2006-03-05
|
|
39
|
+
enhances:
|
|
40
|
+
- '<%# ... %>' is supported
|
|
41
|
+
- PrintEnhancer, PrintEruby, and PrintXmlEruby added
|
|
12
42
|
|
|
13
43
|
- release: 1.0.1
|
|
14
|
-
date:
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
text: bin/erubis is available with RubyGems
|
|
44
|
+
date: 2006-02-01
|
|
45
|
+
bugfixes:
|
|
46
|
+
- bin/erubis is available with RubyGems
|
|
18
47
|
|
|
19
48
|
- release: 1.0.0
|
|
20
|
-
date:
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
text: first release
|
|
24
|
-
|
|
49
|
+
date: 2006-02-01
|
|
50
|
+
bugfixes:
|
|
51
|
+
- first release
|
|
25
52
|
|
data/README.txt
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
= README
|
|
2
|
+
|
|
3
|
+
release:: $Release: 2.0.0 $
|
|
4
|
+
copyright:: copyright(c) 2006 kuwata-lab all rights reserved.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
== About Erubis
|
|
9
|
+
|
|
10
|
+
Erubis is an implementation of eRuby. It has the following features.
|
|
11
|
+
* Very fast (about three times faster than ERB and almost as fast as eruby)
|
|
12
|
+
* Auto trimming spaces around '<% %>'
|
|
13
|
+
* Auto escape (sanitizing)
|
|
14
|
+
* Changeable embedded pattern (default '<% %>')
|
|
15
|
+
* Context object available
|
|
16
|
+
* Easy to expand and customize in subclass
|
|
17
|
+
* Multi-language support (Ruby/PHP/C/Java/Scheme/Perl/Javascript)
|
|
18
|
+
|
|
19
|
+
Erubis is implemented in pure Ruby. It requires Ruby 1.8 or higher.
|
|
20
|
+
|
|
21
|
+
See doc/users-guide.html for details.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
== Installation
|
|
26
|
+
|
|
27
|
+
* If you have installed RubyGems, just type <tt>gem install --remote erubis</tt>.
|
|
28
|
+
|
|
29
|
+
$ sudo gem install --remote erubis
|
|
30
|
+
|
|
31
|
+
* Else install abstract[http://rubyforge.org/projects/abstract/] at first,
|
|
32
|
+
and download erubis_X.X.X.tar.bz2 and install it by setup.rb.
|
|
33
|
+
|
|
34
|
+
$ tar xjf abstract_X.X.X.tar.bz2
|
|
35
|
+
$ cd abstract_X.X.X/
|
|
36
|
+
$ sudo ruby setup.rb
|
|
37
|
+
$ cd ..
|
|
38
|
+
$ tar xjf erubis_X.X.X.tar.bz2
|
|
39
|
+
$ cd erubis_X.X.X/
|
|
40
|
+
$ sudo ruby setup.rb
|
|
41
|
+
|
|
42
|
+
* (Optional) It is able to merge 'lib/**/*.rb' into 'bin/erubis' by
|
|
43
|
+
'contrib/inline-require' script.
|
|
44
|
+
|
|
45
|
+
$ tar xjf erubis_X.X.X.tar.bz2
|
|
46
|
+
$ cd erubis_X.X.X/
|
|
47
|
+
$ cp /tmp/abstract_X.X.X/lib/abstract.rb lib
|
|
48
|
+
$ unset RUBYLIB
|
|
49
|
+
$ contrib/inline-require -I lib bin/erubis > contrib/erubis
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
== Exploring Guide
|
|
54
|
+
|
|
55
|
+
If you are exploring Eruby, see the following class at first.
|
|
56
|
+
* Erubis::TinyEruby (erubis/tiny.rb) --
|
|
57
|
+
the most simple eRuby implementation.
|
|
58
|
+
* Erubis::Engine (erubis/engine.rb) --
|
|
59
|
+
base class of Eruby, Ephp, Ejava, and so on.
|
|
60
|
+
* Erubis::Eruby (erubis/engine/eruby.rb) --
|
|
61
|
+
engine class for eRuby.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
== Benchmark
|
|
66
|
+
|
|
67
|
+
'benchmark/erubybenchmark.rb' is a benchmark script of Erubis.
|
|
68
|
+
Try 'ruby erubybenchmark.rb' in benchmark directory.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
== License
|
|
73
|
+
|
|
74
|
+
GPL ver.2
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
== Author
|
|
79
|
+
|
|
80
|
+
makoto kuwata <kwa(at)kuwata-lab.com>
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
|
|
2
|
+
module Erubis
|
|
3
|
+
|
|
4
|
+
class Eruby2 < Eruby
|
|
5
|
+
def finalize_src(src)
|
|
6
|
+
#src << "\nprint _buf.join; nil\n"
|
|
7
|
+
src << "\n_buf.join; ''\n"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class ExprStrippedEruby < Eruby
|
|
12
|
+
def add_expr(src, code, indicator)
|
|
13
|
+
super(src, code.strip! || code, indicator)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
## use $stdout
|
|
20
|
+
##
|
|
21
|
+
class TinyStdoutEruby
|
|
22
|
+
|
|
23
|
+
def initialize(input)
|
|
24
|
+
@src = compile(input)
|
|
25
|
+
end
|
|
26
|
+
attr_reader :src
|
|
27
|
+
|
|
28
|
+
def result(binding=TOPLEVEL_BINDING)
|
|
29
|
+
eval @src, binding
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
EMBEDDED_PATTERN = /(.*?)<%(=+|\#)?(.*?)-?%>/m
|
|
33
|
+
|
|
34
|
+
def compile(input)
|
|
35
|
+
src = "_buf = $stdout;" # preamble
|
|
36
|
+
input.scan(EMBEDDED_PATTERN) do |text, indicator, code|
|
|
37
|
+
src << " _buf << '" << escape_text(text) << "';"
|
|
38
|
+
if !indicator # <% %>
|
|
39
|
+
src << code << ";"
|
|
40
|
+
elsif indicator[0] == ?\# # <%# %>
|
|
41
|
+
n = code.count("\n")
|
|
42
|
+
add_stmt(src, "\n" * n)
|
|
43
|
+
else # <%= %>
|
|
44
|
+
src << " _buf << (" << code << ").to_s;"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
rest = $' || input
|
|
48
|
+
src << " _buf << '" << escape_text(rest) << "';"
|
|
49
|
+
src << "\nnil\n" # postamble
|
|
50
|
+
return src
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def escape_text(text)
|
|
54
|
+
return text.gsub!(/['\\]/, '\\\\\&') || text
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
##
|
|
61
|
+
## use print statement
|
|
62
|
+
##
|
|
63
|
+
class TinyPrintEruby
|
|
64
|
+
|
|
65
|
+
def initialize(input)
|
|
66
|
+
@src = compile(input)
|
|
67
|
+
end
|
|
68
|
+
attr_reader :src
|
|
69
|
+
|
|
70
|
+
def result(binding=TOPLEVEL_BINDING)
|
|
71
|
+
eval @src, binding
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
EMBEDDED_PATTERN = /(.*?)<%(=+|\#)?(.*?)-?%>/m
|
|
75
|
+
|
|
76
|
+
def compile(input)
|
|
77
|
+
src = ""
|
|
78
|
+
input.scan(EMBEDDED_PATTERN) do |text, indicator, code|
|
|
79
|
+
src << " print '" << escape_text(text) << "';"
|
|
80
|
+
if !indicator # <% %>
|
|
81
|
+
src << code << ";"
|
|
82
|
+
elsif indicator[0] == ?\# # <%# %>
|
|
83
|
+
n = code.count("\n")
|
|
84
|
+
add_stmt(src, "\n" * n)
|
|
85
|
+
else # <%= %>
|
|
86
|
+
src << " print((" << code << ").to_s);"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
rest = $' || input
|
|
90
|
+
src << " print '" << escape_text(rest) << "';"
|
|
91
|
+
src << "\nnil\n"
|
|
92
|
+
return src
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def escape_text(text)
|
|
96
|
+
return text.gsub!(/['\\]/, '\\\\\&') || text
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
##
|
|
103
|
+
## for test
|
|
104
|
+
##
|
|
105
|
+
class Optimized2Eruby < Eruby # :nodoc:
|
|
106
|
+
|
|
107
|
+
def self.supported_properties() # :nodoc:
|
|
108
|
+
return super
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def initialize(input, properties={})
|
|
112
|
+
@initialized = false
|
|
113
|
+
#@prev_is_expr = false
|
|
114
|
+
super
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
protected
|
|
118
|
+
|
|
119
|
+
def escape_text(text)
|
|
120
|
+
text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def escaped_expr(code)
|
|
124
|
+
return "Erubis::XmlHelper.escape_xml(#{code})"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
#def switch_to_expr(src)
|
|
128
|
+
# return if @prev_is_expr
|
|
129
|
+
# @prev_is_expr = true
|
|
130
|
+
# src << ' _buf'
|
|
131
|
+
#end
|
|
132
|
+
|
|
133
|
+
#def switch_to_stmt(src)
|
|
134
|
+
# return unless @prev_is_expr
|
|
135
|
+
# @prev_is_expr = false
|
|
136
|
+
# src << ';'
|
|
137
|
+
#end
|
|
138
|
+
|
|
139
|
+
def add_preamble(src)
|
|
140
|
+
@initialized = false
|
|
141
|
+
#@prev_is_expr = false
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def add_text(src, text)
|
|
145
|
+
return if text.empty?
|
|
146
|
+
if @initialized
|
|
147
|
+
#switch_to_expr(src)
|
|
148
|
+
#src << " << '" << escape_text(text) << "'"
|
|
149
|
+
src << "_buf << '" << escape_text(text) << "';"
|
|
150
|
+
else
|
|
151
|
+
src << "_buf = '" << escape_text(text) << "';"
|
|
152
|
+
@initialized = true
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def add_stmt(src, code)
|
|
157
|
+
#switch_to_stmt(src) if @initialized
|
|
158
|
+
#super
|
|
159
|
+
src << code << ';'
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def add_expr_literal(src, code)
|
|
163
|
+
unless @initialized; src << "_buf = ''"; @initialized = true; end
|
|
164
|
+
#switch_to_expr(src)
|
|
165
|
+
#src << " << (" << code << ").to_s"
|
|
166
|
+
src << " _buf << (" << code << ").to_s;"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def add_expr_escaped(src, code)
|
|
170
|
+
unless @initialized; src << "_buf = ''"; @initialized = true; end
|
|
171
|
+
#switch_to_expr(src)
|
|
172
|
+
#src << " << " << escaped_expr(code)
|
|
173
|
+
src << " _buf << " << escaped_expr(code) << ';'
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def add_expr_debug(src, code)
|
|
177
|
+
code.strip!
|
|
178
|
+
s = (code.dump =~ /\A"(.*)"\z/) && $1
|
|
179
|
+
src << ' $stderr.puts("*** debug: ' << s << '=#{(' << code << ').inspect}");'
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def add_postamble(src)
|
|
183
|
+
#super if @initialized
|
|
184
|
+
src << "\n_buf\n" if @initialized
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
##
|
|
2
|
+
## $Rev: 21 $
|
|
3
|
+
## $Release: 2.0.0 $
|
|
4
|
+
## copyright(c) 2006 kuwata-lab all rights reserved.
|
|
5
|
+
##
|
|
6
|
+
|
|
7
|
+
require 'eruby'
|
|
8
|
+
require 'erb'
|
|
9
|
+
require 'stringio'
|
|
10
|
+
|
|
11
|
+
require 'erubis'
|
|
12
|
+
require 'erubis/engine/enhanced'
|
|
13
|
+
require 'erubis/engine/optimized'
|
|
14
|
+
require 'erubis/tiny'
|
|
15
|
+
require 'erubybench-lib'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## default values
|
|
20
|
+
filename = 'erubybench.rhtml'
|
|
21
|
+
datafile = 'erubybench.yaml'
|
|
22
|
+
n = 10000
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## usage
|
|
26
|
+
def usage(n, filename, datafile)
|
|
27
|
+
s = "Usage: ruby #{$0} [-h] [-n N] [-f file] [-d file] [testname ...]\n"
|
|
28
|
+
s << " -h : help\n"
|
|
29
|
+
s << " -n N : number of times to loop (default #{n})\n"
|
|
30
|
+
s << " -f file : eruby filename (default '#{filename}')\n"
|
|
31
|
+
s << " -d file : data filename (default '#{datafile}')\n"
|
|
32
|
+
return s
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## parse command-line options
|
|
37
|
+
flag_help = false
|
|
38
|
+
flag_all = false
|
|
39
|
+
targets = nil
|
|
40
|
+
test_type = nil
|
|
41
|
+
compiler_name = 'ErubisOptimized'
|
|
42
|
+
while !ARGV.empty? && ARGV[0][0] == ?-
|
|
43
|
+
opt = ARGV.shift
|
|
44
|
+
case opt
|
|
45
|
+
when '-n' ; n = ARGV.shift.to_i
|
|
46
|
+
when '-f' ; filename = ARGV.shift
|
|
47
|
+
when '-d' ; datafile = ARGV.shift
|
|
48
|
+
when '-h', '--help' ; flag_help = true
|
|
49
|
+
when '-A' ; test_all = true
|
|
50
|
+
when '-C' ; compiler_name = ARGV.shift
|
|
51
|
+
when '-t' ; test_type = ARGV.shift
|
|
52
|
+
else ; raise "#{opt}: invalid option."
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
puts "** n=#{n.inspect}, filename=#{filename.inspect}, datafile=#{datafile.inspect}"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## help
|
|
59
|
+
if flag_help
|
|
60
|
+
puts usage(n, filename, datafile)
|
|
61
|
+
exit()
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## load data file
|
|
66
|
+
require 'yaml'
|
|
67
|
+
ydoc = YAML.load_file(datafile)
|
|
68
|
+
data = []
|
|
69
|
+
ydoc['data'].each do |hash|
|
|
70
|
+
data << hash.inject({}) { |h, t| h[t[0].intern] = t[1]; h }
|
|
71
|
+
#h = {}; hash.each { |k, v| h[k.intern] = v } ; data << h
|
|
72
|
+
end
|
|
73
|
+
data = data.sort_by { |h| h[:code] }
|
|
74
|
+
#require 'pp'; pp data
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## open /dev/null
|
|
78
|
+
$devnull = File.open("/dev/null", 'w')
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## test definitions
|
|
82
|
+
testdefs_str = <<END
|
|
83
|
+
- name: ERuby
|
|
84
|
+
class: ERuby
|
|
85
|
+
code: |
|
|
86
|
+
ERuby.import(filename)
|
|
87
|
+
compile: |
|
|
88
|
+
ERuby::Compiler.new.compile_string(str)
|
|
89
|
+
return: null
|
|
90
|
+
|
|
91
|
+
- name: ERB
|
|
92
|
+
class: ERB
|
|
93
|
+
code: |
|
|
94
|
+
print ERB.new(File.read(filename)).result(binding())
|
|
95
|
+
# eruby = ERB.new(File.read(filename))
|
|
96
|
+
# print eruby.result(binding())
|
|
97
|
+
compile: |
|
|
98
|
+
ERB.new(str).src
|
|
99
|
+
return: str
|
|
100
|
+
|
|
101
|
+
- name: ErubisEruby
|
|
102
|
+
class: Erubis::Eruby
|
|
103
|
+
return: str
|
|
104
|
+
|
|
105
|
+
- name: ErubisEruby2
|
|
106
|
+
desc: print _buf #, no binding()
|
|
107
|
+
class: Erubis::Eruby2
|
|
108
|
+
code: |
|
|
109
|
+
#Erubis::Eruby2.new(File.read(filename)).result()
|
|
110
|
+
Erubis::Eruby2.new(File.read(filename)).result(binding())
|
|
111
|
+
return: null
|
|
112
|
+
skip: yes
|
|
113
|
+
|
|
114
|
+
- name: ErubisExprStripped
|
|
115
|
+
desc: strip expr code
|
|
116
|
+
class: Erubis::ExprStrippedEruby
|
|
117
|
+
return: str
|
|
118
|
+
skip: yes
|
|
119
|
+
|
|
120
|
+
- name: ErubisOptimized
|
|
121
|
+
class: Erubis::OptimizedEruby
|
|
122
|
+
return: str
|
|
123
|
+
skip: yes
|
|
124
|
+
|
|
125
|
+
- name: ErubisOptimized2
|
|
126
|
+
class: Erubis::Optimized2Eruby
|
|
127
|
+
return: str
|
|
128
|
+
skip: yes
|
|
129
|
+
|
|
130
|
+
#- name: ErubisArrayBuffer
|
|
131
|
+
# class: Erubis::ArrayBufferEruby
|
|
132
|
+
# code: |
|
|
133
|
+
# Erubis::ArrayBufferEruby.new(File.read(filename)).result(binding())
|
|
134
|
+
# compile: |
|
|
135
|
+
# Erubis::ArrayBufferEruby.new(str).src
|
|
136
|
+
# return: str
|
|
137
|
+
# skip: no
|
|
138
|
+
|
|
139
|
+
- name: ErubisStringBuffer
|
|
140
|
+
class: Erubis::StringBufferEruby
|
|
141
|
+
return: str
|
|
142
|
+
skip: no
|
|
143
|
+
|
|
144
|
+
- name: ErubisStringIO
|
|
145
|
+
class: Erubis::StringIOEruby
|
|
146
|
+
return: str
|
|
147
|
+
skip: yes
|
|
148
|
+
|
|
149
|
+
- name: ErubisSimplified
|
|
150
|
+
class: Erubis::SimplifiedEruby
|
|
151
|
+
return: str
|
|
152
|
+
skip: no
|
|
153
|
+
|
|
154
|
+
- name: ErubisStdout
|
|
155
|
+
class: Erubis::StdoutEruby
|
|
156
|
+
return: null
|
|
157
|
+
skip: no
|
|
158
|
+
|
|
159
|
+
- name: ErubisStdoutSimplified
|
|
160
|
+
class: Erubis::StdoutSimplifiedEruby
|
|
161
|
+
return: str
|
|
162
|
+
skip: no
|
|
163
|
+
|
|
164
|
+
- name: ErubisPrintOut
|
|
165
|
+
class: Erubis::PrintOutEruby
|
|
166
|
+
return: str
|
|
167
|
+
skip: no
|
|
168
|
+
|
|
169
|
+
- name: ErubisPrintOutSimplified
|
|
170
|
+
class: Erubis::PrintOutSimplifiedEruby
|
|
171
|
+
return: str
|
|
172
|
+
skip: no
|
|
173
|
+
|
|
174
|
+
- name: ErubisTiny
|
|
175
|
+
class: Erubis::TinyEruby
|
|
176
|
+
return: yes
|
|
177
|
+
skip: no
|
|
178
|
+
|
|
179
|
+
- name: ErubisTinyStdout
|
|
180
|
+
class: Erubis::TinyStdoutEruby
|
|
181
|
+
return: null
|
|
182
|
+
skip: no
|
|
183
|
+
|
|
184
|
+
- name: ErubisTinyPrint
|
|
185
|
+
class: Erubis::TinyPrintEruby
|
|
186
|
+
return: null
|
|
187
|
+
skip: no
|
|
188
|
+
|
|
189
|
+
#- name: load
|
|
190
|
+
# class: load
|
|
191
|
+
# code: |
|
|
192
|
+
# load($load_filename)
|
|
193
|
+
# compile: null
|
|
194
|
+
# return: null
|
|
195
|
+
# skip: yes
|
|
196
|
+
|
|
197
|
+
END
|
|
198
|
+
testdefs = YAML.load(testdefs_str)
|
|
199
|
+
|
|
200
|
+
## manipulate
|
|
201
|
+
testdefs.each do |testdef|
|
|
202
|
+
c = testdef['class']
|
|
203
|
+
testdef['code'] ||= "print #{c}.new(File.read(filename)).result(binding())\n"
|
|
204
|
+
testdef['compile'] ||= "#{c}.new(str).src\n"
|
|
205
|
+
require 'pp'
|
|
206
|
+
#pp testdef
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
### create file for load
|
|
211
|
+
#if testdefs.find { |h| h['name'] == 'load' }
|
|
212
|
+
# $load_filename = filename + ".tmp" # for load
|
|
213
|
+
# $data = data
|
|
214
|
+
# str = File.read(filename)
|
|
215
|
+
# str.gsub!(/\bdata\b/, '$data')
|
|
216
|
+
# hash = testdefs.find { |h| h['name'] == compiler_name }
|
|
217
|
+
# code = eval hash['compile']
|
|
218
|
+
# code.sub!(/_buf\s*\z/, 'print \&')
|
|
219
|
+
# File.open($load_filename, 'w') { |f| f.write(code) }
|
|
220
|
+
# at_exit do
|
|
221
|
+
# File.unlink $load_filename if test(?f, $load_filename)
|
|
222
|
+
# end
|
|
223
|
+
#end
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
## select test target
|
|
227
|
+
if test_all
|
|
228
|
+
#testdefs.each { |h| h['skip'] = false }
|
|
229
|
+
elsif !ARGV.empty?
|
|
230
|
+
#testdefs.each { |h| h['skip'] = ARGV.include?(h['name']) }
|
|
231
|
+
testdefs.delete_if { |h| !ARGV.include?(h['name']) }
|
|
232
|
+
else
|
|
233
|
+
testdefs.delete_if { |h| h['skip'] }
|
|
234
|
+
end
|
|
235
|
+
#require 'pp'
|
|
236
|
+
#pp testdefs
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
## define test functions for each classes
|
|
240
|
+
testdefs.each do |h|
|
|
241
|
+
s = ''
|
|
242
|
+
s << "def test_#{h['name']}(filename, data)\n"
|
|
243
|
+
s << " $stdout = $devnull\n"
|
|
244
|
+
n.times do
|
|
245
|
+
s << ' ' << h['code'] #<< "\n"
|
|
246
|
+
end
|
|
247
|
+
s << " $stdout = STDOUT\n"
|
|
248
|
+
s << "end\n"
|
|
249
|
+
#puts s
|
|
250
|
+
eval s
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
## define view functions for each classes
|
|
255
|
+
str = File.read(filename)
|
|
256
|
+
testdefs.each do |h|
|
|
257
|
+
next unless h['compile']
|
|
258
|
+
code = eval h['compile']
|
|
259
|
+
s = <<-END
|
|
260
|
+
def view_#{h['name']}(data)
|
|
261
|
+
#{code}
|
|
262
|
+
end
|
|
263
|
+
END
|
|
264
|
+
#puts s
|
|
265
|
+
eval s
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
## define tests for view functions
|
|
270
|
+
testdefs.each do |h|
|
|
271
|
+
pr = h['return'] ? 'print ' : ''
|
|
272
|
+
s = ''
|
|
273
|
+
s << "def test_view_#{h['name']}(data)\n"
|
|
274
|
+
s << " $stdout = $devnull\n"
|
|
275
|
+
n.times do
|
|
276
|
+
s << " #{pr}view_#{h['name']}(data)\n"
|
|
277
|
+
end
|
|
278
|
+
s << " $stdout = STDOUT\n"
|
|
279
|
+
s << "end\n"
|
|
280
|
+
#puts s
|
|
281
|
+
eval s
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
## define tests for caching
|
|
286
|
+
str = File.read(filename)
|
|
287
|
+
testdefs.each do |h|
|
|
288
|
+
next unless h['compile']
|
|
289
|
+
# create file to read
|
|
290
|
+
code = eval h['compile']
|
|
291
|
+
fname = "#{filename}.#{h['name']}"
|
|
292
|
+
File.open(fname, 'w') { |f| f.write(code) }
|
|
293
|
+
#at_exit do File.unlink fname if test(?f, fname) end
|
|
294
|
+
# define function
|
|
295
|
+
pr = h['return'] ? 'print ' : ''
|
|
296
|
+
s = ''
|
|
297
|
+
s << "def test_cache_#{h['name']}(filename, data)\n"
|
|
298
|
+
s << " $stdout = $devnull\n"
|
|
299
|
+
n.times do
|
|
300
|
+
s << " #{pr}eval(File.read(\"\#{filename}.#{h['name']}\"))\n"
|
|
301
|
+
end
|
|
302
|
+
s << " $stdout = STDOUT\n"
|
|
303
|
+
s << "end\n"
|
|
304
|
+
#puts s
|
|
305
|
+
eval s
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
## rehearsal
|
|
310
|
+
$stdout = $devnull
|
|
311
|
+
testdefs.each do |h|
|
|
312
|
+
## execute test code
|
|
313
|
+
eval h['code']
|
|
314
|
+
## execute view function
|
|
315
|
+
next unless h['compile']
|
|
316
|
+
v = __send__("view_#{h['name']}", data)
|
|
317
|
+
print v if h['return']
|
|
318
|
+
## execute caching function
|
|
319
|
+
v = eval(File.read("#{filename}.#{h['name']}"))
|
|
320
|
+
print v if h['return']
|
|
321
|
+
end
|
|
322
|
+
$stdout = STDOUT
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
## do benchmark
|
|
326
|
+
require 'benchmark'
|
|
327
|
+
begin
|
|
328
|
+
Benchmark.bmbm(25) do |job|
|
|
329
|
+
## basic test
|
|
330
|
+
testdefs.each do |h|
|
|
331
|
+
title = h['class']
|
|
332
|
+
func = 'test_' + h['name']
|
|
333
|
+
GC.start
|
|
334
|
+
job.report(title) do
|
|
335
|
+
__send__(func, filename, data)
|
|
336
|
+
end
|
|
337
|
+
end if !test_type || test_type == 'basic'
|
|
338
|
+
|
|
339
|
+
## caching function
|
|
340
|
+
testdefs.each do |h|
|
|
341
|
+
next unless h['compile']
|
|
342
|
+
title = 'cache_' + h['name']
|
|
343
|
+
func = 'test_cache_' + h['name']
|
|
344
|
+
GC.start
|
|
345
|
+
job.report(title) do
|
|
346
|
+
__send__(func, filename, data)
|
|
347
|
+
end
|
|
348
|
+
end if !test_type || test_type == 'eval'
|
|
349
|
+
|
|
350
|
+
## view-function test
|
|
351
|
+
testdefs.each do |h|
|
|
352
|
+
next unless h['compile']
|
|
353
|
+
title = 'func_' + h['name']
|
|
354
|
+
func = 'test_view_' + h['name']
|
|
355
|
+
GC.start
|
|
356
|
+
job.report(title) do
|
|
357
|
+
__send__(func, data)
|
|
358
|
+
end
|
|
359
|
+
end if !test_type || test_type == 'func'
|
|
360
|
+
|
|
361
|
+
end
|
|
362
|
+
ensure
|
|
363
|
+
$devnull.close()
|
|
364
|
+
end
|