gearbox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.document +5 -0
  2. data/Gemfile +21 -0
  3. data/Gemfile.lock +138 -0
  4. data/Guardfile +9 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.html +89 -0
  7. data/README.md +87 -0
  8. data/Rakefile +46 -0
  9. data/VERSION +1 -0
  10. data/lib/examples/audience.rb +24 -0
  11. data/lib/examples/person.rb +29 -0
  12. data/lib/examples/reference.rb +38 -0
  13. data/lib/examples/theme.rb +8 -0
  14. data/lib/gearbox.rb +40 -0
  15. data/lib/gearbox/attribute_collection.rb +42 -0
  16. data/lib/gearbox/mixins/ad_hoc_properties.rb +41 -0
  17. data/lib/gearbox/mixins/resource.rb +17 -0
  18. data/lib/gearbox/mixins/semantic_accessors.rb +118 -0
  19. data/lib/gearbox/rdf_collection.rb +72 -0
  20. data/lib/gearbox/type.rb +85 -0
  21. data/lib/gearbox/types.rb +28 -0
  22. data/lib/gearbox/types/any.rb +24 -0
  23. data/lib/gearbox/types/boolean.rb +31 -0
  24. data/lib/gearbox/types/date.rb +27 -0
  25. data/lib/gearbox/types/decimal.rb +29 -0
  26. data/lib/gearbox/types/float.rb +28 -0
  27. data/lib/gearbox/types/integer.rb +27 -0
  28. data/lib/gearbox/types/native.rb +22 -0
  29. data/lib/gearbox/types/string.rb +27 -0
  30. data/lib/gearbox/types/uri.rb +25 -0
  31. data/spec/examples/audience_spec.rb +28 -0
  32. data/spec/examples/person_spec.rb +45 -0
  33. data/spec/examples/reference_spec.rb +43 -0
  34. data/spec/examples/theme_spec.rb +137 -0
  35. data/spec/gearbox/attribute_collection_spec.rb +33 -0
  36. data/spec/gearbox/mixins/ad_hoc_properties_spec.rb +52 -0
  37. data/spec/gearbox/mixins/resource_spec.rb +32 -0
  38. data/spec/gearbox/mixins/semantic_accessors_spec.rb +53 -0
  39. data/spec/gearbox/rdf_collection_spec.rb +52 -0
  40. data/spec/gearbox_spec.rb +13 -0
  41. data/spec/spec_helper.rb +16 -0
  42. metadata +235 -0
@@ -0,0 +1,28 @@
1
+ module Gearbox
2
+
3
+ ##
4
+ # Gearbox::Types is a set of default Gearbox::Type classes.
5
+ #
6
+ # @see Gearbox::Type
7
+ # @see Gearbox::Types::Integer
8
+ # @see Gearbox::Types::Boolean
9
+ # @see Gearbox::Types::String
10
+ # @see Gearbox::Types::Float
11
+ # @see Gearbox::Types::Any
12
+ module Types
13
+
14
+ # No autoloading here--the associations to XSD types are made by the
15
+ # classes themselves, so we need to explicitly require them or XSD types
16
+ # will show up as not found.
17
+ require 'gearbox/types/integer'
18
+ require 'gearbox/types/boolean'
19
+ require 'gearbox/types/any'
20
+ require 'gearbox/types/string'
21
+ require 'gearbox/types/float'
22
+ require 'gearbox/types/uri'
23
+ require 'gearbox/types/decimal'
24
+ require 'gearbox/types/native'
25
+
26
+
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # This class does its best to serialize or unserialize RDF values into Ruby
5
+ # values and vice versa using RDF.rb's built-in helpers for `RDF::Literal`s.
6
+ # Its behavior is defined as 'What `RDF::Literal` does' for a given value.
7
+ #
8
+ # @see Gearbox::Type
9
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
10
+ class Any
11
+
12
+ include Gearbox::Type
13
+
14
+ def self.unserialize(value)
15
+ value.respond_to?(:object) ? value.object : value
16
+ end
17
+
18
+ def self.serialize(value)
19
+ raise TypeError, "Gearbox::Types::Any cannot serialize collections" if value.is_a?(Array)
20
+ value.is_a?(RDF::Value) ? value : RDF::Literal.new(value)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # A {Gearbox::Type} for Boolean values. Values will be expressed as booleans
5
+ # and packaged as `XSD.boolean` `RDF::Literal`s.
6
+ #
7
+ # A {Gearbox::Resource} property can reference this type as
8
+ # `Gearbox::Types::Boolean`, `Boolean`, or `XSD.boolean`.
9
+ #
10
+ # @see Gearbox::Type
11
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
12
+ class Boolean
13
+
14
+ include Gearbox::Type
15
+
16
+ def self.unserialize(value)
17
+ value.object == true
18
+ end
19
+
20
+ def self.serialize(value)
21
+ if value
22
+ RDF::Literal.new(true, :datatype => XSD.boolean)
23
+ else
24
+ RDF::Literal.new(false, :datatype => XSD.boolean)
25
+ end
26
+ end
27
+
28
+ register_alias XSD.boolean
29
+
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # A {Gearbox::Type} for Date values. Values will be associated with the
5
+ # `XSD.date` type.
6
+ #
7
+ # A {Gearbox::Resource} property can reference this type as
8
+ # `Gearbox::Types::Date`, `Date`, or `XSD.Date`.
9
+ #
10
+ # @see Gearbox::Type
11
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
12
+ class Date
13
+
14
+ include Gearbox::Type
15
+
16
+ def self.unserialize(value)
17
+ value.object
18
+ end
19
+
20
+ def self.serialize(value)
21
+ RDF::Literal::Date.new(value)
22
+ end
23
+
24
+ register_alias XSD.date
25
+
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ require 'bigdecimal'
2
+
3
+ module Gearbox::Types
4
+
5
+ ##
6
+ # A {Gearbox::Type} for integer values. Values will be associated with the
7
+ # `XSD.integer` type.
8
+ #
9
+ # A {Gearbox::Resource} property can reference this type as
10
+ # `Gearbox::Types::Integer`, `Integer`, or `XSD.integer`.
11
+ #
12
+ # @see Gearbox::Type
13
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
14
+ class Decimal
15
+ include Gearbox::Type
16
+
17
+ def self.unserialize(value)
18
+ object = value.object
19
+ object.is_a?(BigDecimal) ? object : BigDecimal.new(object.to_s)
20
+ end
21
+
22
+ def self.serialize(value)
23
+ RDF::Literal.new(value.is_a?(BigDecimal) ? value.to_s('F') : value.to_s, :datatype => XSD.decimal)
24
+ end
25
+
26
+ register_alias XSD.decimal
27
+
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # A {Gearbox::Type} for Float values. Values will be associated with the
5
+ # `XSD.double` type.
6
+ #
7
+ # A {Gearbox::Resource} property can reference this type as
8
+ # `Gearbox::Types::Float`, `Float`, `XSD.double`, or `XSD.float`.
9
+ #
10
+ # @see Gearbox::Type
11
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
12
+ class Float
13
+
14
+ include Gearbox::Type
15
+
16
+ def self.unserialize(value)
17
+ value.object.to_f
18
+ end
19
+
20
+ def self.serialize(value)
21
+ RDF::Literal.new(value.to_f, :datatype => XSD.double)
22
+ end
23
+
24
+ register_alias XSD.float
25
+ register_alias XSD.double
26
+
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # A {Gearbox::Type} for integer values. Values will be associated with the
5
+ # `XSD.integer` type.
6
+ #
7
+ # A {Gearbox::Resource} property can reference this type as
8
+ # `Gearbox::Types::Integer`, `Integer`, or `XSD.integer`.
9
+ #
10
+ # @see Gearbox::Type
11
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
12
+ class Integer
13
+
14
+ include Gearbox::Type
15
+
16
+ def self.unserialize(value)
17
+ value.object
18
+ end
19
+
20
+ def self.serialize(value)
21
+ RDF::Literal.new(value)
22
+ end
23
+
24
+ register_alias XSD.integer
25
+
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # This type is a native type, doing no conversion to Ruby types. The naked
5
+ # RDF::Value (URI, Node, Literal, etc) will be used, and no deserialization
6
+ # is done.
7
+ #
8
+ # @see Gearbox::Type
9
+ class Native
10
+
11
+ include Gearbox::Type
12
+
13
+ def self.unserialize(value)
14
+ value
15
+ end
16
+
17
+ def self.serialize(value)
18
+ value
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # A {Gearbox::Type} for string values. Values will be associated with the
5
+ # `XSD.string` type with no language code.
6
+ #
7
+ # A {Gearbox::Resource} property can reference this type as
8
+ # `Gearbox::Types::String`, `String`, or `XSD.string`.
9
+ #
10
+ # @see Gearbox::Type
11
+ # @see http://rdf.rubyforge.org/RDF/Literal.html
12
+ class String
13
+
14
+ include Gearbox::Type
15
+
16
+ def self.unserialize(value)
17
+ value.object.to_s
18
+ end
19
+
20
+ def self.serialize(value)
21
+ RDF::Literal.new(value.to_s)
22
+ end
23
+
24
+ register_alias XSD.string
25
+
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ module Gearbox::Types
2
+
3
+ ##
4
+ # This type takes RDF Resource objects and provides RDF::URI objects for the
5
+ # ruby representation.
6
+ #
7
+ # @see Gearbox::Type
8
+ # @see http://rdf.rubyforge.org/RDF/URI.html
9
+ class URI
10
+
11
+ include Gearbox::Type
12
+
13
+ def self.unserialize(value)
14
+ RDF::URI(value)
15
+ end
16
+
17
+ def self.serialize(value)
18
+ RDF::URI(value)
19
+ end
20
+
21
+ register_alias :uri
22
+ register_alias RDF::URI
23
+
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Gearbox
4
+
5
+ describe Audience do
6
+
7
+ subject { Audience.new() }
8
+
9
+ it "has a name getter and setter" do
10
+ subject.name = "Dolphins"
11
+ subject.name.must_equal("Dolphins")
12
+ end
13
+
14
+ it "has a resources association" do
15
+ subject.resource_source = OpenStruct.public_method(:new)
16
+ location = "http://example.com"
17
+ resource = subject.add_resource(:location => location)
18
+ subject.resources[0].must_equal resource
19
+ resource.audience.must_equal subject
20
+ resource.location.must_equal location
21
+ end
22
+
23
+ it "produces popular_themes"
24
+ it "allows hash-based filters for popular_themes"
25
+ it "produces explicit_participants"
26
+ it "allows hash-based filters for explicit_participants"
27
+
28
+ end
@@ -0,0 +1,45 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Gearbox
4
+
5
+ describe Person do
6
+
7
+ subject { Person.new() }
8
+
9
+ it "has a name getter and setter" do
10
+ name = "George Q. Cannon"
11
+ subject.name = name
12
+ subject.name.must_equal(name)
13
+ end
14
+
15
+ it "has a twitter_account getter and setter" do
16
+ twitter_account = "gcannon"
17
+ subject.twitter_account = twitter_account
18
+ subject.twitter_account.must_equal(twitter_account)
19
+ end
20
+
21
+ it "has a email getter and setter" do
22
+ email = "george@example.com"
23
+ subject.email = email
24
+ subject.email.must_equal(email)
25
+ end
26
+
27
+ it "has a website getter and setter" do
28
+ website = "example.com"
29
+ subject.website = website
30
+ subject.website.must_equal(website)
31
+ end
32
+
33
+ it "has a phone getter and setter" do
34
+ phone = "801 555-1122"
35
+ subject.phone = phone
36
+ subject.phone.must_equal(phone)
37
+ end
38
+
39
+ it "has a resource getter and setter" do
40
+ resource = "Some Resource"
41
+ subject.resource = resource
42
+ subject.resource.must_equal(resource)
43
+ end
44
+
45
+ end
@@ -0,0 +1,43 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Gearbox
4
+
5
+ describe Reference do
6
+
7
+ subject { Reference.new() }
8
+
9
+ it "has a location getter and setter" do
10
+ location = "http://example.com"
11
+ subject.location = location
12
+ subject.location.must_equal(location)
13
+ end
14
+
15
+ it "has an audience getter and setter" do
16
+ audience = :audience
17
+ subject.audience = audience
18
+ subject.audience.must_equal audience
19
+ end
20
+
21
+ it "has a people association" do
22
+ subject.person_source = OpenStruct.public_method(:new)
23
+ name = "George Q. Cannon"
24
+ twitter_account = "gcannon"
25
+ person = subject.add_person(:name => name, :twitter_account => twitter_account)
26
+ subject.people[0].must_equal person
27
+ person.reference.must_equal subject
28
+ person.name.must_equal name
29
+ person.twitter_account.must_equal twitter_account
30
+ end
31
+
32
+ it "has a themes association" do
33
+ subject.theme_source = OpenStruct.public_method(:new)
34
+ name = "George Q. Cannon"
35
+ tally = 3
36
+ theme = subject.add_theme(:name => name, :tally => tally)
37
+ subject.themes[0].must_equal theme
38
+ theme.reference.must_equal subject
39
+ theme.name.must_equal name
40
+ theme.tally.must_equal tally
41
+ end
42
+
43
+ end
@@ -0,0 +1,137 @@
1
+ require_relative '../spec_helper'
2
+
3
+ include Gearbox
4
+
5
+ describe Theme do
6
+
7
+ subject { Theme.new() }
8
+
9
+ it "has a name getter and setter" do
10
+ subject.name = "Dolphins"
11
+ subject.name.must_equal("Dolphins")
12
+ end
13
+
14
+ it "has a tally getter and setter" do
15
+ tally = 3
16
+ subject.tally = tally
17
+ subject.tally.must_equal(tally)
18
+ end
19
+
20
+ end
21
+
22
+ =begin
23
+
24
+ Steps That May Work
25
+ ===================
26
+
27
+ * Read up on various implementations for RDF
28
+ * Mix in model -> RDF via serialization class and some builder methods
29
+ * Read up on various implementations for SPARQL
30
+ * Build some query objects to do full CRUD on these models
31
+ * Read the LOD code
32
+ * Implement a mix in for properties and associations
33
+ * Build a half-dozen minimal models with the new infrastructure
34
+
35
+ Implementing RDF
36
+ ================
37
+
38
+ What are the types of serialization?
39
+ ------------------------------------
40
+
41
+ The [JSON](https://github.com/gkellogg/rdf-json) gem is about representing the triples in plain JSON. It is more-nested, with fewer conventions.
42
+
43
+ The [JSON::LD](http://json-ld.org/) is JSON for Linked Data. It has a playground for building this stuff and learning how this can be used. It is meant to be as accessible as anything we'd use in a client application.
44
+
45
+ The [Microdata](https://github.com/gkellogg/rdf-microdata) gem is about annotating HTML with microdata. I think I'd rather go with rdfa and [Schema.org](http://schema.org/) instead.
46
+
47
+ The [RDFa](https://github.com/gkellogg/rdf-rdfa) stuff is more promising. There is a [good article](http://semanticweb.com/introduction-to-rdfa-2_b26361) about using this in practical terms. This is the [Schema.org](http://schema.org/) stuff.
48
+
49
+ [N3](http://www.w3.org/2001/sw/RDFCore/ntriples/) or N-Triples are a long-winded serialization format. The [RDF Library](https://github.com/gkellogg/rdf-n3) is straightforward and useful. As far as I know, N-Quads are triples + context.
50
+
51
+ There are others that I don't understand as well: RDF-XML, Trig, Trix, and Turtle.
52
+
53
+ This comes down to understanding which types of serialization to use. Which to use, any why? I think Turtle is terse and easy to ready for humans. There are abbreviations and aliases and punctuation that make it fairly straight forward.
54
+
55
+ RDF::XML is verbose and possibly a pain in the ass. Why make it so complicated? If we had other XML tools that we wanted to use, that would be fine. As far as I'm concerned, SPARQL is more powerful than any other set of XML tools. So, no thanks.
56
+
57
+ As far as interoperability goes, it shouldn't matter. Any SPARQL end point or semantic application should be able to consume anything. So, the RDF.rb tools can consume a format that I'm not in love with, and I can produce an RDF format that's easiest to use.
58
+
59
+ I've wondered about the JSON formats: RDF::JSON and RDF::JSON-LD. What possible use could I have for dealing with this in JSON? If I hada Node.js application, then I would have to implement some of the same tools I have in RDF.rb in JavaScript. If I was sending this to the client, I have the same problem. There might be a case for accepting a graph and producing some schema.org or microdata HTML. With a rich Internet application, templates, and that sort of thing, I think there's a strong use case for that format.
60
+
61
+ But Why?
62
+ -------
63
+
64
+ I spent some real time working on why I'm so interested in Semantic data right now. I am experiencing pain right now. I am lost. I feel like I spend a lot of time looking at important things. I feel like I forget more than I remember. I don't think I have a problem with my memory, I'm just front-loading exponentially more information than I typically do. And, I want to work on this problem.
65
+
66
+ Why am I experiencing pain? I'm trying to get pregnant with a product right now. I'm working on audiences and their pain and their watering holes and their needs and the ways they make money. I am addressing these things, and finding that I have not found myself equal to the task?
67
+
68
+ Why are you not equal to the task? There are two issues here, the first is that it takes a lot of deep-seated knowledge to move forward. That, and guts. Guts, I'll have to deal with. The knowledge, I need to get my head around things.
69
+
70
+ This is what they call shaving your yak. It's a task before a task. It's a way to get ready to get ready. It can be a colosal waste of time, a panty-waste way to do life. It can also be necessary. It takes wisdom to know the difference. That is why I'm typing right now, to listen to that wisdom.
71
+
72
+ If I had the perfect modeling system, then what?
73
+
74
+ * I could record little things. I'd want to have the tree browser to go over things by hand. I'd want to have topics and tallys and people and sites and themes. I'd want to have full-text indices on various axes where decisions are made. I'd want to have auto correct tools built off of these indices to keep things neat and orderly.
75
+ * I'd want to have some good inference tools around. I'd want to know why all this matters. I'd want to see the forest from the trees.
76
+
77
+ Audience | Event | Question
78
+ name
79
+ Resource
80
+ location
81
+ Person
82
+ name
83
+ tweet account | email | website | phone
84
+ Theme
85
+ name
86
+ tally
87
+
88
+ As a result:
89
+
90
+ * What themes arise amongst this adience|event|question?
91
+ * Who is involved in this theme? What proportion are they of X, where X can be almost anything? How likely is someone likely to believe X, if they are associated with this audience|event|question?
92
+ * How do I find X?
93
+ * Does X know Y?
94
+ * How is X connected to Y?
95
+ * Of the people in X, which ones hold more sway? How do I reach these people?
96
+ * If I were to fill a jury, and wanted them to believe X, what other attributes would I look for to know that they are in audience Y?
97
+ * Can I express all of these questions in terms of graphical models, conditional probabilities, and Bayesian inference?
98
+
99
+ At this point, we are very explicit with our world. At this point, if my reading blog articles and tweet feeds could give me this kind of re-usability, I'd do it all day long.
100
+
101
+ Another scenario, Research
102
+ --------------------------
103
+
104
+ I read an incindiary blog article. I'm pissed. I want to rip this person a new one. Now what?
105
+
106
+ * What opinions do I have that tell me this guy is full of shit?
107
+ * How can I support these opinions?
108
+
109
+ That's really it. I'll need a way to do:
110
+
111
+ Question
112
+ title
113
+ Answer
114
+ body
115
+ Measure (some sort of graphical model, likely stemming from other main-line research)
116
+ amount
117
+ Conclusion
118
+ body
119
+
120
+ The Patthern
121
+ ===========
122
+
123
+ So, I've realized that the pattern is mundane -> summarized -> insightful. I'd like to go around making mundane little messages and tallies as I work through life, and have a way to respond with insightful conversation as a consequence.
124
+
125
+
126
+ How to build triples?
127
+ ---------------------
128
+
129
+ What kinds of repositories are there?
130
+ -------------------------------------
131
+
132
+ Is this information useful if I'll have a SPARQL endpoint any way?
133
+ ------------------------------------------------------------------
134
+
135
+
136
+ =end
137
+