pincushion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8d51bc5faf8cad8112f822aa6b99d40473790720
4
+ data.tar.gz: 32bc18b5c133c5862ed9a10b0f9f7e75e33287f3
5
+ SHA512:
6
+ metadata.gz: 32db6265a455714d8e50303ca644129632d7e510d368fc0ab161770bc72f5eed14e47a95f4ae2c5b67f5f95fba51c9a01e5de4cf1b439dd540ba66f16c20df4b
7
+ data.tar.gz: a5abddff7882701b6e681aa29b406dfad111450a4f24eacf2057215746ca766cdd06eb13867d87187c32c8ecfc682bbd4229478720e7c0d93ce3208acf480603
@@ -0,0 +1,170 @@
1
+ require 'set'
2
+ require 'pincushion/plugins'
3
+
4
+ module Pincushion
5
+ module RootModuleMethods
6
+ include Plugins
7
+
8
+ attr_reader :identifiers
9
+
10
+ def all_identifiers_predicates_hashes
11
+ identifiers.map { |k, v| [k, v.all_predicates_hash] }.to_h
12
+ end
13
+
14
+ def all_identifiers_predicates_rows
15
+ identifiers.flat_map do |id, cls|
16
+ cls.new(id).all_predicates_hash.map { |k, v| [id, k, v] }
17
+ end
18
+ end
19
+
20
+ def find(identifier)
21
+ unless identifiers.key?(identifier)
22
+ fail MissingIdentifierError, "Can't find model #{identifier.inspect}"
23
+ end
24
+
25
+ identifiers[identifier].new(identifier)
26
+ end
27
+
28
+ def predicates(*preds)
29
+ return @predicates if preds.empty?
30
+ fail "Predicates can't be changed after initialization" if @predicates
31
+ @predicates = Set.new preds
32
+ is_not(*@predicates)
33
+ @predicates.each do |predicate|
34
+ alias_method(:"is_#{predicate}?", :"#{predicate}?")
35
+ end
36
+ end
37
+ end # module RootModuleMethods
38
+
39
+ module ModuleMethods
40
+ attr_reader :predicate_pincushion_root
41
+
42
+ def all_predicates
43
+ predicate_pincushion_root.predicates
44
+ end
45
+
46
+ def all_predicates_hash
47
+ obj = new ""
48
+ predicate_pincushion_root.predicates.map { |p| [p, obj.is?(p)] }.to_h
49
+ end
50
+
51
+ def identifiers
52
+ predicate_pincushion_root.identifiers
53
+ end
54
+
55
+ def is(*preds)
56
+ preds.each { |pred| define_method(:"#{pred}?") { true } }
57
+ self
58
+ end
59
+
60
+ def is_not(*preds)
61
+ preds.each { |pred| define_method(:"#{pred}?") { false } }
62
+ self
63
+ end
64
+
65
+ def named(*given_identifiers)
66
+ given_identifiers.each do |id|
67
+ if identifiers.key?(id)
68
+ fail DuplicateIdentifierError,
69
+ "Identifier #{id} not unique: #{identifiers[id]} <> #{self}"
70
+ end
71
+
72
+ identifiers[id] = self
73
+ end
74
+
75
+ self
76
+ end
77
+
78
+ def that_are(*preds)
79
+ mod = Module.new
80
+ mod.include self
81
+ mod.is(*preds)
82
+ mod
83
+ end
84
+
85
+ def that_is(*preds)
86
+ klass = Class.new
87
+ klass.include self
88
+ klass.is(*preds)
89
+ klass
90
+ end
91
+
92
+ def included(mod)
93
+ base = self
94
+
95
+ mod.instance_eval do
96
+ @predicate_pincushion_root = base.predicate_pincushion_root
97
+ extend ModuleMethods
98
+ include InstanceMethods
99
+ end
100
+ end
101
+ end # module ModuleMethods
102
+
103
+ module InstanceMethods
104
+ attr_reader :name
105
+
106
+ def initialize(name, *_)
107
+ @name = name
108
+ @additional_predicates = Set.new
109
+ end
110
+
111
+ def all_predicates
112
+ self.class.all_predicates.merge(@additional_predicates)
113
+ end
114
+
115
+ def all_predicates_hash
116
+ all_predicates.map { |p| [p, is?(p)] }.to_h
117
+ end
118
+
119
+ def is(*preds)
120
+ preds.each do |pred|
121
+ define_singleton_method(:"#{pred}?") { true }
122
+ @additional_predicates << pred
123
+ end
124
+
125
+ self
126
+ end
127
+
128
+ def is_not(*preds)
129
+ preds.each do |pred|
130
+ define_singleton_method(:"#{pred}?") { false }
131
+ @additional_predicates << pred
132
+ end
133
+
134
+ self
135
+ end
136
+
137
+ def is?(predicate)
138
+ unless all_predicates.include?(predicate)
139
+ fail MissingPredicateError, "Unknown predicate #{predicate}"
140
+ end
141
+
142
+ send(:"#{predicate}?")
143
+ end
144
+
145
+ def any?(*preds)
146
+ preds.any? { |pred| is?(pred) }
147
+ end
148
+
149
+ def all?(*preds)
150
+ preds.all? { |pred| is?(pred) }
151
+ end
152
+ end # module InstanceMethods
153
+
154
+ def self.included(mod)
155
+ mod.instance_eval do
156
+ @identifiers = {}
157
+ @predicate_pincushion_root = self
158
+
159
+ extend ModuleMethods
160
+ extend RootModuleMethods
161
+ include InstanceMethods
162
+
163
+ is_not(*predicates)
164
+ end
165
+ end
166
+
167
+ DuplicateIdentifierError = Class.new(StandardError)
168
+ MissingIdentifierError = Class.new(StandardError)
169
+ MissingPredicateError = Class.new(StandardError)
170
+ end # module Pincushion
@@ -0,0 +1,21 @@
1
+ module Pincushion
2
+ module Plugins
3
+ def self.camelize(string)
4
+ string.to_s
5
+ .gsub(/\/(.?)/) { "::" + Regexp.last_match(1).upcase }
6
+ .gsub(/(^|_)(.)/) { Regexp.last_match(2).upcase }
7
+ end
8
+
9
+ def plugin(name)
10
+ require "pincushion/plugins/#{name}"
11
+ mod = Plugins.const_get(Plugins.camelize(name))
12
+ extend mod::ModuleMethods if defined?(mod::ModuleMethods)
13
+ extend mod::RootModuleMethods if defined?(mod::RootModuleMethods)
14
+ include mod::InstanceMethods if defined?(mod::InstanceMethods)
15
+ rescue LoadError
16
+ raise LoadError, "Plugin not found: #{name}"
17
+ rescue NameError => e
18
+ raise NameError, "#{e} for plugin: #{name}"
19
+ end
20
+ end # module Plugins
21
+ end # module Pincushion
@@ -0,0 +1,18 @@
1
+ require 'csv'
2
+
3
+ module Pincushion
4
+ module Plugins
5
+ module CsvSerializer
6
+ module RootModuleMethods
7
+ def to_csv(*args, **kwargs)
8
+ rows = all_identifiers_predicates_rows
9
+ kwargs[:headers] ||= [:identifier, :predicate, :value]
10
+
11
+ CSV.generate(*args, **kwargs) do |csv|
12
+ rows.each { |row| csv << row }
13
+ end
14
+ end
15
+ end # module RootModuleMethods
16
+ end # module CsvSerializer
17
+ end # module Plugins
18
+ end # module Pincushion
@@ -0,0 +1,13 @@
1
+ require 'multi_json'
2
+
3
+ module Pincushion
4
+ module Plugins
5
+ module JsonSerializer
6
+ module RootModuleMethods
7
+ def to_json(*args)
8
+ MultiJson.dump(all_identifiers_predicates_hashes, *args)
9
+ end
10
+ end # module RootModuleMethods
11
+ end # module JsonSerializer
12
+ end # module Plugins
13
+ end # module Pincushion
@@ -0,0 +1,5 @@
1
+ module Pincushion
2
+ def self.version
3
+ '0.0.1'
4
+ end
5
+ end # module Pincushion
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pincushion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Miller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description:
28
+ email: bmiller@rackspace.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/pincushion.rb
34
+ - lib/pincushion/plugins.rb
35
+ - lib/pincushion/plugins/csv_serializer.rb
36
+ - lib/pincushion/plugins/json_serializer.rb
37
+ - lib/pincushion/version.rb
38
+ homepage: https://github.com/bjmllr/pincushion
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '2.0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.4.5.1
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Predicate-centric classification toolkit
62
+ test_files: []