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 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