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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5cf5eda70ec67c313b2df05ad3280682c8785f40
4
- data.tar.gz: 9a0d1adaf5762a97cbf854086bb09edff5577169
3
+ metadata.gz: e68abf828440fc78dcde5dcfd7ffbdfb97d12947
4
+ data.tar.gz: 36c75eb045436c4af77795747cec641e8aaf3b3d
5
5
  SHA512:
6
- metadata.gz: b04ee0b54f862440283a251cb940d05c55412d6dd9312286935302c9d26b9aeeeb892e3632cfdb433f3d7b9c65c7c804ca9a78e3080039d3cd19b709d928b4e3
7
- data.tar.gz: 6d3f90b0717a52ef4ef069dea162070b3b0cf4bd7e96d36911475afeec513ef79a3b933152bcc3f488a300cf7caa4b1f46ec3b8858755b7e814bf2a18d20f7f5
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
- proc?(default) ? default.(other_side_value) : default
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.respond_to?(:call) && block
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.respond_to?(:call) or return 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
@@ -6,6 +6,7 @@ require 'set'
6
6
 
7
7
  module Abstractivator
8
8
  module Trees
9
+ # recursively deletes the specified keys
9
10
  def recursive_delete!(hash, keys)
10
11
  x = hash # hash is named 'hash' for documentation purposes but may be anything
11
12
  case x
@@ -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.respond_to?(:call)
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.respond_to?(:call)
116
+ if mask.callable?
113
117
  massaged = :__predicate__
114
118
  begin
115
119
  massaged = mask.to_source
@@ -79,7 +79,7 @@ module Abstractivator
79
79
  end
80
80
 
81
81
  def leaf?(path_tree)
82
- path_tree.respond_to?(:call)
82
+ path_tree.callable?
83
83
  end
84
84
 
85
85
  def deleted?(value)
@@ -1,3 +1,3 @@
1
1
  module Abstractivator
2
- VERSION = '0.0.23'
2
+ VERSION = '0.0.24'
3
3
  end
@@ -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.23
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-15 00:00:00.000000000 Z
11
+ date: 2015-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler