suggest_rb 0.3.0 → 0.4.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 +5 -5
- data/README.md +14 -2
- data/lib/suggest.rb +35 -44
- data/lib/suggest/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 34aee46d7b04cc746443cae1623bc6ec09fdfc6c
|
4
|
+
data.tar.gz: 9168c4b4db034e5c46645b7e6a2b8c2aa359addd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04e21185e022abc6113aa0cd130ad78ab1ad770712130b5d728ea4aef6515b734e88e4b68c79fcadec8e87e8245d033cd49835fa00e0b5e64e60698b854f40bb
|
7
|
+
data.tar.gz: 68483b98b9fa8402c0e569f2088deb65fcc5c7407b460f6a143fdbdf80fd09389b9eb216b6823067586c62a68f35581364a439102111f5ef938998f2d0069e2d
|
data/README.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
tells you which method does the thing you want to do
|
4
4
|
|
5
|
+
## Disclaimer
|
6
|
+
|
7
|
+
I don't recommend you ship this in your Gemfile. Keep it in your system's gems (e.g. `gem install`) and load it as needed (e.g. `irb -rsuggest`, `RUBY_OPT=-rsuggest irb`, etc)
|
8
|
+
|
5
9
|
## Installation
|
6
10
|
|
7
11
|
```
|
@@ -19,11 +23,11 @@ require 'suggest'
|
|
19
23
|
|
20
24
|
# You can also specify the args you want that method to take
|
21
25
|
[1,2,3].what_returns? [1], args: [1]
|
22
|
-
=> [:
|
26
|
+
=> [:first, :take, :grep, :min]
|
23
27
|
|
24
28
|
# By default, it only returns methods that don't mutate the object
|
25
29
|
[1,2,3].what_returns? [1], args: [1], allow_mutation: true
|
26
|
-
=> [:
|
30
|
+
=> [:first, :take, :shift, :grep, :min]
|
27
31
|
|
28
32
|
# It works on several core modules including String
|
29
33
|
"HELLO".what_returns? "hello"
|
@@ -55,6 +59,14 @@ require 'suggest'
|
|
55
59
|
# And you can give it a block as well
|
56
60
|
[1,2,3,4].what_mutates? [2,4] { |n| n % 2 == 0 }
|
57
61
|
=> [:select!, :keep_if]
|
62
|
+
|
63
|
+
# It respects the ruby version
|
64
|
+
# ruby 2.4.3
|
65
|
+
{a: 1, b: 2}.what_returns?({})
|
66
|
+
=> []
|
67
|
+
# ruby 2.5.0
|
68
|
+
{a: 1, b: 2}.what_returns?({})
|
69
|
+
=> [:slice]
|
58
70
|
```
|
59
71
|
|
60
72
|
## Note to Self
|
data/lib/suggest.rb
CHANGED
@@ -47,27 +47,22 @@ module Suggest
|
|
47
47
|
[Numeric, :dup],
|
48
48
|
])
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
SUGGEST_MODS.include?(m.owner) &&
|
56
|
-
!INCONSISTENT.include?([m.owner, m.name]) &&
|
57
|
-
!TOO_COMPLICATED.include?([m.owner, m.name])
|
58
|
-
end
|
50
|
+
SELECTOR = ->(m) do
|
51
|
+
SUGGEST_MODS.include?(m.owner) &&
|
52
|
+
!INCONSISTENT.include?([m.owner, m.name]) &&
|
53
|
+
!TOO_COMPLICATED.include?([m.owner, m.name])
|
54
|
+
end
|
59
55
|
|
60
|
-
|
56
|
+
module Mixin
|
57
|
+
def what_returns?(expected, args: [], allow_mutation: false, allow_not_public: false, &block)
|
58
|
+
methods.map(&method(:method)).select(&SELECTOR).select do |m|
|
61
59
|
arity = m.arity
|
62
|
-
next unless arity
|
60
|
+
next unless arity < 0 || arity == args.count
|
63
61
|
|
64
62
|
post = clone
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
else
|
69
|
-
result = post.public_send(m.name, *args) rescue next
|
70
|
-
end
|
63
|
+
|
64
|
+
next if block && UNSAFE_WITH_BLOCK.include?([m.owner, m.name])
|
65
|
+
result = post.__send__(allow_not_public ? :send : :public_send, m.name, *args, &block) rescue next
|
71
66
|
|
72
67
|
next unless allow_mutation || self == post
|
73
68
|
|
@@ -75,31 +70,17 @@ module Suggest
|
|
75
70
|
end.map(&:name)
|
76
71
|
end
|
77
72
|
|
78
|
-
def what_mutates?(expected, opts
|
79
|
-
|
80
|
-
block = Proc.new if block_given?
|
81
|
-
|
82
|
-
applicable_methods = self.methods.map(&method(:method)).select do |m|
|
83
|
-
SUGGEST_MODS.include?(m.owner) &&
|
84
|
-
!INCONSISTENT.include?([m.owner, m.name]) &&
|
85
|
-
!TOO_COMPLICATED.include?([m.owner, m.name])
|
86
|
-
end
|
87
|
-
|
88
|
-
applicable_methods.select do |m|
|
73
|
+
def what_mutates?(expected, args: [], allow_not_public: false, **opts, &block)
|
74
|
+
methods.map(&method(:method)).select(&SELECTOR).select do |m|
|
89
75
|
arity = m.arity
|
90
|
-
next unless arity
|
76
|
+
next unless arity < 0 || arity == args.count
|
91
77
|
|
92
78
|
post = clone
|
93
|
-
if block
|
94
|
-
next if UNSAFE_WITH_BLOCK.include?([m.owner, m.name])
|
95
|
-
result = post.public_send(m.name, *args, &block) rescue next
|
96
|
-
else
|
97
|
-
result = post.public_send(m.name, *args) rescue next
|
98
|
-
end
|
99
79
|
|
100
|
-
if
|
101
|
-
|
102
|
-
|
80
|
+
next if block && UNSAFE_WITH_BLOCK.include?([m.owner, m.name])
|
81
|
+
result = post.__send__(allow_not_public ? :send : :public_send, m.name, *args, &block) rescue next
|
82
|
+
|
83
|
+
next if opts.key?(:returns) && !Suggest.eq?(result, opts[:returns])
|
103
84
|
|
104
85
|
Suggest.eq?(post, expected)
|
105
86
|
end.map(&:name)
|
@@ -110,18 +91,28 @@ module Suggest
|
|
110
91
|
result.is_a?(expected.class) && result == expected
|
111
92
|
end
|
112
93
|
|
94
|
+
def self.suggestable!(mod, **corrections) # unsafe_with_block: [], inconsistent: [], too_complicated: []
|
95
|
+
raise ArgumentError.new("Must support smart comparison (implement «#{mod}#==»)") if mod.instance_method(:==).owner == BasicObject
|
96
|
+
|
97
|
+
SUGGEST_MODS << mod
|
98
|
+
%w[unsafe_with_block inconsistent too_complicated].each do |correction|
|
99
|
+
c = Suggest.const_get(correction.upcase)
|
100
|
+
[mod].product(corrections.fetch(correction, [])).each(&c.method(:<<))
|
101
|
+
end
|
102
|
+
mod.include(Suggest::Mixin) unless mod.ancestors.include?(Suggest::Mixin)
|
103
|
+
end
|
104
|
+
|
113
105
|
def self.suggestable_methods
|
114
|
-
|
115
|
-
SUGGEST_MODS.each do |mod|
|
106
|
+
SUGGEST_MODS.each_with_object([]) do |mod, candidates|
|
116
107
|
owned_methods = mod.instance_methods.select { |m| mod.instance_method(m).owner == mod }
|
117
108
|
next if owned_methods.none?
|
118
109
|
candidates += [mod].product(owned_methods)
|
119
|
-
end
|
120
|
-
|
121
|
-
candidates.reject do |m|
|
110
|
+
end.reject do |m|
|
122
111
|
INCONSISTENT.include?(m) || TOO_COMPLICATED.include?(m)
|
123
112
|
end
|
124
113
|
end
|
125
114
|
end
|
126
115
|
|
127
|
-
|
116
|
+
Suggest::SUGGEST_MODS.each do |mod|
|
117
|
+
mod.include(Suggest::Mixin) unless mod.ancestors.include?(Suggest::Mixin)
|
118
|
+
end
|
data/lib/suggest/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: suggest_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Bodah
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
version: '0'
|
117
117
|
requirements: []
|
118
118
|
rubyforge_project:
|
119
|
-
rubygems_version: 2.
|
119
|
+
rubygems_version: 2.5.2.3
|
120
120
|
signing_key:
|
121
121
|
specification_version: 4
|
122
122
|
summary: tells you which method does the thing you want to do
|