linecache 0.43-mswin32 → 0.45-mswin32
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 +329 -31
- data/NEWS +8 -2
- data/README +14 -2
- data/Rakefile +64 -45
- data/ext/trace_nums.c +17 -3
- data/ext/trace_nums.h +1 -1
- data/lib/linecache.rb +237 -69
- data/lib/trace_nums.so +0 -0
- data/lib/tracelines.rb +0 -0
- data/lib/version.rb +3 -0
- data/test/data/block1.rb +0 -0
- data/test/lnum-diag.rb +0 -0
- data/test/parse-show.rb +0 -0
- data/test/test-linecache.rb +2 -2
- data/test/test-lnum.rb +0 -0
- data/test/test-tracelines.rb +0 -0
- metadata +89 -64
- data/VERSION +0 -1
data/ext/trace_nums.c
CHANGED
@@ -34,15 +34,29 @@
|
|
34
34
|
#include <ruby.h>
|
35
35
|
#include <version.h>
|
36
36
|
#include <node.h>
|
37
|
-
#include <env.h>
|
38
37
|
#include <rubysig.h>
|
39
38
|
#include "trace_nums.h"
|
40
39
|
|
41
40
|
VALUE mTraceLineNumbers;
|
42
|
-
|
41
|
+
RUBY_EXTERN NODE *ruby_eval_tree_begin;
|
42
|
+
RUBY_EXTERN int ruby_in_eval;
|
43
43
|
|
44
44
|
#define nd_3rd u3.node
|
45
45
|
|
46
|
+
extern struct FRAME {
|
47
|
+
VALUE self;
|
48
|
+
int argc;
|
49
|
+
ID last_func;
|
50
|
+
ID orig_func;
|
51
|
+
VALUE last_class;
|
52
|
+
struct FRAME *prev;
|
53
|
+
struct FRAME *tmp;
|
54
|
+
struct RNode *node;
|
55
|
+
int iter;
|
56
|
+
int flags;
|
57
|
+
unsigned long uniq;
|
58
|
+
} *ruby_frame;
|
59
|
+
|
46
60
|
struct METHOD {
|
47
61
|
VALUE klass, rklass;
|
48
62
|
VALUE recv;
|
@@ -87,7 +101,7 @@ struct BLOCK {
|
|
87
101
|
#endif
|
88
102
|
|
89
103
|
/* Used just in debugging. */
|
90
|
-
static indent_level = 0;
|
104
|
+
static int indent_level = 0;
|
91
105
|
|
92
106
|
static
|
93
107
|
void ln_eval(VALUE self, NODE * n, VALUE ary) {
|
data/ext/trace_nums.h
CHANGED
data/lib/linecache.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# $Id: linecache.rb
|
2
|
+
# $Id: linecache.rb 264 2011-06-04 13:32:30Z rockyb $
|
3
3
|
#
|
4
|
-
# Copyright (C) 2007, 2008 Rocky Bernstein <rockyb@rubyforge.net>
|
4
|
+
# Copyright (C) 2007, 2008, 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
5
5
|
#
|
6
6
|
# This program is free software; you can redistribute it and/or modify
|
7
7
|
# it under the terms of the GNU General Public License as published by
|
@@ -22,16 +22,20 @@
|
|
22
22
|
# Author:: Rocky Bernstein (mailto:rockyb@rubyforge.net)
|
23
23
|
#
|
24
24
|
# = linecache
|
25
|
-
#
|
26
|
-
# == Version
|
27
|
-
# :include:VERSION
|
25
|
+
# A module to read and cache lines of a Ruby program.
|
28
26
|
|
29
27
|
# == SYNOPSIS
|
30
28
|
#
|
31
29
|
# The LineCache module allows one to get any line from any file,
|
32
|
-
# caching lines of the file on first access to the file.
|
33
|
-
#
|
34
|
-
#
|
30
|
+
# caching lines of the file on first access to the file. Although the
|
31
|
+
# file may be any file, the common use is when the file is a Ruby
|
32
|
+
# script since parsing of the file is done to figure out where the
|
33
|
+
# statement boundaries are.
|
34
|
+
#
|
35
|
+
# The routines here may be is useful when a small random sets of lines
|
36
|
+
# are read from a single file, in particular in a debugger to show
|
37
|
+
# source lines.
|
38
|
+
#
|
35
39
|
#
|
36
40
|
# require 'linecache'
|
37
41
|
# lines = LineCache::getlines('/tmp/myruby.rb')
|
@@ -43,7 +47,6 @@
|
|
43
47
|
# # Note lines[6] == line (if /tmp/myruby.rb has 6 lines)
|
44
48
|
#
|
45
49
|
# LineCache::clear_file_cache
|
46
|
-
# LineCache::clear_file_cache('/tmp/myruby.rb')
|
47
50
|
# LineCache::update_cache # Check for modifications of all cached files.
|
48
51
|
#
|
49
52
|
# Some parts of the interface is derived from the Python module of the
|
@@ -60,11 +63,13 @@ require 'digest/sha1'
|
|
60
63
|
require 'set'
|
61
64
|
|
62
65
|
begin require 'rubygems' rescue LoadError end
|
63
|
-
require '
|
66
|
+
require 'require_relative'
|
67
|
+
require_relative 'tracelines'
|
68
|
+
require_relattve 'version'
|
64
69
|
# require 'ruby-debug' ; Debugger.start
|
65
70
|
|
66
71
|
# = module LineCache
|
67
|
-
#
|
72
|
+
# A module to read and cache lines of a Ruby program.
|
68
73
|
module LineCache
|
69
74
|
LineCacheInfo = Struct.new(:stat, :line_numbers, :lines, :path, :sha1) unless
|
70
75
|
defined?(LineCacheInfo)
|
@@ -72,6 +77,11 @@ module LineCache
|
|
72
77
|
# The file cache. The key is a name as would be given by Ruby for
|
73
78
|
# __FILE__. The value is a LineCacheInfo object.
|
74
79
|
@@file_cache = {}
|
80
|
+
@@script_cache = {}
|
81
|
+
|
82
|
+
|
83
|
+
# Used for CodeRay syntax highlighting
|
84
|
+
@@ruby_highlighter = nil
|
75
85
|
|
76
86
|
# Maps a string filename (a String) to a key in @@file_cache (a
|
77
87
|
# String).
|
@@ -87,28 +97,80 @@ module LineCache
|
|
87
97
|
# ranges. Will probably use this for that, but I'm not sure.
|
88
98
|
@@file2file_remap = {}
|
89
99
|
@@file2file_remap_lines = {}
|
100
|
+
@@script2file = {}
|
101
|
+
|
102
|
+
module_function
|
103
|
+
|
104
|
+
def remove_script_temps
|
105
|
+
@@script2file.values.each do |filename|
|
106
|
+
File.unlink(filename) if File.exist?(filename)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
at_exit { remove_script_temps }
|
110
|
+
|
90
111
|
|
91
112
|
# Clear the file cache entirely.
|
92
|
-
def clear_file_cache()
|
93
|
-
|
94
|
-
|
95
|
-
|
113
|
+
def clear_file_cache(filename=nil)
|
114
|
+
if filename
|
115
|
+
if @@file_cache[filename]
|
116
|
+
@@file_cache.delete(filename)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
@@file_cache = {}
|
120
|
+
@@file2file_remap = {}
|
121
|
+
@@file2file_remap_lines = {}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Remove syntax-formatted lines in the cache. Use this
|
126
|
+
# when you change the CodeRay syntax or Token formatting
|
127
|
+
# and want to redo how files may have previously been
|
128
|
+
# syntax marked.
|
129
|
+
def clear_file_format_cache
|
130
|
+
@@file_cache.each_pair do |fname, cache_info|
|
131
|
+
cache_info.lines.each_pair do |format, lines|
|
132
|
+
next if :plain == format
|
133
|
+
@@file_cache[fname].lines[format] = nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Remove syntax-formatted lines in the cache. Use this
|
139
|
+
# when you change the CodeRay syntax or Token formatting
|
140
|
+
# and want to redo how files may have previously been
|
141
|
+
# syntax marked.
|
142
|
+
def clear_file_format_cache
|
143
|
+
@@file_cache.each_pair do |fname, cache_info|
|
144
|
+
cache_info.lines.each_pair do |format, lines|
|
145
|
+
next if :plain == format
|
146
|
+
@@file_cache[fname].lines[format] = nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Clear the script cache entirely.
|
152
|
+
def clear_script_cache()
|
153
|
+
@@script_cache = {}
|
96
154
|
end
|
97
|
-
module_function :clear_file_cache
|
98
155
|
|
99
156
|
# Return an array of cached file names
|
100
157
|
def cached_files()
|
101
158
|
@@file_cache.keys
|
102
159
|
end
|
103
|
-
module_function :cached_files
|
104
160
|
|
105
161
|
# Discard cache entries that are out of date. If +filename+ is +nil+
|
106
162
|
# all entries in the file cache +@@file_cache+ are checked.
|
107
|
-
# If we don't have stat information about a file which can happen
|
163
|
+
# If we don't have stat information about a file, which can happen
|
108
164
|
# if the file was read from __SCRIPT_LINES but no corresponding file
|
109
165
|
# is found, it will be kept. Return a list of invalidated filenames.
|
110
166
|
# nil is returned if a filename was given but not found cached.
|
111
|
-
def checkcache(filename=nil,
|
167
|
+
def checkcache(filename=nil, opts=false)
|
168
|
+
use_script_lines =
|
169
|
+
if opts.kind_of?(Hash)
|
170
|
+
opts[:use_script_lines]
|
171
|
+
else
|
172
|
+
opts
|
173
|
+
end
|
112
174
|
|
113
175
|
if !filename
|
114
176
|
filenames = @@file_cache.keys()
|
@@ -123,19 +185,60 @@ module LineCache
|
|
123
185
|
next unless @@file_cache.member?(filename)
|
124
186
|
path = @@file_cache[filename].path
|
125
187
|
if File.exist?(path)
|
126
|
-
cache_info = @@file_cache[filename]
|
188
|
+
cache_info = @@file_cache[filename].stat
|
127
189
|
stat = File.stat(path)
|
128
|
-
if
|
129
|
-
|
190
|
+
if cache_info
|
191
|
+
if stat &&
|
192
|
+
(cache_info.size != stat.size or cache_info.mtime != stat.mtime)
|
193
|
+
result << filename
|
194
|
+
update_cache(filename, opts)
|
195
|
+
end
|
196
|
+
else
|
130
197
|
result << filename
|
131
|
-
update_cache(filename,
|
198
|
+
update_cache(filename, opts)
|
132
199
|
end
|
133
200
|
end
|
134
201
|
end
|
135
202
|
return result
|
136
203
|
end
|
137
|
-
|
204
|
+
|
205
|
+
# Cache script if it's not already cached.
|
206
|
+
def cache_script(script, opts={})
|
207
|
+
if !@@script_cache.member?(script)
|
208
|
+
update_script_cache(script, opts)
|
209
|
+
end
|
210
|
+
script
|
211
|
+
end
|
212
|
+
|
213
|
+
# Cache file name or script object if it's not already cached.
|
214
|
+
# Return the expanded filename for it in the cache if a filename,
|
215
|
+
# or the script, or nil if we can't find the file.
|
216
|
+
def cache(file_or_script, reload_on_change=false)
|
217
|
+
if file_or_script.kind_of?(String)
|
218
|
+
cache_file(file_or_script, reload_on_change)
|
219
|
+
else
|
220
|
+
cache_script(file_or_script)
|
221
|
+
end
|
222
|
+
end
|
138
223
|
|
224
|
+
# Cache filename if it's not already cached.
|
225
|
+
# Return the expanded filename for it in the cache
|
226
|
+
# or nil if we can't find the file.
|
227
|
+
def cache_file(filename, reload_on_change=false, opts={})
|
228
|
+
if @@file_cache.member?(filename)
|
229
|
+
checkcache(filename) if reload_on_change
|
230
|
+
else
|
231
|
+
opts[:use_script_lines] = true
|
232
|
+
update_cache(filename, opts)
|
233
|
+
end
|
234
|
+
if @@file_cache.member?(filename)
|
235
|
+
@@file_cache[filename].path
|
236
|
+
else
|
237
|
+
nil
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Older routine - for compability.
|
139
242
|
# Cache filename if it's not already cached.
|
140
243
|
# Return the expanded filename for it in the cache
|
141
244
|
# or nil if we can't find the file.
|
@@ -151,80 +254,116 @@ module LineCache
|
|
151
254
|
nil
|
152
255
|
end
|
153
256
|
end
|
154
|
-
module_function :cache
|
155
257
|
|
156
|
-
# Return true if
|
157
|
-
def cached?(
|
158
|
-
|
258
|
+
# Return true if file_or_script is cached
|
259
|
+
def cached?(file_or_script)
|
260
|
+
if file_or_script.kind_of?(String)
|
261
|
+
@@file_cache.member?(unmap_file(file_or_script))
|
262
|
+
else
|
263
|
+
cached_script?(file_or_script)
|
264
|
+
end
|
159
265
|
end
|
160
|
-
module_function :cached?
|
161
266
|
|
162
267
|
def cached_script?(filename)
|
163
268
|
SCRIPT_LINES__.member?(unmap_file(filename))
|
164
269
|
end
|
165
|
-
module_function :cached_script?
|
166
270
|
|
167
271
|
def empty?(filename)
|
168
272
|
filename=unmap_file(filename)
|
169
|
-
|
273
|
+
!!@@file_cache[filename].lines[:plain]
|
170
274
|
end
|
171
|
-
module_function :empty?
|
172
275
|
|
173
276
|
# Get line +line_number+ from file named +filename+. Return nil if
|
174
277
|
# there was a problem. If a file named filename is not found, the
|
175
|
-
# function will look for it in the $:
|
278
|
+
# function will look for it in the $: array.
|
176
279
|
#
|
177
280
|
# Examples:
|
178
281
|
#
|
179
|
-
# lines = LineCache::getline('/tmp/myfile.rb)
|
282
|
+
# lines = LineCache::getline('/tmp/myfile.rb')
|
180
283
|
# # Same as above
|
181
284
|
# $: << '/tmp'
|
182
|
-
# lines =
|
183
|
-
# lines = LineCache::getlines ('myfile.rb')
|
184
|
-
# end
|
285
|
+
# lines = LineCache.getlines('myfile.rb')
|
185
286
|
#
|
186
|
-
def getline(
|
187
|
-
|
188
|
-
|
189
|
-
|
287
|
+
def getline(file_or_script, line_number, opts=true)
|
288
|
+
reload_on_change =
|
289
|
+
if opts.kind_of?(Hash)
|
290
|
+
opts[:reload_on_change]
|
291
|
+
else
|
292
|
+
opts
|
293
|
+
end
|
294
|
+
lines =
|
295
|
+
if file_or_script.kind_of?(String)
|
296
|
+
filename = unmap_file(file_or_script)
|
297
|
+
filename, line_number = unmap_file_line(filename, line_number)
|
298
|
+
getlines(filename, opts)
|
299
|
+
else
|
300
|
+
script_getlines(file_or_script)
|
301
|
+
end
|
190
302
|
if lines and (1..lines.size) === line_number
|
191
303
|
return lines[line_number-1]
|
192
304
|
else
|
193
305
|
return nil
|
194
306
|
end
|
195
307
|
end
|
196
|
-
module_function :getline
|
197
308
|
|
198
309
|
# Read lines of +filename+ and cache the results. However +filename+ was
|
199
310
|
# previously cached use the results from the cache. Return nil
|
200
311
|
# if we can't get lines
|
201
|
-
def getlines(filename,
|
202
|
-
|
312
|
+
def getlines(filename, opts=false)
|
313
|
+
if opts.kind_of?(Hash)
|
314
|
+
reload_on_change, use_script_lines =
|
315
|
+
[opts[:reload_on_change], opts[:use_script_lines]]
|
316
|
+
else
|
317
|
+
reload_on_change, use_script_lines = [opts, false]
|
318
|
+
opts = {:reload_on_change => reload_on_change}
|
319
|
+
end
|
203
320
|
checkcache(filename) if reload_on_change
|
321
|
+
format = opts[:output] || :plain
|
204
322
|
if @@file_cache.member?(filename)
|
205
|
-
|
323
|
+
lines = @@file_cache[filename].lines
|
324
|
+
if opts[:output] && !lines[format]
|
325
|
+
lines[format] =
|
326
|
+
highlight_string(lines[:plain].join(''), format).split(/\n/)
|
327
|
+
end
|
328
|
+
return lines[format]
|
206
329
|
else
|
207
|
-
|
208
|
-
|
330
|
+
opts[:use_script_lines] = true
|
331
|
+
update_cache(filename, opts)
|
332
|
+
if @@file_cache.member?(filename)
|
333
|
+
return @@file_cache[filename].lines[format]
|
334
|
+
else
|
335
|
+
return nil
|
336
|
+
end
|
209
337
|
end
|
210
338
|
end
|
211
|
-
|
339
|
+
|
340
|
+
def highlight_string(string, output_type)
|
341
|
+
require 'rubygems'
|
342
|
+
begin
|
343
|
+
require 'coderay'
|
344
|
+
require 'term/ansicolor'
|
345
|
+
rescue LoadError
|
346
|
+
return string
|
347
|
+
end
|
348
|
+
@@ruby_highlighter ||= CodeRay::Duo[:ruby, output_type]
|
349
|
+
@@ruby_highlighter.encode(string)
|
350
|
+
end
|
212
351
|
|
213
352
|
# Return full filename path for filename
|
214
353
|
def path(filename)
|
354
|
+
return unless filename.kind_of?(String)
|
215
355
|
filename = unmap_file(filename)
|
216
356
|
return nil unless @@file_cache.member?(filename)
|
217
357
|
@@file_cache[filename].path
|
218
358
|
end
|
219
|
-
module_function :path
|
220
359
|
|
221
360
|
def remap_file(from_file, to_file)
|
222
|
-
@@file2file_remap[
|
361
|
+
@@file2file_remap[from_file] = to_file
|
362
|
+
cache_file(to_file)
|
223
363
|
end
|
224
|
-
module_function :remap_file
|
225
364
|
|
226
365
|
def remap_file_lines(from_file, to_file, range, start)
|
227
|
-
range = (range..range) if range.
|
366
|
+
range = (range..range) if range.kind_of?(Fixnum)
|
228
367
|
to_file = from_file unless to_file
|
229
368
|
if @@file2file_remap_lines[to_file]
|
230
369
|
# FIXME: need to check for overwriting ranges: whether
|
@@ -243,21 +382,25 @@ module LineCache
|
|
243
382
|
return @@file_cache[filename].sha1.hexdigest if
|
244
383
|
@@file_cache[filename].sha1
|
245
384
|
sha1 = Digest::SHA1.new
|
246
|
-
@@file_cache[filename].lines.each do |line|
|
247
|
-
sha1 << line
|
385
|
+
@@file_cache[filename].lines[:plain].each do |line|
|
386
|
+
sha1 << line + "\n"
|
248
387
|
end
|
249
388
|
@@file_cache[filename].sha1 = sha1
|
250
389
|
sha1.hexdigest
|
251
390
|
end
|
252
|
-
module_function :sha1
|
253
391
|
|
254
392
|
# Return the number of lines in filename
|
255
|
-
def size(
|
256
|
-
|
257
|
-
|
258
|
-
|
393
|
+
def size(file_or_script)
|
394
|
+
cache(file_or_script)
|
395
|
+
if file_or_script.kind_of?(String)
|
396
|
+
file_or_script = unmap_file(file_or_script)
|
397
|
+
return nil unless @@file_cache.member?(file_or_script)
|
398
|
+
@@file_cache[file_or_script].lines[:plain].length
|
399
|
+
else
|
400
|
+
return nil unless @@script_cache.member?(file_or_script)
|
401
|
+
@@script_cache[file_or_script].lines[:plain].length
|
402
|
+
end
|
259
403
|
end
|
260
|
-
module_function :size
|
261
404
|
|
262
405
|
# Return File.stat in the cache for filename.
|
263
406
|
def stat(filename)
|
@@ -276,17 +419,16 @@ module LineCache
|
|
276
419
|
e = @@file_cache[filename]
|
277
420
|
unless e.line_numbers
|
278
421
|
e.line_numbers =
|
279
|
-
TraceLineNumbers.lnums_for_str_array(e.lines)
|
422
|
+
TraceLineNumbers.lnums_for_str_array(e.lines[:plain])
|
280
423
|
e.line_numbers = false unless e.line_numbers
|
281
424
|
end
|
282
425
|
e.line_numbers
|
283
426
|
end
|
284
|
-
module_function :trace_line_numbers
|
285
427
|
|
286
428
|
def unmap_file(file)
|
287
429
|
@@file2file_remap[file] ? @@file2file_remap[file] : file
|
288
430
|
end
|
289
|
-
|
431
|
+
alias :map_file :unmap_file
|
290
432
|
|
291
433
|
def unmap_file_line(file, line)
|
292
434
|
if @@file2file_remap_lines[file]
|
@@ -299,13 +441,32 @@ module LineCache
|
|
299
441
|
end
|
300
442
|
return [file, line]
|
301
443
|
end
|
302
|
-
|
444
|
+
|
445
|
+
# Update a cache entry. If something is wrong, return nil. Return
|
446
|
+
# true if the cache was updated and false if not.
|
447
|
+
def update_script_cache(script, opts)
|
448
|
+
# return false unless script_is_eval?(script)
|
449
|
+
# string = opts[:string] || script.eval_source
|
450
|
+
lines = {:plain => string.split(/\n/)}
|
451
|
+
lines[opts[:output]] = highlight_string(string, opts[:output]) if
|
452
|
+
opts[:output]
|
453
|
+
@@script_cache[script] =
|
454
|
+
LineCacheInfo.new(nil, nil, lines, nil, opts[:sha1],
|
455
|
+
opts[:compiled_method])
|
456
|
+
return true
|
457
|
+
end
|
303
458
|
|
304
459
|
# Update a cache entry. If something's
|
305
460
|
# wrong, return nil. Return true if the cache was updated and false
|
306
461
|
# if not. If use_script_lines is true, use that as the source for the
|
307
462
|
# lines of the file
|
308
|
-
def update_cache(filename,
|
463
|
+
def update_cache(filename, opts=false)
|
464
|
+
if opts.kind_of?(Hash)
|
465
|
+
use_script_lines = opts[:use_script_lines]
|
466
|
+
else
|
467
|
+
use_script_lines = opts
|
468
|
+
opts = {:use_script_lines => use_script_lines}
|
469
|
+
end
|
309
470
|
|
310
471
|
return nil unless filename
|
311
472
|
|
@@ -322,7 +483,11 @@ module LineCache
|
|
322
483
|
rescue
|
323
484
|
stat = nil
|
324
485
|
end
|
325
|
-
|
486
|
+
raw_lines = SCRIPT_LINES__[name]
|
487
|
+
lines = {:plain => raw_lines}
|
488
|
+
lines[opts[:output]] =
|
489
|
+
highlight_string(raw_lines.join, opts[:output]).split(/\n/) if
|
490
|
+
opts[:output]
|
326
491
|
@@file_cache[filename] = LineCacheInfo.new(stat, nil, lines, path, nil)
|
327
492
|
@@file2file_remap[path] = filename
|
328
493
|
return true
|
@@ -346,8 +511,13 @@ module LineCache
|
|
346
511
|
end
|
347
512
|
begin
|
348
513
|
fp = File.open(path, 'r')
|
349
|
-
|
514
|
+
raw_string = fp.read
|
515
|
+
fp.rewind
|
516
|
+
lines = {:plain => fp.readlines}
|
350
517
|
fp.close()
|
518
|
+
lines[opts[:output]] =
|
519
|
+
highlight_string(raw_string, opts[:output]).split(/\n/) if
|
520
|
+
opts[:output]
|
351
521
|
rescue
|
352
522
|
## print '*** cannot open', path, ':', msg
|
353
523
|
return nil
|
@@ -358,8 +528,6 @@ module LineCache
|
|
358
528
|
return true
|
359
529
|
end
|
360
530
|
|
361
|
-
module_function :update_cache
|
362
|
-
|
363
531
|
end
|
364
532
|
|
365
533
|
# example usage
|