methodfinder 1.2.0 → 1.2.1
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/README.markdown +17 -5
- data/lib/methodfinder.rb +60 -45
- metadata +2 -2
data/README.markdown
CHANGED
@@ -38,6 +38,22 @@ Inside `find_method`'s block, the receiver is available as block
|
|
38
38
|
argument and the special method `unknown` is used as a placeholder for
|
39
39
|
the desired method.
|
40
40
|
|
41
|
+
#### Blacklists
|
42
|
+
|
43
|
+
You can exclude methods from being tried by editing the hashes
|
44
|
+
`MethodFinder::INSTANCE_METHOD_BLACKLIST` and
|
45
|
+
`MethodFinder::CLASS_METHOD_BLACKLIST`. Both use the class/module
|
46
|
+
as key and an array of method names as values (note that class, module
|
47
|
+
and method names have to be symbols).
|
48
|
+
|
49
|
+
For example, to blacklist the instance method `shutdown` of `Object`,
|
50
|
+
you would do
|
51
|
+
|
52
|
+
MethodFinder::INSTANCE_METHOD_BLACKLIST[:Object] << :shutdown
|
53
|
+
|
54
|
+
This might come in handy when using `MethodFinder` together with other
|
55
|
+
gems as such as `interactive_editor`.
|
56
|
+
|
41
57
|
### MethodFinder.find\_classes\_and_modules
|
42
58
|
|
43
59
|
A simple method to return all currently defined modules and classes.
|
@@ -76,11 +92,6 @@ I initially wrote this for the students of the core Ruby course on
|
|
76
92
|
to me (not saying it doesn't work there, just that I test in plain
|
77
93
|
IRB, not with `script/console`).
|
78
94
|
|
79
|
-
Todo
|
80
|
-
---
|
81
|
-
|
82
|
-
* a method black list (maybe)
|
83
|
-
|
84
95
|
Thanks
|
85
96
|
---
|
86
97
|
|
@@ -88,6 +99,7 @@ Thanks
|
|
88
99
|
* Ryan Bates for
|
89
100
|
[suggesting](https://github.com/citizen428/methodfinder/issues/closed#issue/3)
|
90
101
|
what eventually became `Object#find_method`.
|
102
|
+
* Jan Lelis for [implementing blacklists](https://github.com/citizen428/methodfinder/issues/closed#issue/4).
|
91
103
|
|
92
104
|
License
|
93
105
|
---
|
data/lib/methodfinder.rb
CHANGED
@@ -2,60 +2,75 @@ require 'stringio'
|
|
2
2
|
|
3
3
|
class Object
|
4
4
|
def find_method(*args, &block)
|
5
|
-
|
5
|
+
MethodFinder.methods_to_try(self).select do |met|
|
6
6
|
self.class.class_eval %{ alias :unknown #{met} }
|
7
|
-
|
8
|
-
|
7
|
+
obj = self.dup rescue self
|
8
|
+
yield obj rescue nil
|
9
|
+
end
|
9
10
|
end
|
10
11
|
end
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
obj
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
m.
|
12
|
+
|
13
|
+
class MethodFinder
|
14
|
+
ARGS = {
|
15
|
+
:cycle => [1] # prevent cycling forever
|
16
|
+
}
|
17
|
+
|
18
|
+
# Blacklisting methods, e.g. { :Object => [:ri, :vim] }
|
19
|
+
INSTANCE_METHOD_BLACKLIST = Hash.new { |h, k| h[k] = [] }
|
20
|
+
CLASS_METHOD_BLACKLIST = Hash.new { |h, k| h[k] = [] }
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def find(obj, res, *args, &block)
|
24
|
+
redirect_streams
|
25
|
+
|
26
|
+
methods_to_try(obj).select do |met|
|
27
|
+
o = obj.dup rescue obj
|
28
|
+
m = o.method(met)
|
29
|
+
if m.arity <= args.size
|
30
|
+
a = args.empty? && ARGS.has_key?(met) ? ARGS[met] : args
|
31
|
+
m.call(*a, &block) == res rescue nil
|
32
|
+
end
|
28
33
|
end
|
34
|
+
ensure
|
35
|
+
restore_streams
|
29
36
|
end
|
30
|
-
ensure
|
31
|
-
restore_streams
|
32
|
-
end
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
# Added by Jan Lelis
|
39
|
+
def methods_to_try(obj)
|
40
|
+
ret = obj.methods.map(&:intern)
|
41
|
+
blacklist = obj.is_a?(Module) ? CLASS_METHOD_BLACKLIST : INSTANCE_METHOD_BLACKLIST
|
42
|
+
klass = obj.is_a?(Module) ? obj : obj.class
|
38
43
|
|
39
|
-
|
40
|
-
cs = Object.const_get(c.to_s)
|
41
|
-
class_methods = cs.methods(false) rescue []
|
42
|
-
instance_methods = cs.instance_methods(false)
|
43
|
-
all_methods = class_methods + instance_methods
|
44
|
-
all_methods.grep(/#{pattern}/).sort
|
45
|
-
end
|
44
|
+
klass.ancestors.each { |ancestor| ret -= blacklist[ancestor.to_s.intern] }
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
ret.sort
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_classes_and_modules
|
50
|
+
constants = Object.constants.sort.map { |c| Object.const_get(c) }
|
51
|
+
constants.select { |c| c.class == Class || c.class == Module}
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_in_class_or_module(c, pattern=/./)
|
55
|
+
cs = Object.const_get(c.to_s)
|
56
|
+
class_methods = cs.methods(false) rescue []
|
57
|
+
instance_methods = cs.instance_methods(false)
|
58
|
+
all_methods = class_methods + instance_methods
|
59
|
+
all_methods.grep(/#{pattern}/).sort
|
60
|
+
end
|
61
|
+
|
62
|
+
def redirect_streams
|
63
|
+
@orig_stdout = $stdout
|
64
|
+
@orig_stderr = $stderr
|
65
|
+
$stdout = StringIO.new
|
66
|
+
$stderr = StringIO.new
|
67
|
+
end
|
53
68
|
|
54
|
-
|
55
|
-
|
56
|
-
|
69
|
+
def restore_streams
|
70
|
+
$stdout = @orig_stdout
|
71
|
+
$stderr = @orig_stderr
|
72
|
+
end
|
57
73
|
end
|
74
|
+
private_class_method :redirect_streams, :restore_streams
|
58
75
|
end
|
59
|
-
private_class_method :redirect_streams, :restore_streams
|
60
|
-
end
|
61
76
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: methodfinder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.2.
|
5
|
+
version: 1.2.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Michael Kohl
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-16 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|