methodfinder 1.2.2 → 1.2.3
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 +9 -1
- data/lib/methodfinder.rb +57 -51
- metadata +2 -2
data/README.markdown
CHANGED
@@ -38,6 +38,12 @@ 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
|
+
You can also call `find_method` without passing a block. This is the
|
42
|
+
same as calling `MethodFinder.find`.
|
43
|
+
|
44
|
+
>> 10.find_method(1,3)
|
45
|
+
[:%, :<=>, :>>, :[], :modulo, :remainder]
|
46
|
+
|
41
47
|
#### Blacklists
|
42
48
|
|
43
49
|
You can exclude methods from being tried by editing the hashes
|
@@ -100,7 +106,9 @@ Thanks
|
|
100
106
|
[suggesting](https://github.com/citizen428/methodfinder/issues/closed#issue/3)
|
101
107
|
what eventually became `Object#find_method`.
|
102
108
|
* Jan Lelis for [implementing blacklists](https://github.com/citizen428/methodfinder/issues/closed#issue/4).
|
103
|
-
*
|
109
|
+
* Brian Morearty for pointing out an
|
110
|
+
[incompatibility with Ruby 1.8.7](https://github.com/citizen428/methodfinder/pull/5)
|
111
|
+
and adding the [blockless version](https://github.com/citizen428/methodfinder/pull/6) of `Object#find_method`.
|
104
112
|
|
105
113
|
License
|
106
114
|
---
|
data/lib/methodfinder.rb
CHANGED
@@ -2,75 +2,81 @@ require 'stringio'
|
|
2
2
|
|
3
3
|
class Object
|
4
4
|
def find_method(*args, &block)
|
5
|
-
|
6
|
-
self.
|
5
|
+
if block_given?
|
6
|
+
MethodFinder.methods_to_try(self).select do |met|
|
7
|
+
self.class.class_eval %{ alias :unknown #{met} }
|
7
8
|
obj = self.dup rescue self
|
8
9
|
yield obj rescue nil
|
9
10
|
end
|
11
|
+
else
|
12
|
+
MethodFinder.find(self, *args)
|
10
13
|
end
|
11
14
|
end
|
15
|
+
end
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
class MethodFinder
|
18
|
+
ARGS = {
|
19
|
+
:cycle => [1] # prevent cycling forever
|
20
|
+
}
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
# Blacklisting methods, e.g. { :Object => [:ri, :vim] }
|
23
|
+
INSTANCE_METHOD_BLACKLIST = Hash.new { |h, k| h[k] = [] }
|
24
|
+
CLASS_METHOD_BLACKLIST = Hash.new { |h, k| h[k] = [] }
|
25
|
+
INSTANCE_METHOD_BLACKLIST[:Object] << :find_method # prevent stack overflow
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
class << self
|
28
|
+
def find(obj, res, *args, &block)
|
29
|
+
redirect_streams
|
25
30
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
31
|
+
methods_to_try(obj).select do |met|
|
32
|
+
o = obj.dup rescue obj
|
33
|
+
m = o.method(met)
|
34
|
+
if m.arity <= args.size
|
35
|
+
a = args.empty? && ARGS.has_key?(met) ? ARGS[met] : args
|
36
|
+
m.call(*a, &block) == res rescue nil
|
33
37
|
end
|
34
|
-
ensure
|
35
|
-
restore_streams
|
36
38
|
end
|
39
|
+
ensure
|
40
|
+
restore_streams
|
41
|
+
end
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
# Added by Jan Lelis
|
44
|
+
def methods_to_try(obj)
|
45
|
+
ret = obj.methods.map(&:intern)
|
46
|
+
blacklist = obj.is_a?(Module) ? CLASS_METHOD_BLACKLIST : INSTANCE_METHOD_BLACKLIST
|
47
|
+
klass = obj.is_a?(Module) ? obj : obj.class
|
43
48
|
|
44
|
-
|
49
|
+
klass.ancestors.each { |ancestor| ret -= blacklist[ancestor.to_s.intern] }
|
45
50
|
|
46
|
-
|
47
|
-
|
51
|
+
# 1.8.7 lacks Symbol#<=>
|
52
|
+
ret.sort_by(&:to_s)
|
53
|
+
end
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
def find_classes_and_modules
|
56
|
+
constants = Object.constants.sort.map { |c| Object.const_get(c) }
|
57
|
+
constants.select { |c| c.class == Class || c.class == Module}
|
58
|
+
end
|
53
59
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
def find_in_class_or_module(c, pattern=/./)
|
61
|
+
cs = Object.const_get(c.to_s)
|
62
|
+
class_methods = cs.methods(false) rescue []
|
63
|
+
instance_methods = cs.instance_methods(false)
|
64
|
+
all_methods = class_methods + instance_methods
|
65
|
+
all_methods.grep(/#{pattern}/).sort
|
66
|
+
end
|
61
67
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
+
def redirect_streams
|
69
|
+
@orig_stdout = $stdout
|
70
|
+
@orig_stderr = $stderr
|
71
|
+
$stdout = StringIO.new
|
72
|
+
$stderr = StringIO.new
|
73
|
+
end
|
68
74
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
75
|
+
def restore_streams
|
76
|
+
$stdout = @orig_stdout
|
77
|
+
$stderr = @orig_stderr
|
73
78
|
end
|
74
|
-
private_class_method :redirect_streams, :restore_streams
|
75
79
|
end
|
80
|
+
private_class_method :redirect_streams, :restore_streams
|
81
|
+
end
|
76
82
|
|
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.3
|
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-24 00:00:00 Z
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description:
|