abstractivator 0.0.23 → 0.0.24
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 +4 -4
- data/lib/abstractivator/array_ext.rb +7 -0
- data/lib/abstractivator/enumerable_ext.rb +2 -2
- data/lib/abstractivator/proc_ext.rb +25 -1
- data/lib/abstractivator/trees/recursive_delete.rb +1 -0
- data/lib/abstractivator/trees/tree_compare.rb +6 -2
- data/lib/abstractivator/trees/tree_map.rb +1 -1
- data/lib/abstractivator/version.rb +1 -1
- data/spec/lib/abstractivator/proc_ext_spec.rb +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e68abf828440fc78dcde5dcfd7ffbdfb97d12947
|
4
|
+
data.tar.gz: 36c75eb045436c4af77795747cec641e8aaf3b3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6253948262fb4db237c054869d8cf198a39d3abc0d9ba8115ce9ef56c6c06b7322d416604782d8ddd7398b07394b7fd16fb377b8bc477903a2c9770c2fe13be5
|
7
|
+
data.tar.gz: f367bfbca002208c663a7d96decec94a3f010f56b731c760f9ac6f2b79ed45c13c1caaa00ccc6564884637783476df96c44ba1015dcd685952b661e95f4672af
|
@@ -1,14 +1,21 @@
|
|
1
1
|
class Array
|
2
|
+
# returns the first element of a 2-element array.
|
3
|
+
# useful when dealing with hashes in array form.
|
4
|
+
# e.g., pairs.map(&:key)
|
2
5
|
def key
|
3
6
|
size == 2 or raise 'array must contain exactly two elements'
|
4
7
|
first
|
5
8
|
end
|
6
9
|
|
10
|
+
# returns the second element of a 2-element array.
|
11
|
+
# useful when dealing with hashes in array form.
|
12
|
+
# e.g., pairs.map(&:value)
|
7
13
|
def value
|
8
14
|
size == 2 or raise 'array must contain exactly two elements'
|
9
15
|
last
|
10
16
|
end
|
11
17
|
|
18
|
+
# A backport of Array@to_h from Ruby 2.1
|
12
19
|
unless instance_methods.include?(:to_h)
|
13
20
|
define_method(:to_h) do
|
14
21
|
Hash[self]
|
@@ -41,7 +41,7 @@ module Enumerable
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.get_default(default, other_side_value)
|
44
|
-
|
44
|
+
default.callable? ? default.call(other_side_value) : default
|
45
45
|
end
|
46
46
|
|
47
47
|
def self.proc?(x)
|
@@ -73,7 +73,7 @@ module Enumerable
|
|
73
73
|
define_method :detect do |*args, &block|
|
74
74
|
detect = orig_detect.bind(self)
|
75
75
|
|
76
|
-
if args.size == 1 && !args.first.
|
76
|
+
if args.size == 1 && !args.first.callable? && block
|
77
77
|
value = args.first
|
78
78
|
detect.call {|x| block.call(x) == value}
|
79
79
|
elsif args.size == 2 && !block
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'abstractivator/enumerable_ext'
|
2
2
|
|
3
3
|
module MethodAndProcExtensions
|
4
|
+
# returns a version of the procedure that accepts any number of arguments
|
4
5
|
def loosen_args
|
5
6
|
proc do |*args, &block|
|
6
7
|
Proc.loose_call(self, args, &block)
|
@@ -11,27 +12,37 @@ end
|
|
11
12
|
class Proc
|
12
13
|
include MethodAndProcExtensions
|
13
14
|
|
15
|
+
# composes this procedure with another procedure
|
16
|
+
# f.compose(g) ==> proc { |x| f.call(g.call(x)) }
|
14
17
|
def compose(other)
|
15
18
|
proc{|x| self.call(other.call(x))}
|
16
19
|
end
|
17
20
|
|
21
|
+
# composes procedures.
|
22
|
+
# compose(f, g, h) returns the procedure
|
23
|
+
# proc { |x| f.call(g.call(h.call(x))) }
|
18
24
|
def self.compose(*procs)
|
19
25
|
procs.map(&:to_proc).inject_right(identity) { |inner, p| p.compose(inner) }
|
20
26
|
end
|
21
27
|
|
28
|
+
# returns the identity function
|
22
29
|
def self.identity
|
23
30
|
proc {|x| x}
|
24
31
|
end
|
25
32
|
|
33
|
+
# returns a version of the procedure with the argument list reversed
|
26
34
|
def reverse_args
|
27
35
|
proc do |*args, &block|
|
28
36
|
self.call(*args.reverse, &block)
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
40
|
+
# tries to coerce x into a procedure, then calls it with
|
41
|
+
# the given argument list.
|
42
|
+
# If x cannot be coerced into a procedure, returns x.
|
32
43
|
def self.loose_call(x, args, &block)
|
33
44
|
x = x.to_proc if x.respond_to?(:to_proc)
|
34
|
-
x.
|
45
|
+
x.callable? or return x
|
35
46
|
args = args.take(x.arity).pad_right(x.arity) if x.arity >= 0
|
36
47
|
x.call(*args, &block)
|
37
48
|
end
|
@@ -42,6 +53,9 @@ class Method
|
|
42
53
|
end
|
43
54
|
|
44
55
|
class UnboundMethod
|
56
|
+
# returns a version of the procedure that takes the receiver
|
57
|
+
# (that would otherwise need to be bound with .bind()) as
|
58
|
+
# the first argument
|
45
59
|
def explicit_receiver
|
46
60
|
proc do |receiver, *args, &block|
|
47
61
|
self.bind(receiver).call(*args, &block)
|
@@ -50,8 +64,18 @@ class UnboundMethod
|
|
50
64
|
end
|
51
65
|
|
52
66
|
class Array
|
67
|
+
# A syntactic hack to get hash values.
|
68
|
+
# xs.map(&:name) works when xs is an array of objects, each with a #name method. (built into ruby)
|
69
|
+
# xs.map(&[:name]) works when xs is an array of hashes, each with a :name key.
|
70
|
+
# xs.map(&['name']) works when xs is an array of hashes, each with a 'name' key.
|
53
71
|
def to_proc
|
54
72
|
raise 'size must be exactly one' unless size == 1
|
55
73
|
proc{|x| x[first]}
|
56
74
|
end
|
57
75
|
end
|
76
|
+
|
77
|
+
class Object
|
78
|
+
def callable?
|
79
|
+
respond_to?(:call)
|
80
|
+
end
|
81
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/object/deep_dup'
|
2
2
|
require 'abstractivator/trees/block_collector'
|
3
|
+
require 'abstractivator/proc_ext'
|
3
4
|
require 'sourcify'
|
4
5
|
require 'delegate'
|
5
6
|
require 'set'
|
@@ -12,6 +13,9 @@ module Abstractivator
|
|
12
13
|
SetMask.new(items, get_key)
|
13
14
|
end
|
14
15
|
|
16
|
+
# Compares a tree to a mask.
|
17
|
+
# Returns a diff of where the tree differs from the mask.
|
18
|
+
# Ignores parts of the tree not specified in the mask.
|
15
19
|
def tree_compare(tree, mask, path=[], index=nil)
|
16
20
|
if mask == [:*] && tree.is_a?(Enumerable)
|
17
21
|
[]
|
@@ -19,7 +23,7 @@ module Abstractivator
|
|
19
23
|
[]
|
20
24
|
elsif mask == :- && tree != :__missing__
|
21
25
|
[diff(path, tree, :__absent__)]
|
22
|
-
elsif mask.
|
26
|
+
elsif mask.callable?
|
23
27
|
are_equivalent = mask.call(tree)
|
24
28
|
are_equivalent ? [] : [diff(path, tree, mask)]
|
25
29
|
else
|
@@ -109,7 +113,7 @@ module Abstractivator
|
|
109
113
|
end
|
110
114
|
|
111
115
|
def massage_mask_for_diff(mask)
|
112
|
-
if mask.
|
116
|
+
if mask.callable?
|
113
117
|
massaged = :__predicate__
|
114
118
|
begin
|
115
119
|
massaged = mask.to_source
|
@@ -84,3 +84,11 @@ describe 'Array#to_proc' do
|
|
84
84
|
expect{[:a, :b].to_proc}.to raise_error 'size must be exactly one'
|
85
85
|
end
|
86
86
|
end
|
87
|
+
|
88
|
+
describe 'Object#callable?' do
|
89
|
+
it 'determines whether or not the object has a public :call method' do
|
90
|
+
expect(1.callable?).to be_falsey
|
91
|
+
expect(proc{}).to be_truthy
|
92
|
+
expect(double(call: 1)).to be_truthy
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstractivator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Winton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|