abstractivator 0.0.23 → 0.0.24
Sign up to get free protection for your applications and to get access to all the features.
- 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
|