Version: 0.0.1
Statements
What’s In A Statement?
Statements are the basic building-block of RDF, and are also known as triples, as they have three parts: a subject, a predicate, and an object. Each statement is a way of asserting some fact about the statement’s subject, namely that the object of the statement is related to the subject via the relationship described by the predicate.
You can construct a Statement object via the usual Ruby constructor:
require 'redleaf' Redleaf::Statement.new # =>
This statement has three null nodes — subject, predicate, and object — so it’s not complete. A complete statement is one which has a valid value for all three. You can ask a statement if it’s complete via the #complete?
predicate method:
require 'redleaf' Redleaf::Statement.new.complete? # =>
Incomplete statements are useful for situations in which you want to use one statement to match other complete ones in a Redleaf::Graph; any nodes which are nil
will match any value. This will be covered more in the Working With Graphs section, but for now we’ll just make all our statements complete.
Note that a null node is not the same as a blank node.
Setting the Statement’s Nodes
The subject of a node can be set via the #subject=
method, and likewise the predicate and object can be set via their accessors, too:
require 'redleaf' st = Redleaf::Statement.new st.subject = URI('http://example.com/') st.predicate = URI('http://purl.org/dc/elements/1.1/author') st.object = "Barry J. Example" st.complete? # =>
In this example, the subject and predicate are both explicitly-created URIs, and the object is a string literal. Instances of Core Ruby classes are mapped to their RDF equivalent representation and back for you by Redleaf’s node translation system. See The Node Type System section for more details. For now I’ll just use Strings and you can take me at my word that under the hood, Redleaf is doing the right thing.
Namespaces
When working with a lot of URIs, you can find yourself repeating the same prefix over and over. Rubyists hate to repeat themselves, so Redleaf borrows the idea of namespaces from many of the RDF serialization syntaxes to make the construction of URIs with the same prefix easier to read and type.
A namespace is an object that is constructed with a URI prefix, which can then used to create variants of that URI. It’s used typically to construct URIs for elements of an RDF vocabulary. Let’s use the Dublin Core Metadata Element Set (http://purl.org/dc/elements/1.1/
) and create a few:
require 'redleaf' dc = Redleaf::Namespace.new( 'http://purl.org/dc/elements/1.1/' ) dc[:creator] # => dc[:description] # => dc[:format] # =>
Redleaf::Constants has a CommonNamespaces module which you can include that defines several namespaces that you’ll probably run across if you find yourself working much with RDF.
Creating Complete Statements
So now let’s create a few statements about an online resource, identifying some attributes of it using the Dublin Core namespace (DC
) imported from CommonNamespaces
:
require 'redleaf' require 'redleaf/constants' include Redleaf::Constants::CommonNamespaces paper = URI( 'http://www.ics.uci.edu/~fielding/pubs/dissertation/' ) st = Redleaf::Statement.new( paper, DC[:creator], "Roy T. Fielding" ) # => st2 = Redleaf::Statement.new( paper, DC[:title], "Architectural Styles and the Design " + "of Network-based Software Architectures" ) # =>
Blank Nodes
Blank nodes in Redleaf are created by setting a node to a Symbol, which is translated into a corresponding blank node when it’s handed to the back end, and then back to a Symbol when it comes back into Ruby:
require 'redleaf' dc = Redleaf::Namespace.new( 'http://purl.org/dc/elements/1.1/' ) foaf = Redleaf::Namespace.new( 'http://xmlns.com/foaf/0.1/' ) st = Redleaf::Statement.new st.subject = URI('http://example.com/') st.predicate = dc[:author] st.object = :barry st # => st.object # => st2 = Redleaf::Statement.new st2.subject = :barry st2.predicate = foaf[:givenname] st2.object = "Barry" st2 # => st3 = Redleaf::Statement.new st3.subject = :barry st3.predicate = foaf[:surname] st3.object = "Example" st3 # =>
You can specify an anonymous blank node by using the Symbol :_
:
require 'redleaf' st = Redleaf::Statement.new st.subject = :_ st # =>
Note that each use of :_
generates a new blank node, so if you need two statements linked together, you’ll need to use a named node or do it like so:
require 'redleaf' dc = Redleaf::Namespace.new( 'http://purl.org/dc/elements/1.1/' ) foaf = Redleaf::Namespace.new( 'http://xmlns.com/foaf/0.1/' ) st = Redleaf::Statement.new st.subject = URI('http://example.com/') st.predicate = dc[:author] st.object = :_ st # => st.object # => st2 = Redleaf::Statement.new st2.subject = st.object st2.predicate = foaf[:givenname] st2.object = "Barry" st2 # => st3 = Redleaf::Statement.new st3.subject = st.object st3.predicate = foaf[:surname] st3.object = "Example" st3 # =>
Moving On To Graphs
Eventually, you’ll probably tire of creating nodes, rejoicing in their three-ness, and want to save them off somewhere so you can take them with you on picnics. To do that, you’ll need a Graph.