fast_method_source 0.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/CHANGELOG.md +6 -0
- data/LICENCE.txt +19 -0
- data/README.md +261 -0
- data/VERSION +1 -0
- data/ext/fast_method_source/extconf.rb +5 -0
- data/ext/fast_method_source/fast_method_source.c +428 -0
- data/ext/fast_method_source/fast_method_source.h +53 -0
- data/ext/fast_method_source/node.h +519 -0
- data/lib/fast_method_source/core_ext.rb +19 -0
- data/lib/fast_method_source.rb +44 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 05784a528c431c7cf44acd224efb46961b71aab0
|
4
|
+
data.tar.gz: 6c01ae108aa332254d90d3017e9b99765faacde8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d61984aee9f70704d029a85d1e409be18ea9a357bac38033f8f9e27fab347adeef2138a9c60779152356cf61e70cbf0591b80c1eb5362f8c208cc506f25e1999
|
7
|
+
data.tar.gz: 566c2dc70be7cd41e2c99aa063bcead973e1232b3c6729faed5337067f9f37548ad81535494f039b1c2a465c3831e82885331f79a41687cb1256e874c980d554
|
data/CHANGELOG.md
ADDED
data/LICENCE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2015 Kyrylo Silin
|
2
|
+
|
3
|
+
This software is provided 'as-is', without any express or implied
|
4
|
+
warranty. In no event will the authors be held liable for any damages
|
5
|
+
arising from the use of this software.
|
6
|
+
|
7
|
+
Permission is granted to anyone to use this software for any purpose,
|
8
|
+
including commercial applications, and to alter it and redistribute it
|
9
|
+
freely, subject to the following restrictions:
|
10
|
+
|
11
|
+
1. The origin of this software must not be misrepresented; you must not
|
12
|
+
claim that you wrote the original software. If you use this software
|
13
|
+
in a product, an acknowledgment in the product documentation would be
|
14
|
+
appreciated but is not required.
|
15
|
+
|
16
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
17
|
+
misrepresented as being the original software.
|
18
|
+
|
19
|
+
3. This notice may not be removed or altered from any source distribution.
|
data/README.md
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
# Fast Method Source
|
2
|
+
|
3
|
+
* Repository: [https://github.com/kyrylo/fast_method_source/][repo]
|
4
|
+
|
5
|
+
Description
|
6
|
+
-----------
|
7
|
+
|
8
|
+
Fast Method Source is a Ruby library for quering methods, procs and lambdas for
|
9
|
+
their source code and comments.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'fast_method_source'
|
13
|
+
require 'fast_method_source/core_ext'
|
14
|
+
require 'set'
|
15
|
+
|
16
|
+
puts Set.instance_method(:merge).source
|
17
|
+
```
|
18
|
+
|
19
|
+
Output.
|
20
|
+
|
21
|
+
```
|
22
|
+
def merge(enum)
|
23
|
+
if enum.instance_of?(self.class)
|
24
|
+
@hash.update(enum.instance_variable_get(:@hash))
|
25
|
+
else
|
26
|
+
do_with_enum(enum) { |o| add(o) }
|
27
|
+
end
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Installation
|
34
|
+
------------
|
35
|
+
|
36
|
+
All you need is to install the gem.
|
37
|
+
|
38
|
+
gem install fast_method_source
|
39
|
+
|
40
|
+
Synopsis
|
41
|
+
--------
|
42
|
+
|
43
|
+
Fast Method Source provides similar functionality to [method_source][ms], which
|
44
|
+
is being used by the Pry REPL, but with a number of major key differences.
|
45
|
+
|
46
|
+
### Speed improvements
|
47
|
+
|
48
|
+
The main goal of Fast Method Source is to be as fast as possible. In result, the
|
49
|
+
library is much faster than method_source. What's acceptable for Pry, when you
|
50
|
+
query only one method, is not acceptable for other use cases such as querying
|
51
|
+
all the methods defined in your Ruby process. The benchmark showed that Fast
|
52
|
+
Method Source is about 5-10x faster than its competitor.
|
53
|
+
|
54
|
+
I'd be remiss if I didn't mention that there's also room for further speed
|
55
|
+
improvements. The benchmarks below represent comparison of both libraries.
|
56
|
+
|
57
|
+
#### #commend_and_source
|
58
|
+
##### ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
59
|
+
|
60
|
+
This is a utility method and method_source doesn't feature it.
|
61
|
+
|
62
|
+
```
|
63
|
+
Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
|
64
|
+
Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
65
|
+
Counting the number of sample methods...
|
66
|
+
Sample methods: 19439
|
67
|
+
Rehearsal ---------------------------------------------------------------------------
|
68
|
+
FastMethodSource#comment_and_source_for 24.080000 1.900000 25.980000 ( 28.425889)
|
69
|
+
----------------------------------------------------------------- total: 25.980000sec
|
70
|
+
|
71
|
+
user system total real
|
72
|
+
FastMethodSource#comment_and_source_for 23.130000 1.710000 24.840000 ( 27.097578)
|
73
|
+
```
|
74
|
+
|
75
|
+
#### #source
|
76
|
+
##### ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
77
|
+
|
78
|
+
```
|
79
|
+
Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
|
80
|
+
Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
81
|
+
Counting the number of sample methods...
|
82
|
+
Sample methods: 19438
|
83
|
+
Rehearsal -----------------------------------------------------------
|
84
|
+
FastMethodSource#source 18.760000 1.290000 20.050000 ( 21.802014)
|
85
|
+
MethodSource#source 100.100000 0.440000 100.540000 (122.748676)
|
86
|
+
------------------------------------------------ total: 120.590000sec
|
87
|
+
|
88
|
+
user system total real
|
89
|
+
FastMethodSource#source 19.040000 1.170000 20.210000 ( 22.079805)
|
90
|
+
MethodSource#source 92.740000 0.300000 93.040000 (103.833941)
|
91
|
+
```
|
92
|
+
|
93
|
+
#### #comment
|
94
|
+
##### ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
95
|
+
|
96
|
+
```
|
97
|
+
Processor: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
|
98
|
+
Platform: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
|
99
|
+
Counting the number of sample methods...
|
100
|
+
Sample methods: 19595
|
101
|
+
Rehearsal ------------------------------------------------------------
|
102
|
+
FastMethodSource#comment 4.120000 0.520000 4.640000 ( 5.188443)
|
103
|
+
MethodSource#comment 82.480000 0.330000 82.810000 (103.135012)
|
104
|
+
-------------------------------------------------- total: 87.450000sec
|
105
|
+
|
106
|
+
user system total real
|
107
|
+
FastMethodSource#comment 3.580000 0.370000 3.950000 ( 4.398557)
|
108
|
+
MethodSource#comment 73.390000 0.150000 73.540000 ( 81.880220)
|
109
|
+
```
|
110
|
+
|
111
|
+
### Correctness of output
|
112
|
+
|
113
|
+
Fast Method Source is capable of displaying source code even for dynamically
|
114
|
+
defined methods (there are some crazy methods in stdlib).
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
require 'fast_method_source'
|
118
|
+
require 'rss'
|
119
|
+
|
120
|
+
puts RSS::Maker::ChannelBase.instance_method(:dc_description=).source
|
121
|
+
```
|
122
|
+
|
123
|
+
Output.
|
124
|
+
|
125
|
+
```
|
126
|
+
def #{name}=(#{new_value_variable_name})
|
127
|
+
#{local_variable_name} =
|
128
|
+
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
129
|
+
#{additional_setup_code}
|
130
|
+
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
### RAM consumption
|
135
|
+
|
136
|
+
Memory consumption is considerably higher for Fast Method Source (for the
|
137
|
+
benchmarks it used about 800-1500 MB of RES RAM). In fact, since the library is
|
138
|
+
very young, it *may* have memory leaks.
|
139
|
+
|
140
|
+
API
|
141
|
+
---
|
142
|
+
|
143
|
+
### General description
|
144
|
+
|
145
|
+
The library provides two methods `#source` and `#comment`. There are two ways to
|
146
|
+
use Fast Method Source. One way is to monkey-patch relevant core Ruby classes
|
147
|
+
and use the methods directly.
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
require 'fast_method_source'
|
151
|
+
require 'fast_method_source/core_ext'
|
152
|
+
|
153
|
+
# With UnboundMethod
|
154
|
+
Set.instance_method(:merge).source
|
155
|
+
#=> " def merge(enum)\n..."
|
156
|
+
|
157
|
+
# With Method
|
158
|
+
Set.method(:[]).source
|
159
|
+
#=> " def self.[](*ary)\n..."
|
160
|
+
|
161
|
+
# With Proc (or lambda)
|
162
|
+
myproc = proc { |arg|
|
163
|
+
arg + 1
|
164
|
+
}
|
165
|
+
myproc.source
|
166
|
+
#=> "myproc = proc { |arg|\n..."
|
167
|
+
```
|
168
|
+
|
169
|
+
The other way is by using these methods defined on the library's class directly.
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
require 'fast_method_source'
|
173
|
+
|
174
|
+
# With UnboundMethod
|
175
|
+
FastMethodSource.source_for(Set.instance_method(:merge))
|
176
|
+
#=> " def merge(enum)\n..."
|
177
|
+
|
178
|
+
# With Method
|
179
|
+
FastMethodSource.source_for(Set.method(:[]))
|
180
|
+
#=> " def self.[](*ary)\n..."
|
181
|
+
|
182
|
+
# With Proc (or lambda)
|
183
|
+
myproc = proc { |arg|
|
184
|
+
arg + 1
|
185
|
+
}
|
186
|
+
FastMethodSource.source_for(myproc)
|
187
|
+
#=> "myproc = proc { |arg|\n..."
|
188
|
+
```
|
189
|
+
|
190
|
+
### Methods
|
191
|
+
|
192
|
+
#### FastMethodSource#source_for(method)
|
193
|
+
|
194
|
+
Returns the source code of the given _method_ as a String.
|
195
|
+
Raises `FastMethodSource::SourceNotFoundError` if:
|
196
|
+
|
197
|
+
* _method_ is defined outside of a file (for example, in a REPL)
|
198
|
+
* _method_ doesn't have a source location (typically C methods)
|
199
|
+
|
200
|
+
Raises `IOError` if:
|
201
|
+
|
202
|
+
* the file location of _method_ is inaccessible
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
FastMethodSource.source_for(Set.instance_method(:merge))
|
206
|
+
#=> " def merge(enum)\n..."
|
207
|
+
FastMethodSource.source_for(Array.instance_method(:pop))
|
208
|
+
#=> FastMethodSource::SourceNotFoundError
|
209
|
+
```
|
210
|
+
|
211
|
+
#### FastMethodSource#comment_for(method)
|
212
|
+
|
213
|
+
Returns the comment of the given _method_ as a String. The rest is identical to
|
214
|
+
`FastMethodSource#source_for(method)`.
|
215
|
+
|
216
|
+
#### FastMethodSource#comment_and_source_for(method)
|
217
|
+
|
218
|
+
Returns the comment and the source code of the given _method_ as a String (the
|
219
|
+
order is the same as the method's name). The rest is identical to
|
220
|
+
`FastMethodSource#source_for(method)`.
|
221
|
+
|
222
|
+
Limitations
|
223
|
+
-----------
|
224
|
+
|
225
|
+
### Rubies
|
226
|
+
|
227
|
+
* CRuby 2.2.2
|
228
|
+
* CRuby 2.3.0dev and higher
|
229
|
+
|
230
|
+
Rubies below 2.2.2 were not tested, so in theory if it quacks like Ruby 2, it
|
231
|
+
may work.
|
232
|
+
|
233
|
+
### OS'es
|
234
|
+
|
235
|
+
* GNU/Linux
|
236
|
+
* Mac OS (hopefully)
|
237
|
+
|
238
|
+
Roadmap
|
239
|
+
-------
|
240
|
+
|
241
|
+
### Further speed improvements
|
242
|
+
|
243
|
+
Although Fast Method Source is faster than any of its competitors, it's still
|
244
|
+
very slow. On average, a mature Rails 4 application has at least 45K methods. In
|
245
|
+
order to query all those methods for their source code, you would need to wait
|
246
|
+
for a while and perhaps to drink a cup of tea.
|
247
|
+
|
248
|
+
The goal of the project is to be able to query 50K methods in less than 15
|
249
|
+
seconds. Whether it's possible or not is to be determined.
|
250
|
+
|
251
|
+
### Decrease memory consumption
|
252
|
+
|
253
|
+
I'm not happy about the current rates. To be investigated.
|
254
|
+
|
255
|
+
Licence
|
256
|
+
-------
|
257
|
+
|
258
|
+
The project uses Zlib License. See the LICENCE.txt file for more information.
|
259
|
+
|
260
|
+
[repo]: https://github.com/kyrylo/fast_method_source/ "Home page"
|
261
|
+
[ms]: https://github.com/banister/method_source
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|