mvz-live_ast 1.1.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.
- checksums.yaml +7 -0
- data/CHANGES.rdoc +93 -0
- data/README.rdoc +419 -0
- data/Rakefile +21 -0
- data/devel/levitate.rb +853 -0
- data/devel/levitate_config.rb +4 -0
- data/lib/live_ast.rb +4 -0
- data/lib/live_ast/ast_eval.rb +11 -0
- data/lib/live_ast/ast_load.rb +15 -0
- data/lib/live_ast/base.rb +73 -0
- data/lib/live_ast/common.rb +48 -0
- data/lib/live_ast/error.rb +20 -0
- data/lib/live_ast/evaler.rb +32 -0
- data/lib/live_ast/full.rb +2 -0
- data/lib/live_ast/irb_spy.rb +43 -0
- data/lib/live_ast/linker.rb +122 -0
- data/lib/live_ast/loader.rb +60 -0
- data/lib/live_ast/reader.rb +26 -0
- data/lib/live_ast/replace_eval.rb +121 -0
- data/lib/live_ast/replace_load.rb +14 -0
- data/lib/live_ast/replace_raise.rb +18 -0
- data/lib/live_ast/ruby_parser.rb +36 -0
- data/lib/live_ast/ruby_parser/test.rb +197 -0
- data/lib/live_ast/ruby_parser/unparser.rb +13 -0
- data/lib/live_ast/to_ast.rb +26 -0
- data/lib/live_ast/to_ruby.rb +24 -0
- data/lib/live_ast/version.rb +3 -0
- data/test/ast_eval_feature_test.rb +11 -0
- data/test/ast_load_feature_test.rb +11 -0
- data/test/attr_test.rb +24 -0
- data/test/backtrace_test.rb +158 -0
- data/test/covert_define_method_test.rb +23 -0
- data/test/def_test.rb +35 -0
- data/test/define_method_test.rb +67 -0
- data/test/define_singleton_method_test.rb +15 -0
- data/test/encoding_test.rb +52 -0
- data/test/encoding_test/bad.rb +1 -0
- data/test/encoding_test/cp932.rb +6 -0
- data/test/encoding_test/default.rb +5 -0
- data/test/encoding_test/eucjp.rb +6 -0
- data/test/encoding_test/koi8.rb +6 -0
- data/test/encoding_test/koi8_shebang.rb +7 -0
- data/test/encoding_test/koi8_with_utf8bom.rb +6 -0
- data/test/encoding_test/usascii.rb +6 -0
- data/test/encoding_test/usascii_with_utf8bom.rb +6 -0
- data/test/encoding_test/utf8.rb +6 -0
- data/test/encoding_test/utf8bom.rb +6 -0
- data/test/encoding_test/utf8bom_only.rb +5 -0
- data/test/encoding_test/utf8dos.rb +6 -0
- data/test/encoding_test/utf8mac.rb +6 -0
- data/test/encoding_test/utf8mac_alt.rb +6 -0
- data/test/encoding_test/utf8unix.rb +6 -0
- data/test/error_test.rb +116 -0
- data/test/eval_test.rb +269 -0
- data/test/flush_cache_test.rb +98 -0
- data/test/irb_test.rb +25 -0
- data/test/lambda_test.rb +56 -0
- data/test/load_path_test.rb +78 -0
- data/test/load_test.rb +123 -0
- data/test/main.rb +140 -0
- data/test/nested_test.rb +29 -0
- data/test/noninvasive_test.rb +51 -0
- data/test/readme_test.rb +16 -0
- data/test/recursive_eval_test.rb +52 -0
- data/test/redefine_method_test.rb +83 -0
- data/test/reload_test.rb +105 -0
- data/test/replace_eval_test.rb +405 -0
- data/test/rubygems_test.rb +25 -0
- data/test/rubyspec_test.rb +39 -0
- data/test/singleton_test.rb +25 -0
- data/test/stdlib_test.rb +13 -0
- data/test/thread_test.rb +44 -0
- data/test/to_ast_feature_test.rb +15 -0
- data/test/to_ruby_feature_test.rb +15 -0
- data/test/to_ruby_test.rb +87 -0
- metadata +275 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4396a6fdc53cf54aeb3b6266167f0068549d7d2c
|
4
|
+
data.tar.gz: bdd39a8334d5f29c054d72c5125d21347b0dfa19
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 81b894dcecb96cb803a65c06d77f99f374a91c877721dd5d6fd220b7f5bf79fe5a951d0426d65973d99d404146d146977995942b0ee7344bf3c6c685f2d128c6
|
7
|
+
data.tar.gz: 8ff9b6c24ff52fffd01bb0acca72c391fdab696b5954892da9a98441859eaf109da06798a9362ff347cc221204325ccafdf4c743cc3c08a71e0c3f1d69b3eb10
|
data/CHANGES.rdoc
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
= live_ast Changes
|
3
|
+
|
4
|
+
== Version 1.1.0
|
5
|
+
|
6
|
+
* incorporate default parser in the main gem
|
7
|
+
* update RubyParser dependency
|
8
|
+
* use binding_of_caller gem instead of boc
|
9
|
+
|
10
|
+
== Version 1.0.2
|
11
|
+
|
12
|
+
* handle -unix, -dos, -mac special encoding suffixes
|
13
|
+
|
14
|
+
== Version 1.0.1
|
15
|
+
|
16
|
+
* add tests for "def self.f" and "def A.f" (plugins were missing this construct)
|
17
|
+
|
18
|
+
== Version 1.0.0
|
19
|
+
|
20
|
+
* no known bugs; API is settled
|
21
|
+
* ast_load respects $VERBOSE=true
|
22
|
+
|
23
|
+
== Version 0.7.3
|
24
|
+
|
25
|
+
* live_ast/full now available for jruby (via boc gem)
|
26
|
+
* fix instance_eval with BasicObject instance
|
27
|
+
|
28
|
+
== Version 0.7.2
|
29
|
+
|
30
|
+
* fix old find&replace accident with boc; rubyspec test now enabled by default
|
31
|
+
|
32
|
+
== Version 0.7.1
|
33
|
+
|
34
|
+
* fix rubygems problem when parser not loaded after live_ast/full
|
35
|
+
|
36
|
+
== Version 0.7.0
|
37
|
+
|
38
|
+
* eval replacement option now included in the gem
|
39
|
+
* new 'boc' gem for eval replacement -- no more syntax restrictions
|
40
|
+
* add require 'live_ast/full' -- shortcut for live_ast + live_ast/replace_eval
|
41
|
+
* rubyspec conformance for require 'live_ast/full'
|
42
|
+
* added required_ruby_version to gemspec
|
43
|
+
* fixed error when IRB is partially required
|
44
|
+
|
45
|
+
== Version 0.6.3
|
46
|
+
|
47
|
+
* minor change for Ruby 1.9.3
|
48
|
+
|
49
|
+
== Version 0.6.2
|
50
|
+
|
51
|
+
* simplified irb handling; readline no longer required
|
52
|
+
* add -e notes to readme
|
53
|
+
|
54
|
+
== Version 0.6.1
|
55
|
+
|
56
|
+
* enable usage inside irb
|
57
|
+
|
58
|
+
== Version 0.6.0
|
59
|
+
|
60
|
+
* removed FlushError and NoSourceError -- not possible to distinguish these
|
61
|
+
* added more tests
|
62
|
+
* refined testing API for plugins
|
63
|
+
|
64
|
+
== Version 0.5.2
|
65
|
+
|
66
|
+
* fix default plugin version
|
67
|
+
|
68
|
+
== Version 0.5.1
|
69
|
+
|
70
|
+
* protect against user needlessly requiring default parser
|
71
|
+
|
72
|
+
== Version 0.5.0
|
73
|
+
|
74
|
+
* new parser plugin API
|
75
|
+
|
76
|
+
== Version 0.2.3
|
77
|
+
|
78
|
+
* fix a utf-8 BOM issue
|
79
|
+
|
80
|
+
== Version 0.2.2
|
81
|
+
|
82
|
+
* handle utf-8 BOMs in loading
|
83
|
+
|
84
|
+
== Version 0.2.1
|
85
|
+
|
86
|
+
* fixed some rdoc issues
|
87
|
+
* removed rubyforge references
|
88
|
+
* update ruby_parser
|
89
|
+
* less MRI-centric tests
|
90
|
+
|
91
|
+
== Version 0.2.0
|
92
|
+
|
93
|
+
* initial release
|
data/README.rdoc
ADDED
@@ -0,0 +1,419 @@
|
|
1
|
+
|
2
|
+
= LiveAST
|
3
|
+
|
4
|
+
== Summary
|
5
|
+
|
6
|
+
Live abstract syntax trees of methods and procs. Fork of +live_ast+
|
7
|
+
(http://quix.github.com/live_ast).
|
8
|
+
|
9
|
+
== Synopsis
|
10
|
+
|
11
|
+
require 'live_ast'
|
12
|
+
|
13
|
+
class Greet
|
14
|
+
def default
|
15
|
+
"hello"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#### ASTs of methods
|
20
|
+
|
21
|
+
p Greet.instance_method(:default).to_ast
|
22
|
+
# => s(:defn, :default, s(:args), s(:str, "hello"))
|
23
|
+
|
24
|
+
#### ASTs of lambdas, procs, blocks
|
25
|
+
|
26
|
+
f = lambda { "foo" }
|
27
|
+
p f.to_ast
|
28
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "foo"))
|
29
|
+
|
30
|
+
def query(&block)
|
31
|
+
p block.to_ast
|
32
|
+
# => s(:iter, s(:call, nil, :query), s(:args), s(:str, "bar"))
|
33
|
+
end
|
34
|
+
|
35
|
+
query do
|
36
|
+
"bar"
|
37
|
+
end
|
38
|
+
|
39
|
+
#### ASTs from dynamic code -- pure ruby version
|
40
|
+
|
41
|
+
u = ast_eval "lambda { 'dynamic3' }", binding
|
42
|
+
p u.to_ast
|
43
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic3"))
|
44
|
+
|
45
|
+
ast_eval "def v ; 'dynamic4' ; end", binding
|
46
|
+
p method(:v).to_ast
|
47
|
+
# => s(:defn, :v, s(:args), s(:str, "dynamic4"))
|
48
|
+
|
49
|
+
#### ASTs from dynamic code -- fully integrated version
|
50
|
+
|
51
|
+
require 'live_ast/full'
|
52
|
+
|
53
|
+
f = eval "lambda { 'dynamic1' }"
|
54
|
+
p f.to_ast
|
55
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic1"))
|
56
|
+
|
57
|
+
eval "def g ; 'dynamic2' ; end"
|
58
|
+
p method(:g).to_ast
|
59
|
+
# => s(:defn, :g, s(:args), s(:str, "dynamic2"))
|
60
|
+
|
61
|
+
== Install
|
62
|
+
|
63
|
+
% gem install mvz-live_ast
|
64
|
+
|
65
|
+
== Description
|
66
|
+
|
67
|
+
LiveAST enables a program to find the ASTs of objects created by
|
68
|
+
dynamically generated code. It may be used in a strictly noninvasive
|
69
|
+
manner, where no standard classes or methods are modified, or it may
|
70
|
+
be transparently integrated into Ruby. The default setting is in
|
71
|
+
between.
|
72
|
+
|
73
|
+
RubyParser is the default parsing engine. To replace it with Ripper,
|
74
|
+
<code>gem install live_ast_ripper</code> and then <code>require
|
75
|
+
'live_ast_ripper'</code>. A simple plug-in interface allows LiveAST to
|
76
|
+
work with any parser.
|
77
|
+
|
78
|
+
The advantage of RubyParser is that it gives the traditional ParseTree
|
79
|
+
sexps used by tools such as <code>ruby2ruby</code>.
|
80
|
+
|
81
|
+
LiveAST is thread-safe.
|
82
|
+
|
83
|
+
Ruby 1.9.2 or higher is required.
|
84
|
+
|
85
|
+
== Links
|
86
|
+
|
87
|
+
* Home: https://github.com/mvz/live_ast
|
88
|
+
* Feature Requests, Bug Reports: https://github.com/mvz/live_ast/issues
|
89
|
+
|
90
|
+
== +to_ruby+
|
91
|
+
|
92
|
+
When the default parser is active,
|
93
|
+
|
94
|
+
require 'live_ast/to_ruby'
|
95
|
+
|
96
|
+
will define the +to_ruby+ method for the +Method+, +UnboundMethod+,
|
97
|
+
and +Proc+ classes. These methods are one-liners which pass the
|
98
|
+
extracted ASTs to <code>ruby2ruby</code>.
|
99
|
+
|
100
|
+
require 'live_ast/to_ruby'
|
101
|
+
|
102
|
+
p lambda { |x, y| x + y }.to_ruby # => "lambda { |x, y| (x + y) }"
|
103
|
+
|
104
|
+
class A
|
105
|
+
def f
|
106
|
+
"A#f"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
p A.instance_method(:f).to_ruby # => "def f\n \"A#f\"\nend"
|
111
|
+
|
112
|
+
In general, +to_ruby+ will hook into the unparser provided by the
|
113
|
+
parser plug-in, if one is found.
|
114
|
+
|
115
|
+
== Pure Ruby and +ast_eval+
|
116
|
+
|
117
|
+
An essential feature of <code>require 'live_ast'</code> is that it is
|
118
|
+
implemented in pure ruby. However since pure ruby is not powerful
|
119
|
+
enough to replace +eval+, in this case +ast_eval+ must be used instead
|
120
|
+
of +eval+ for AST-accessible objects. +ast_eval+ has the same
|
121
|
+
semantics as +eval+ except that the binding argument is required.
|
122
|
+
|
123
|
+
require 'live_ast'
|
124
|
+
|
125
|
+
u = ast_eval "lambda { 'dynamic3' }", binding
|
126
|
+
p u.to_ast
|
127
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic3"))
|
128
|
+
|
129
|
+
== Full Integration
|
130
|
+
|
131
|
+
In order for LiveAST to be transparent to the user, +eval+ must be
|
132
|
+
replaced. This is accomplished with the help of the +binding_of_caller+ gem
|
133
|
+
(https://github.com/banister/binding_of_caller).
|
134
|
+
|
135
|
+
To replace +eval+,
|
136
|
+
|
137
|
+
require 'live_ast/full'
|
138
|
+
|
139
|
+
The new AST-electrified +eval+, +instance_eval+, +module_eval+,
|
140
|
+
+class_eval+, and <code>Binding#eval</code> all pass RubySpec
|
141
|
+
(http://rubyspec.org) with the minor exception of backtraces sometimes
|
142
|
+
not matching that of the original +eval+ (see the "Backtraces" section
|
143
|
+
below for details).
|
144
|
+
|
145
|
+
require 'live_ast/full'
|
146
|
+
|
147
|
+
f = eval "lambda { 'dynamic1' }"
|
148
|
+
p f.to_ast
|
149
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic1"))
|
150
|
+
|
151
|
+
Since LiveAST itself is pure ruby, any platforms supported by
|
152
|
+
+binding_of_caller+ should work with <code>live_ast/full</code>.
|
153
|
+
|
154
|
+
== Limitations
|
155
|
+
|
156
|
+
A method or block definition must not share a line with other methods
|
157
|
+
or blocks in order for its AST to be accessible.
|
158
|
+
|
159
|
+
require 'live_ast'
|
160
|
+
|
161
|
+
class A
|
162
|
+
def f ; end ; def g ; end
|
163
|
+
end
|
164
|
+
A.instance_method(:f).to_ast # => raises LiveAST::MultipleDefinitionsOnSameLineError
|
165
|
+
|
166
|
+
a = lambda { } ; b = lambda { }
|
167
|
+
a.to_ast # => raises LiveAST::MultipleDefinitionsOnSameLineError
|
168
|
+
|
169
|
+
Code given to the <code>-e</code> command-line switch is not
|
170
|
+
AST-accessible.
|
171
|
+
|
172
|
+
Evaled code appearing before <code>require 'live_ast/full'</code> is
|
173
|
+
not AST-accessible.
|
174
|
+
|
175
|
+
In some circumstances +ast_eval+ and the replaced +eval+ will not give
|
176
|
+
the same backtrace as the original +eval+ (next section).
|
177
|
+
|
178
|
+
----
|
179
|
+
== <em>Technical Issues</em>
|
180
|
+
|
181
|
+
You can probably skip these next sections. Goodbye.
|
182
|
+
----
|
183
|
+
|
184
|
+
== Backtraces
|
185
|
+
|
186
|
+
+ast_eval+ is meant to be compatible with +eval+. For instance the
|
187
|
+
first line of +ast_eval+'s backtrace should be identical to that of
|
188
|
+
+eval+:
|
189
|
+
|
190
|
+
require 'live_ast'
|
191
|
+
|
192
|
+
ast_eval %{ raise "boom" }, binding
|
193
|
+
# => test.rb:3:in `<main>': boom (RuntimeError)
|
194
|
+
|
195
|
+
Let's make a slight change,
|
196
|
+
|
197
|
+
require 'live_ast'
|
198
|
+
|
199
|
+
f = ast_eval %{ lambda { raise "boom" } }, binding
|
200
|
+
f.call
|
201
|
+
# => test.rb|ast@a:3:in `block in <main>': boom (RuntimeError)
|
202
|
+
|
203
|
+
What the heck is '<code>|ast@a</code>' doing there? LiveAST's
|
204
|
+
implementation has just been exposed: each source input is assigned a
|
205
|
+
unique key which enables a Ruby object to find its own definition.
|
206
|
+
|
207
|
+
In the first case above, +ast_eval+ has removed the key from the
|
208
|
+
exception backtrace. But in the second case there is no opportunity to
|
209
|
+
remove it since +ast_eval+ has already returned.
|
210
|
+
|
211
|
+
If you find this to be problem---for example if you cannot add a
|
212
|
+
filter for the jump-to-location feature in your editor---then +raise+
|
213
|
+
may be redefined to strip these tokens,
|
214
|
+
|
215
|
+
require 'live_ast'
|
216
|
+
require 'live_ast/replace_raise'
|
217
|
+
|
218
|
+
f = ast_eval %{ lambda { raise "boom" } }, binding
|
219
|
+
f.call
|
220
|
+
# => test.rb:4:in `block in <main>': boom (RuntimeError)
|
221
|
+
|
222
|
+
However this only applies to a +raise+ call originating from Ruby
|
223
|
+
code. An exception from within a native method will likely still
|
224
|
+
contain the token in its backtrace (e.g., in MRI the exception raised
|
225
|
+
by <code>1/0</code> comes from C).
|
226
|
+
|
227
|
+
== Replacing the Parser
|
228
|
+
|
229
|
+
Despite its name, LiveAST knows nothing about ASTs. It merely reports
|
230
|
+
what it finds in the line-to-AST hash returned by the parser's +parse+
|
231
|
+
method. Replacing the parser class is therefore easy: the only
|
232
|
+
specification is that the +parse+ instance method return such a hash.
|
233
|
+
|
234
|
+
To override the default parser with your own,
|
235
|
+
|
236
|
+
LiveAST.parser = YourParser
|
237
|
+
|
238
|
+
To test it, provide some examples of what the ASTs look like in
|
239
|
+
<code>YourParser::Test</code>. See +live_ast/ruby_parser+ for
|
240
|
+
reference.
|
241
|
+
|
242
|
+
== Noninvasive Mode
|
243
|
+
|
244
|
+
For safety purposes, <code>require 'live_ast'</code> performs the
|
245
|
+
invasive act of redefining +load+ (but not +require+); otherwise bad
|
246
|
+
things can happen to the unwary. The addition of +to_ast+ to a few
|
247
|
+
standard Ruby classes is also a meddlesome move.
|
248
|
+
|
249
|
+
To avoid these modifications,
|
250
|
+
|
251
|
+
require 'live_ast/base'
|
252
|
+
|
253
|
+
will provide the essentials of LiveAST but will not touch core classes
|
254
|
+
or methods.
|
255
|
+
|
256
|
+
To select features individually,
|
257
|
+
|
258
|
+
require 'live_ast/to_ast' # define to_ast for Method, UnboundMethod, Proc
|
259
|
+
require 'live_ast/to_ruby' # define to_ruby for Method, UnboundMethod, Proc
|
260
|
+
require 'live_ast/ast_eval' # define Kernel#ast_eval
|
261
|
+
require 'live_ast/ast_load' # define Kernel#ast_load (mentioned below)
|
262
|
+
require 'live_ast/replace_load' # redefine Kernel#load
|
263
|
+
|
264
|
+
== Noninvasive Interface
|
265
|
+
|
266
|
+
The following alternative interface is available.
|
267
|
+
|
268
|
+
require 'live_ast/base'
|
269
|
+
|
270
|
+
class A
|
271
|
+
def f
|
272
|
+
"A#f"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
p LiveAST.ast(A.instance_method(:f))
|
277
|
+
# => s(:defn, :f, s(:args), s(:str, "A#f"))
|
278
|
+
|
279
|
+
p LiveAST.ast(lambda { })
|
280
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args))
|
281
|
+
|
282
|
+
f = LiveAST.eval("lambda { }", binding)
|
283
|
+
|
284
|
+
p LiveAST.ast(f)
|
285
|
+
# => s(:iter, s(:call, nil, :lambda), s(:args))
|
286
|
+
|
287
|
+
ast_eval # => raises NameError
|
288
|
+
|
289
|
+
== Reloading Files In Noninvasive Mode
|
290
|
+
|
291
|
+
Use +ast_load+ or (equivalently) <code>LiveAST.load</code> when
|
292
|
+
reloading an AST-aware file.
|
293
|
+
|
294
|
+
require 'live_ast/ast_load'
|
295
|
+
require 'live_ast/to_ast'
|
296
|
+
|
297
|
+
require "foo"
|
298
|
+
Foo.instance_method(:bar).to_ast # caches AST
|
299
|
+
|
300
|
+
# ... the bar method is changed in foo.rb ...
|
301
|
+
|
302
|
+
ast_load "foo.rb"
|
303
|
+
p Foo.instance_method(:bar).to_ast # => updated AST
|
304
|
+
|
305
|
+
Note if +load+ is called instead of +ast_load+ then the last line will
|
306
|
+
give the old AST,
|
307
|
+
|
308
|
+
load "foo.rb" # oops! forgot to use ast_load
|
309
|
+
p Foo.instance_method(:bar).to_ast # => stale AST
|
310
|
+
|
311
|
+
Realize that <code>foo.rb</code> may be referenced by an unknown
|
312
|
+
number of methods and blocks. If the original <code>foo.rb</code>
|
313
|
+
source were dumped in favor of the modified <code>foo.rb</code>, then
|
314
|
+
an unknown number of those references would be invalidated (and some
|
315
|
+
may even point to the wrong AST).
|
316
|
+
|
317
|
+
This is the reason for the caching that results in the stale AST
|
318
|
+
above. It should now be clear why the default behavior of
|
319
|
+
<code>require 'live_ast'</code> is to redefine +load+: doing so
|
320
|
+
prevents this problem entirely. On the other hand if it is fully known
|
321
|
+
where files are being reloaded (if at all) then there's no need for
|
322
|
+
paranoia; the noninvasive option may be the most appropriate.
|
323
|
+
|
324
|
+
== The Source/AST Cache
|
325
|
+
|
326
|
+
+ast_eval+ and +load+ cache all incoming code, while
|
327
|
+
<code>require</code>d files are cached on a need-to-know basis. When
|
328
|
+
an AST is requested, the corresponding source file is parsed and
|
329
|
+
discarded, leaving behind method and block ASTs. +to_ast+ removes an
|
330
|
+
AST from the cache and attaches it to the appropriate object (a Proc
|
331
|
+
or Module).
|
332
|
+
|
333
|
+
Ignored, unextracted ASTs will therefore linger in the cache. Since
|
334
|
+
sexps are generally small there is little need for concern unless one
|
335
|
+
is continually evaling/reloading <em>and</em> failing to extract the
|
336
|
+
sexps. Nevertheless it is possible that old ASTs will eventually need
|
337
|
+
to be garbage collected. To flush the cache,
|
338
|
+
|
339
|
+
(1) Check that +to_ast+ has been called on all objects whose ASTs are
|
340
|
+
desired.
|
341
|
+
|
342
|
+
(2) Call <code>LiveAST.flush_cache</code>.
|
343
|
+
|
344
|
+
Calling +to_ast+ prevents the object's AST from being flushed (since
|
345
|
+
it grafts the AST onto the object).
|
346
|
+
|
347
|
+
ASTs of procs and methods whose sources lie in <code>require</code>d
|
348
|
+
files will never be flushed. However a method redefined via +ast_eval+
|
349
|
+
or +load+ is susceptible to +flush_cache+ even when its original
|
350
|
+
definition pointed to a <code>require</code>d file.
|
351
|
+
|
352
|
+
== About +require+
|
353
|
+
|
354
|
+
No measures have been taken to detect manipulations of
|
355
|
+
<code>$LOADED_FEATURES</code> which would cause +require+ to load the
|
356
|
+
same file twice. Though +require+ <em>could</em> be replaced in
|
357
|
+
similar fashion to +load+---heading off problems arising from such
|
358
|
+
"raw" reloads---the overhead would seem inappropriate in relation to
|
359
|
+
the rarity of this case.
|
360
|
+
|
361
|
+
Therefore the working assumption is that +require+ will load a file
|
362
|
+
only once. Furthermore, if a file has not been reloaded then it is
|
363
|
+
assumed that the file is unmodified between the moment it is
|
364
|
+
<code>require</code>d and the moment the first AST is pulled from it.
|
365
|
+
|
366
|
+
== Authors
|
367
|
+
|
368
|
+
* James M. Lawrence < quixoticsycophant@gmail.com >
|
369
|
+
* Matijs van Zuijlen < matijs@matijs.net >
|
370
|
+
|
371
|
+
== License
|
372
|
+
|
373
|
+
Copyright (c) 2011 James M. Lawrence. All rights reserved.
|
374
|
+
Copyright (c) 2014 Matijs van Zuijlen. All rights reserved.
|
375
|
+
|
376
|
+
Permission is hereby granted, free of charge, to any person
|
377
|
+
obtaining a copy of this software and associated documentation files
|
378
|
+
(the "Software"), to deal in the Software without restriction,
|
379
|
+
including without limitation the rights to use, copy, modify, merge,
|
380
|
+
publish, distribute, sublicense, and/or sell copies of the Software,
|
381
|
+
and to permit persons to whom the Software is furnished to do so,
|
382
|
+
subject to the following conditions:
|
383
|
+
|
384
|
+
The above copyright notice and this permission notice shall be
|
385
|
+
included in all copies or substantial portions of the Software.
|
386
|
+
|
387
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
388
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
389
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
390
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
391
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
392
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
393
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
394
|
+
SOFTWARE.
|
395
|
+
|
396
|
+
LiveAST includes the source code of live_ast_ruby_parser, which is licensed as
|
397
|
+
follows:
|
398
|
+
|
399
|
+
Copyright (c) 2011 James M. Lawrence. All rights reserved.
|
400
|
+
|
401
|
+
Permission is hereby granted, free of charge, to any person
|
402
|
+
obtaining a copy of this software and associated documentation files
|
403
|
+
(the "Software"), to deal in the Software without restriction,
|
404
|
+
including without limitation the rights to use, copy, modify, merge,
|
405
|
+
publish, distribute, sublicense, and/or sell copies of the Software,
|
406
|
+
and to permit persons to whom the Software is furnished to do so,
|
407
|
+
subject to the following conditions:
|
408
|
+
|
409
|
+
The above copyright notice and this permission notice shall be
|
410
|
+
included in all copies or substantial portions of the Software.
|
411
|
+
|
412
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
413
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
414
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
415
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
416
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
417
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
418
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
419
|
+
SOFTWARE.
|