rdf 1.0.10.2 → 1.1.0.p0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CREDITS +0 -2
- data/README +67 -20
- data/VERSION +1 -1
- data/etc/doap.nt +75 -75
- data/lib/rdf.rb +15 -64
- data/lib/rdf/format.rb +11 -20
- data/lib/rdf/mixin/countable.rb +4 -11
- data/lib/rdf/mixin/enumerable.rb +4 -8
- data/lib/rdf/mixin/mutable.rb +1 -4
- data/lib/rdf/mixin/queryable.rb +13 -60
- data/lib/rdf/model/graph.rb +46 -22
- data/lib/rdf/model/list.rb +27 -102
- data/lib/rdf/model/literal.rb +48 -100
- data/lib/rdf/model/literal/date.rb +1 -1
- data/lib/rdf/model/literal/datetime.rb +1 -35
- data/lib/rdf/model/literal/decimal.rb +0 -30
- data/lib/rdf/model/literal/double.rb +6 -14
- data/lib/rdf/model/literal/integer.rb +3 -11
- data/lib/rdf/model/literal/numeric.rb +0 -40
- data/lib/rdf/model/literal/time.rb +4 -3
- data/lib/rdf/model/node.rb +1 -3
- data/lib/rdf/model/statement.rb +7 -47
- data/lib/rdf/model/term.rb +9 -0
- data/lib/rdf/model/uri.rb +28 -68
- data/lib/rdf/model/value.rb +1 -31
- data/lib/rdf/nquads.rb +4 -7
- data/lib/rdf/ntriples.rb +2 -2
- data/lib/rdf/ntriples/format.rb +1 -2
- data/lib/rdf/ntriples/reader.rb +15 -68
- data/lib/rdf/ntriples/writer.rb +13 -53
- data/lib/rdf/query.rb +1 -8
- data/lib/rdf/query/pattern.rb +25 -7
- data/lib/rdf/query/solution.rb +3 -19
- data/lib/rdf/query/solutions.rb +4 -22
- data/lib/rdf/query/variable.rb +1 -3
- data/lib/rdf/reader.rb +8 -22
- data/lib/rdf/repository.rb +23 -5
- data/lib/rdf/transaction.rb +19 -8
- data/lib/rdf/util/aliasing.rb +3 -13
- data/lib/rdf/util/cache.rb +2 -3
- data/lib/rdf/util/file.rb +5 -15
- data/lib/rdf/vocab.rb +19 -20
- data/lib/rdf/writer.rb +5 -44
- metadata +12 -27
- data/lib/rdf/vocab/schema.rb +0 -652
data/lib/rdf/format.rb
CHANGED
@@ -13,18 +13,18 @@ module RDF
|
|
13
13
|
# RDF::Format.for("etc/doap.nt")
|
14
14
|
# RDF::Format.for(:file_name => "etc/doap.nt")
|
15
15
|
# RDF::Format.for(:file_extension => "nt")
|
16
|
-
# RDF::Format.for(:content_type => "
|
16
|
+
# RDF::Format.for(:content_type => "text/plain")
|
17
17
|
#
|
18
18
|
# @example Obtaining serialization format MIME types
|
19
|
-
# RDF::Format.content_types #=> {"
|
19
|
+
# RDF::Format.content_types #=> {"text/plain" => [RDF::NTriples::Format]}
|
20
20
|
#
|
21
21
|
# @example Obtaining serialization format file extension mappings
|
22
22
|
# RDF::Format.file_extensions #=> {:nt => [RDF::NTriples::Format]}
|
23
23
|
#
|
24
24
|
# @example Defining a new RDF serialization format class
|
25
25
|
# class RDF::NTriples::Format < RDF::Format
|
26
|
-
# content_type '
|
27
|
-
# content_encoding '
|
26
|
+
# content_type 'text/plain', :extension => :nt
|
27
|
+
# content_encoding 'ascii'
|
28
28
|
#
|
29
29
|
# reader RDF::NTriples::Reader
|
30
30
|
# writer RDF::NTriples::Writer
|
@@ -142,14 +142,12 @@ module RDF
|
|
142
142
|
|
143
143
|
# If we have a sample, use that for format detection
|
144
144
|
if sample = (options[:sample] if options.is_a?(Hash)) || (yield if block_given?)
|
145
|
-
sample = sample.dup.to_s
|
146
|
-
sample.force_encoding(Encoding::US_ASCII) if sample.respond_to?(:force_encoding)
|
147
145
|
# Given a sample, perform format detection across the appropriate formats, choosing
|
148
146
|
# the first that matches
|
149
147
|
format ||= @@subclasses
|
150
148
|
|
151
149
|
# Return first format that has a positive detection
|
152
|
-
format.detect {|f| f.detect(sample)} || format.first
|
150
|
+
format.detect {|f| f.detect(sample.to_s)} || format.first
|
153
151
|
elsif format.is_a?(Array)
|
154
152
|
# Otherwise, just return the first matching format
|
155
153
|
format.first
|
@@ -251,7 +249,7 @@ module RDF
|
|
251
249
|
#
|
252
250
|
# @example
|
253
251
|
#
|
254
|
-
# RDF::NTriples::Format.name => "
|
252
|
+
# RDF::NTriples::Format.name => "NTriples"
|
255
253
|
#
|
256
254
|
# @return [Symbol]
|
257
255
|
def self.name
|
@@ -357,7 +355,7 @@ module RDF
|
|
357
355
|
# match cannot be unambigiously found otherwise.
|
358
356
|
#
|
359
357
|
# @example
|
360
|
-
# RDF::NTriples::Format.detect("<a> <b> <c> .")
|
358
|
+
# RDF::NTriples::Format.detect("<a> <b> <c> .") => true
|
361
359
|
#
|
362
360
|
# @param [String] sample Beginning several bytes (~ 1K) of input.
|
363
361
|
# @return [Boolean]
|
@@ -403,21 +401,14 @@ module RDF
|
|
403
401
|
|ct, cl| (cl.include?(self) && ct != @@content_type[self]) ? ct : nil }].flatten.compact
|
404
402
|
else
|
405
403
|
@@content_type[self] = type
|
406
|
-
@@content_types[type] ||= []
|
407
|
-
@@content_types[type] << self unless @@content_types[type].include?(self)
|
404
|
+
(@@content_types[type] ||= []) << self
|
408
405
|
|
409
406
|
if extensions = (options[:extension] || options[:extensions])
|
410
|
-
extensions =
|
411
|
-
extensions.each
|
412
|
-
@@file_extensions[ext] ||= []
|
413
|
-
@@file_extensions[ext] << self unless @@file_extensions[ext].include?(self)
|
414
|
-
end
|
407
|
+
extensions = [extensions].flatten.map(&:to_sym)
|
408
|
+
extensions.each { |ext| (@@file_extensions[ext] ||= []) << self }
|
415
409
|
end
|
416
410
|
if aliases = (options[:alias] || options[:aliases])
|
417
|
-
aliases =
|
418
|
-
@@content_types[a] ||= []
|
419
|
-
@@content_types[a] << self unless @@content_types[a].include?(self)
|
420
|
-
end
|
411
|
+
aliases = [aliases].flatten.each { |a| (@@content_types[a] ||= []) << self }
|
421
412
|
end
|
422
413
|
end
|
423
414
|
end
|
data/lib/rdf/mixin/countable.rb
CHANGED
@@ -9,8 +9,9 @@ module RDF
|
|
9
9
|
#
|
10
10
|
# @return [Boolean]
|
11
11
|
def empty?
|
12
|
-
|
13
|
-
|
12
|
+
empty = true
|
13
|
+
each { empty = false; break }
|
14
|
+
empty
|
14
15
|
end
|
15
16
|
|
16
17
|
##
|
@@ -31,16 +32,8 @@ module RDF
|
|
31
32
|
# @see Object#enum_for
|
32
33
|
def enum_for(method = :each, *args)
|
33
34
|
# Ensure that enumerators support the `#empty?` and `#count` methods:
|
34
|
-
|
35
|
-
Countable::Enumerator.new do |yielder|
|
36
|
-
this.send(method, *args) {|y| yielder << y}
|
37
|
-
end
|
35
|
+
super.extend(RDF::Countable)
|
38
36
|
end
|
39
37
|
alias_method :to_enum, :enum_for
|
40
|
-
|
41
|
-
# Extends Enumerator with {Countable}, which is used by {Countable#enum_for}
|
42
|
-
class Enumerator < ::Enumerator
|
43
|
-
include Countable
|
44
|
-
end
|
45
38
|
end # Countable
|
46
39
|
end # RDF
|
data/lib/rdf/mixin/enumerable.rb
CHANGED
@@ -17,10 +17,10 @@ module RDF
|
|
17
17
|
# enumerable.has_quad?([subject, predicate, object, context])
|
18
18
|
#
|
19
19
|
# @example Checking whether a specific value exists
|
20
|
-
# enumerable.has_subject?(RDF::URI("http://
|
20
|
+
# enumerable.has_subject?(RDF::URI("http://rdf.rubyforge.org/"))
|
21
21
|
# enumerable.has_predicate?(RDF::DC.creator)
|
22
|
-
# enumerable.has_object?(RDF::Literal("
|
23
|
-
# enumerable.has_context?(RDF::URI("http://
|
22
|
+
# enumerable.has_object?(RDF::Literal("Hello!", :language => :en))
|
23
|
+
# enumerable.has_context?(RDF::URI("http://rubyforge.org/"))
|
24
24
|
#
|
25
25
|
# @example Enumerating all statements
|
26
26
|
# enumerable.each_statement do |statement|
|
@@ -162,11 +162,7 @@ module RDF
|
|
162
162
|
# @return [Enumerator]
|
163
163
|
# @see #each_statement
|
164
164
|
def enum_statement
|
165
|
-
|
166
|
-
this = self
|
167
|
-
Queryable::Enumerator.new do |yielder|
|
168
|
-
this.send(:each_statement) {|y| yielder << y}
|
169
|
-
end
|
165
|
+
enum_for(:each_statement).extend(RDF::Queryable, RDF::Enumerable)
|
170
166
|
end
|
171
167
|
alias_method :enum_statements, :enum_statement
|
172
168
|
|
data/lib/rdf/mixin/mutable.rb
CHANGED
@@ -106,9 +106,6 @@ module RDF
|
|
106
106
|
|
107
107
|
##
|
108
108
|
# Deletes RDF statements from `self`.
|
109
|
-
# If any statement contains a {Query::Variable}, it is
|
110
|
-
# considered to be a pattern, and used to query
|
111
|
-
# self to find matching statements to delete.
|
112
109
|
#
|
113
110
|
# @param [Enumerable<RDF::Statement>] statements
|
114
111
|
# @raise [TypeError] if `self` is immutable
|
@@ -121,7 +118,7 @@ module RDF
|
|
121
118
|
when value.respond_to?(:each_statement)
|
122
119
|
delete_statements(value)
|
123
120
|
nil
|
124
|
-
when (statement = Statement.from(value)).
|
121
|
+
when (statement = Statement.from(value)).valid?
|
125
122
|
statement
|
126
123
|
else
|
127
124
|
delete_statements(query(value))
|
data/lib/rdf/mixin/queryable.rb
CHANGED
@@ -17,29 +17,18 @@ module RDF
|
|
17
17
|
# This method delegates to the protected {RDF::Queryable#query_pattern} method for the
|
18
18
|
# actual lower-level query pattern matching implementation.
|
19
19
|
#
|
20
|
-
# @example
|
20
|
+
# @example
|
21
21
|
# queryable.query([nil, RDF::DOAP.developer, nil])
|
22
|
-
# queryable.query(:predicate => RDF::DOAP.developer)
|
23
|
-
# puts statement.inspect
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @example Querying for solutions from a BGP
|
27
|
-
# query = RDF::Query.new {pattern [:s, :p, :o]}
|
28
|
-
# queryable.query(query) do |solution|
|
29
|
-
# puts solution.inspect
|
30
|
-
# end
|
22
|
+
# queryable.query(:predicate => RDF::DOAP.developer)
|
31
23
|
#
|
32
24
|
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
33
|
-
# @param [Hash{Symbol => Object}] options ({})
|
34
|
-
# Any other options passed to {#query_pattern} or {#query_execute}
|
35
25
|
# @yield [statement]
|
36
26
|
# each matching statement
|
37
|
-
# @yieldparam [RDF::Statement
|
38
|
-
# Statement or Solution
|
27
|
+
# @yieldparam [RDF::Statement] statement
|
39
28
|
# @yieldreturn [void] ignored
|
40
29
|
# @return [Enumerator]
|
41
30
|
# @see RDF::Queryable#query_pattern
|
42
|
-
def query(pattern,
|
31
|
+
def query(pattern, &block)
|
43
32
|
raise TypeError, "#{self} is not readable" if respond_to?(:readable?) && !readable?
|
44
33
|
|
45
34
|
case pattern
|
@@ -47,11 +36,7 @@ module RDF
|
|
47
36
|
when Query
|
48
37
|
if block_given?
|
49
38
|
before_query(pattern) if respond_to?(:before_query)
|
50
|
-
|
51
|
-
query_execute(pattern, &block)
|
52
|
-
else
|
53
|
-
query_execute(pattern, options, &block)
|
54
|
-
end
|
39
|
+
query_execute(pattern, &block)
|
55
40
|
after_query(pattern) if respond_to?(:after_query)
|
56
41
|
end
|
57
42
|
enum_for(:query_execute, pattern)
|
@@ -78,16 +63,14 @@ module RDF
|
|
78
63
|
|
79
64
|
# Otherwise, we delegate to `#query_pattern`:
|
80
65
|
else # pattern.variable?
|
81
|
-
if block_given?
|
82
|
-
if self.method(:query_pattern).arity == 1
|
83
|
-
query_pattern(pattern, &block)
|
84
|
-
else
|
85
|
-
query_pattern(pattern, options, &block)
|
86
|
-
end
|
87
|
-
end
|
66
|
+
query_pattern(pattern, &block) if block_given?
|
88
67
|
enum_for(:query_pattern, pattern)
|
89
68
|
end
|
90
69
|
after_query(pattern) if block_given? && respond_to?(:after_query)
|
70
|
+
enum.extend(RDF::Queryable, RDF::Enumerable, RDF::Countable)
|
71
|
+
def enum.to_a
|
72
|
+
super.extend(RDF::Queryable, RDF::Enumerable, RDF::Countable)
|
73
|
+
end
|
91
74
|
enum
|
92
75
|
end
|
93
76
|
end
|
@@ -102,8 +85,6 @@ module RDF
|
|
102
85
|
#
|
103
86
|
# @param [RDF::Query] query
|
104
87
|
# the query to execute
|
105
|
-
# @param [Hash{Symbol => Object}] options ({})
|
106
|
-
# Any other options passed to `query.execute`
|
107
88
|
# @yield [solution]
|
108
89
|
# @yieldparam [RDF::Query::Solution] solution
|
109
90
|
# @yieldreturn [void] ignored
|
@@ -111,12 +92,12 @@ module RDF
|
|
111
92
|
# @see RDF::Queryable#query
|
112
93
|
# @see RDF::Query#execute
|
113
94
|
# @since 0.3.0
|
114
|
-
def query_execute(query,
|
95
|
+
def query_execute(query, &block)
|
115
96
|
# By default, we let RDF.rb's built-in `RDF::Query#execute` handle BGP
|
116
97
|
# query execution by breaking down the query into its constituent
|
117
98
|
# triple patterns and invoking `RDF::Query::Pattern#execute` on each
|
118
99
|
# pattern.
|
119
|
-
query.execute(self
|
100
|
+
query.execute(self).each(&block)
|
120
101
|
end
|
121
102
|
protected :query_execute
|
122
103
|
|
@@ -130,8 +111,6 @@ module RDF
|
|
130
111
|
#
|
131
112
|
# @param [RDF::Query::Pattern] pattern
|
132
113
|
# the query pattern to match
|
133
|
-
# @param [Hash{Symbol => Object}] options ({})
|
134
|
-
# Any other options
|
135
114
|
# @yield [statement]
|
136
115
|
# @yieldparam [RDF::Statement] statement
|
137
116
|
# @yieldreturn [void] ignored
|
@@ -139,7 +118,7 @@ module RDF
|
|
139
118
|
# @see RDF::Queryable#query
|
140
119
|
# @see RDF::Query::Pattern#execute
|
141
120
|
# @since 0.2.0
|
142
|
-
def query_pattern(pattern,
|
121
|
+
def query_pattern(pattern, &block)
|
143
122
|
# By default, we let Ruby's built-in `Enumerable#grep` handle the
|
144
123
|
# matching of statements by iterating over all statements and calling
|
145
124
|
# `RDF::Query::Pattern#===` on each statement.
|
@@ -286,31 +265,5 @@ module RDF
|
|
286
265
|
def first_value(pattern = nil)
|
287
266
|
(literal = first_literal(pattern)) ? literal.value : nil
|
288
267
|
end
|
289
|
-
|
290
|
-
##
|
291
|
-
# @private
|
292
|
-
# @param [Symbol, #to_sym] method
|
293
|
-
# @return [Enumerator]
|
294
|
-
# @see Object#enum_for
|
295
|
-
def enum_for(method = :each, *args)
|
296
|
-
# Ensure that enumerators are, themselves, queryable
|
297
|
-
this = self
|
298
|
-
Queryable::Enumerator.new do |yielder|
|
299
|
-
this.send(method, *args) {|y| yielder << y}
|
300
|
-
end
|
301
|
-
end
|
302
|
-
alias_method :to_enum, :enum_for
|
303
|
-
|
304
|
-
|
305
|
-
# Extends Enumerator with {Queryable} and {Enumerable}, which is used by {Enumerable#each_statement} and {Queryable#enum_for}
|
306
|
-
class Enumerator < ::Enumerator
|
307
|
-
include Queryable
|
308
|
-
include Enumerable
|
309
|
-
|
310
|
-
# Make sure returned arrays are also queryable
|
311
|
-
def to_a
|
312
|
-
return super.to_a.extend(RDF::Queryable, RDF::Enumerable)
|
313
|
-
end
|
314
|
-
end
|
315
268
|
end # Queryable
|
316
269
|
end # RDF
|
data/lib/rdf/model/graph.rb
CHANGED
@@ -2,26 +2,31 @@ module RDF
|
|
2
2
|
##
|
3
3
|
# An RDF graph.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# An {RDF::Graph} contains a unique set of {RDF::Statement}. It is
|
6
|
+
# based on an underlying data object, which may be specified when the
|
7
|
+
# graph is initialized, and will default to a {RDF::Repository} without
|
8
|
+
# support for contexts otherwise.
|
7
9
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
+
# Note that in RDF 1.1, graphs are not named, but are associated with
|
11
|
+
# a name in the context of a Dataset, as a pair of <name, graph>.
|
12
|
+
# This class allows a name to be associated with a graph when it is
|
13
|
+
# a projection of an underlying {RDF::Repository} supporting contexts.
|
10
14
|
#
|
11
|
-
# @example
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# graph = RDF::Graph.new("http://www.bbc.co.uk/programmes/b0081dq5.rdf")
|
15
|
-
# graph.load!
|
15
|
+
# @example Creating an empty graph
|
16
|
+
# graph = Graph.new
|
16
17
|
#
|
17
|
-
# @example Loading graph data from a URL
|
18
|
+
# @example Loading graph data from a URL
|
18
19
|
# require 'rdf/rdfxml' # for RDF/XML support
|
19
20
|
#
|
20
21
|
# graph = RDF::Graph.load("http://www.bbc.co.uk/programmes/b0081dq5.rdf")
|
21
22
|
#
|
23
|
+
# @example Accessing a specific named graph within a {RDF::Repository}
|
24
|
+
# require 'rdf/trig' # for TriG support
|
25
|
+
#
|
26
|
+
# repository = RDF::Repository.load("https://raw.github.com/ruby-rdf/rdf-trig/master/etc/doap.trig")
|
27
|
+
# graph = RDF::Graph.new(:data => repository, :context => RDF::URI("http://greggkellogg.net/foaf#me"))
|
22
28
|
class Graph
|
23
|
-
include RDF::
|
24
|
-
|
29
|
+
include RDF::Value
|
25
30
|
include RDF::Countable
|
26
31
|
include RDF::Durable
|
27
32
|
include RDF::Enumerable
|
@@ -39,8 +44,7 @@ module RDF
|
|
39
44
|
# Name of this graph, if it is part of an {RDF::Repository}
|
40
45
|
# @!attribute [rw] context
|
41
46
|
# @return [RDF::Resource]
|
42
|
-
# @
|
43
|
-
# {RDF::Enumerable} supporting contexts will have a context.
|
47
|
+
# @since 1.1.0
|
44
48
|
attr_accessor :context
|
45
49
|
|
46
50
|
alias_method :name, :context
|
@@ -64,8 +68,8 @@ module RDF
|
|
64
68
|
# @return [Graph]
|
65
69
|
# @since 0.1.7
|
66
70
|
def self.load(url, options = {}, &block)
|
67
|
-
self.new(
|
68
|
-
graph.load
|
71
|
+
self.new(options) do |graph|
|
72
|
+
graph.load(url, options)
|
69
73
|
|
70
74
|
if block_given?
|
71
75
|
case block.arity
|
@@ -79,18 +83,24 @@ module RDF
|
|
79
83
|
##
|
80
84
|
# @overload initialize(context, options)
|
81
85
|
# @param [RDF::Resource] context
|
82
|
-
# The context
|
86
|
+
# The context from the associated {RDF::Queryable} associated
|
87
|
+
# with this graph as provided with the `:data` option
|
88
|
+
# (only for {RDF::Queryable} instances supporting
|
89
|
+
# named contexts).
|
83
90
|
# @param [Hash{Symbol => Object}] options
|
91
|
+
# @option options [RDF::Queryable] :data (RDF::Repository.new)
|
92
|
+
# Storage behind this graph.
|
93
|
+
# @raise [ArgumentError] if a `data` does not support contexts.
|
84
94
|
# @note contexts are only useful when used as a projection
|
85
95
|
# on a `:data` which supports contexts. Otherwise, there is no
|
86
96
|
# such thing as a named graph in RDF 1.1, a repository may have
|
87
97
|
# graphs which are named, but the name is not a property of the graph.
|
88
98
|
# @overload initialize(options)
|
89
99
|
# @param [Hash{Symbol => Object}] options
|
100
|
+
# @option options [RDF::Queryable] :data (RDF::Repository.new)
|
101
|
+
# Storage behind this graph.
|
90
102
|
# @yield [graph]
|
91
103
|
# @yieldparam [Graph]
|
92
|
-
# @note Currently, context makes this a named garph;
|
93
|
-
# in the next release it will not
|
94
104
|
def initialize(*args, &block)
|
95
105
|
context = args.shift unless args.first.is_a?(Hash)
|
96
106
|
options = args.first || {}
|
@@ -101,7 +111,10 @@ module RDF
|
|
101
111
|
end
|
102
112
|
|
103
113
|
@options = options.dup
|
104
|
-
@data = @options.delete(:data) || RDF::Repository.new
|
114
|
+
@data = @options.delete(:data) || RDF::Repository.new(:with_context => false)
|
115
|
+
|
116
|
+
raise ArgumentError, "Can't apply context unless initialized with `data` supporting contexts" if
|
117
|
+
@context && !@data.supports?(:context)
|
105
118
|
|
106
119
|
if block_given?
|
107
120
|
case block.arity
|
@@ -112,12 +125,14 @@ module RDF
|
|
112
125
|
end
|
113
126
|
|
114
127
|
##
|
128
|
+
# (re)loads the graph from the specified location, or from the location associated with the graph context, if any
|
115
129
|
# @return [void]
|
116
|
-
# @
|
130
|
+
# @see RDF::Mutable#load
|
117
131
|
def load!(*args)
|
118
132
|
case
|
119
133
|
when args.empty?
|
120
|
-
|
134
|
+
raise ArgumentError, "Can't reload graph with no context" unless context.is_a?(RDF::URI)
|
135
|
+
load(context.to_s, {:base_uri => context}.merge(@options))
|
121
136
|
else super
|
122
137
|
end
|
123
138
|
end
|
@@ -181,6 +196,15 @@ module RDF
|
|
181
196
|
named? ? context.to_s : "default"
|
182
197
|
end
|
183
198
|
|
199
|
+
##
|
200
|
+
# Returns `true` if this graph contains no RDF statements.
|
201
|
+
#
|
202
|
+
# @return [Boolean]
|
203
|
+
# @see RDF::Enumerable#empty?
|
204
|
+
def empty?
|
205
|
+
!@data.has_context?(context || false)
|
206
|
+
end
|
207
|
+
|
184
208
|
##
|
185
209
|
# Returns `true` if this graph has an anonymous context, `false` otherwise.
|
186
210
|
#
|
data/lib/rdf/model/list.rb
CHANGED
@@ -8,7 +8,8 @@ module RDF
|
|
8
8
|
# @since 0.2.3
|
9
9
|
class RDF::List
|
10
10
|
include RDF::Enumerable
|
11
|
-
include RDF::
|
11
|
+
include RDF::Value
|
12
|
+
include Comparable
|
12
13
|
|
13
14
|
##
|
14
15
|
# Constructs a new list from the given `values`.
|
@@ -38,12 +39,10 @@ module RDF
|
|
38
39
|
# @yield [list]
|
39
40
|
# @yieldparam [RDF::List] list
|
40
41
|
def initialize(subject = nil, graph = nil, values = nil, &block)
|
41
|
-
@subject = subject || RDF.
|
42
|
+
@subject = subject || RDF::Node.new
|
42
43
|
@graph = graph || RDF::Graph.new
|
43
44
|
|
44
|
-
unless values.
|
45
|
-
values.reverse_each {|value| self.unshift(value)}
|
46
|
-
end
|
45
|
+
values.each { |value| self << value } unless values.nil? || values.empty?
|
47
46
|
|
48
47
|
if block_given?
|
49
48
|
case block.arity
|
@@ -61,9 +60,10 @@ module RDF
|
|
61
60
|
##
|
62
61
|
# Validate the list ensuring that
|
63
62
|
# * rdf:rest values are all BNodes are nil
|
64
|
-
# *
|
65
|
-
#
|
66
|
-
#
|
63
|
+
# * each subject has exactly one value for `rdf:first` and
|
64
|
+
# `rdf:rest`.
|
65
|
+
# * The value of `rdf:rest` must be either a BNode or `rdf:nil`.
|
66
|
+
# * All other properties are ignored.
|
67
67
|
# @return [Boolean]
|
68
68
|
def valid?
|
69
69
|
li = subject
|
@@ -71,19 +71,13 @@ module RDF
|
|
71
71
|
rest = nil
|
72
72
|
firsts = rests = 0
|
73
73
|
@graph.query(:subject => li) do |st|
|
74
|
-
return false unless st.subject.node?
|
75
74
|
case st.predicate
|
76
|
-
when RDF.type
|
77
|
-
# Be tollerant about rdf:type entries, as some OWL vocabularies use it excessively
|
78
75
|
when RDF.first
|
79
76
|
firsts += 1
|
80
77
|
when RDF.rest
|
81
78
|
rest = st.object
|
82
79
|
return false unless rest.node? || rest == RDF.nil
|
83
80
|
rests += 1
|
84
|
-
else
|
85
|
-
# First node may have other properties
|
86
|
-
return false unless li == subject
|
87
81
|
end
|
88
82
|
end
|
89
83
|
return false unless firsts == 1 && rests == 1
|
@@ -199,7 +193,7 @@ module RDF
|
|
199
193
|
# Returns the element at `index`.
|
200
194
|
#
|
201
195
|
# @example
|
202
|
-
# RDF::List[1, 2, 3][0] #=>
|
196
|
+
# RDF::List[1, 2, 3][0] #=> 1
|
203
197
|
#
|
204
198
|
# @param [Integer] index
|
205
199
|
# @return [RDF::Term]
|
@@ -208,71 +202,6 @@ module RDF
|
|
208
202
|
at(index)
|
209
203
|
end
|
210
204
|
|
211
|
-
##
|
212
|
-
# Appends an element to the head of this list. Existing references are not updated, as the list subject changes as a side-effect.
|
213
|
-
#
|
214
|
-
# @example
|
215
|
-
# RDF::List[].unshift(1).unshift(2).unshift(3) #=> RDF::List[3, 2, 1]
|
216
|
-
#
|
217
|
-
# @param [RDF::Term] value
|
218
|
-
# @return [RDF::List]
|
219
|
-
# @see http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-unshift
|
220
|
-
#
|
221
|
-
def unshift(value)
|
222
|
-
value = case value
|
223
|
-
when nil then RDF.nil
|
224
|
-
when RDF::Value then value
|
225
|
-
when Array then RDF::List.new(nil, graph, value)
|
226
|
-
else value
|
227
|
-
end
|
228
|
-
|
229
|
-
new_subject, old_subject = RDF::Node.new, subject
|
230
|
-
|
231
|
-
graph.insert([new_subject, RDF.type, RDF.List])
|
232
|
-
graph.insert([new_subject, RDF.first, value.is_a?(RDF::List) ? value.subject : value])
|
233
|
-
graph.insert([new_subject, RDF.rest, old_subject])
|
234
|
-
|
235
|
-
@subject = new_subject
|
236
|
-
|
237
|
-
return self
|
238
|
-
end
|
239
|
-
|
240
|
-
##
|
241
|
-
# Removes and returns the element at the head of this list.
|
242
|
-
#
|
243
|
-
# @example
|
244
|
-
# RDF::List[1,2,3].shift #=> 1
|
245
|
-
#
|
246
|
-
# @return [RDF::Term]
|
247
|
-
# @see http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-shift
|
248
|
-
def shift
|
249
|
-
return nil if empty?
|
250
|
-
|
251
|
-
value = first
|
252
|
-
old_subject, new_subject = subject, rest_subject
|
253
|
-
graph.delete([old_subject, RDF.type, RDF.List])
|
254
|
-
graph.delete([old_subject, RDF.first, value])
|
255
|
-
graph.delete([old_subject, RDF.rest, new_subject])
|
256
|
-
|
257
|
-
@subject = new_subject
|
258
|
-
return value
|
259
|
-
end
|
260
|
-
|
261
|
-
##
|
262
|
-
# Empties this list
|
263
|
-
#
|
264
|
-
# @example
|
265
|
-
# RDF::List[1, 2, 2, 3].clear #=> RDF::List[]
|
266
|
-
#
|
267
|
-
# @return [RDF::List]
|
268
|
-
# @see http://ruby-doc.org/core-1.9.3/classes/Array.html#method-i-clear
|
269
|
-
def clear
|
270
|
-
until empty?
|
271
|
-
shift
|
272
|
-
end
|
273
|
-
return self
|
274
|
-
end
|
275
|
-
|
276
205
|
##
|
277
206
|
# Appends an element to the tail of this list.
|
278
207
|
#
|
@@ -291,14 +220,13 @@ module RDF
|
|
291
220
|
end
|
292
221
|
|
293
222
|
if empty?
|
294
|
-
|
223
|
+
new_subject = subject
|
295
224
|
else
|
296
225
|
old_subject, new_subject = last_subject, RDF::Node.new
|
297
226
|
graph.delete([old_subject, RDF.rest, RDF.nil])
|
298
227
|
graph.insert([old_subject, RDF.rest, new_subject])
|
299
228
|
end
|
300
229
|
|
301
|
-
graph.insert([new_subject, RDF.type, RDF.List])
|
302
230
|
graph.insert([new_subject, RDF.first, value.is_a?(RDF::List) ? value.subject : value])
|
303
231
|
graph.insert([new_subject, RDF.rest, RDF.nil])
|
304
232
|
|
@@ -367,12 +295,10 @@ module RDF
|
|
367
295
|
end
|
368
296
|
|
369
297
|
##
|
370
|
-
# Returns
|
298
|
+
# Returns the element at `index`.
|
371
299
|
#
|
372
300
|
# @example
|
373
|
-
#
|
374
|
-
# RDF::List[1, 2, 3].slice(0, 2) #=> RDF::List[1, 2],
|
375
|
-
# RDF::List[1, 2, 3].slice(0..2) #=> RDF::List[1, 2, 3]
|
301
|
+
# RDF::List[1, 2, 3].at(0) #=> 1
|
376
302
|
#
|
377
303
|
# @return [RDF::Term]
|
378
304
|
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000462
|
@@ -401,10 +327,10 @@ module RDF
|
|
401
327
|
protected :slice_with_range
|
402
328
|
|
403
329
|
##
|
404
|
-
# Returns element at `index
|
330
|
+
# Returns the element at `index`.
|
405
331
|
#
|
406
332
|
# @example
|
407
|
-
# RDF::List[1, 2, 3].fetch(0) #=>
|
333
|
+
# RDF::List[1, 2, 3].fetch(0) #=> 1
|
408
334
|
# RDF::List[1, 2, 3].fetch(4) #=> IndexError
|
409
335
|
# RDF::List[1, 2, 3].fetch(4, nil) #=> nil
|
410
336
|
# RDF::List[1, 2, 3].fetch(4) { |n| n*n } #=> 16
|
@@ -428,7 +354,6 @@ module RDF
|
|
428
354
|
#
|
429
355
|
# @example
|
430
356
|
# RDF::List[1, 2, 3].at(0) #=> 1
|
431
|
-
# RDF::List[1, 2, 3].at(4) #=> nil
|
432
357
|
#
|
433
358
|
# @return [RDF::Term]
|
434
359
|
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000419
|
@@ -445,7 +370,7 @@ module RDF
|
|
445
370
|
# Returns the first element in this list.
|
446
371
|
#
|
447
372
|
# @example
|
448
|
-
# RDF::List[*(1..10)].first #=>
|
373
|
+
# RDF::List[*(1..10)].first #=> 1
|
449
374
|
#
|
450
375
|
# @return [RDF::Term]
|
451
376
|
def first
|
@@ -456,7 +381,7 @@ module RDF
|
|
456
381
|
# Returns the second element in this list.
|
457
382
|
#
|
458
383
|
# @example
|
459
|
-
# RDF::List[*(1..10)].second #=>
|
384
|
+
# RDF::List[*(1..10)].second #=> 2
|
460
385
|
#
|
461
386
|
# @return [RDF::Term]
|
462
387
|
def second
|
@@ -467,7 +392,7 @@ module RDF
|
|
467
392
|
# Returns the third element in this list.
|
468
393
|
#
|
469
394
|
# @example
|
470
|
-
# RDF::List[*(1..10)].third #=>
|
395
|
+
# RDF::List[*(1..10)].third #=> 3
|
471
396
|
#
|
472
397
|
# @return [RDF::Term]
|
473
398
|
def third
|
@@ -478,7 +403,7 @@ module RDF
|
|
478
403
|
# Returns the fourth element in this list.
|
479
404
|
#
|
480
405
|
# @example
|
481
|
-
# RDF::List[*(1..10)].fourth #=>
|
406
|
+
# RDF::List[*(1..10)].fourth #=> 4
|
482
407
|
#
|
483
408
|
# @return [RDF::Term]
|
484
409
|
def fourth
|
@@ -489,7 +414,7 @@ module RDF
|
|
489
414
|
# Returns the fifth element in this list.
|
490
415
|
#
|
491
416
|
# @example
|
492
|
-
# RDF::List[*(1..10)].fifth #=>
|
417
|
+
# RDF::List[*(1..10)].fifth #=> 5
|
493
418
|
#
|
494
419
|
# @return [RDF::Term]
|
495
420
|
def fifth
|
@@ -500,7 +425,7 @@ module RDF
|
|
500
425
|
# Returns the sixth element in this list.
|
501
426
|
#
|
502
427
|
# @example
|
503
|
-
# RDF::List[*(1..10)].sixth #=>
|
428
|
+
# RDF::List[*(1..10)].sixth #=> 6
|
504
429
|
#
|
505
430
|
# @return [RDF::Term]
|
506
431
|
def sixth
|
@@ -511,7 +436,7 @@ module RDF
|
|
511
436
|
# Returns the seventh element in this list.
|
512
437
|
#
|
513
438
|
# @example
|
514
|
-
# RDF::List[*(1..10)].seventh #=>
|
439
|
+
# RDF::List[*(1..10)].seventh #=> 7
|
515
440
|
#
|
516
441
|
# @return [RDF::Term]
|
517
442
|
def seventh
|
@@ -522,7 +447,7 @@ module RDF
|
|
522
447
|
# Returns the eighth element in this list.
|
523
448
|
#
|
524
449
|
# @example
|
525
|
-
# RDF::List[*(1..10)].eighth #=>
|
450
|
+
# RDF::List[*(1..10)].eighth #=> 8
|
526
451
|
#
|
527
452
|
# @return [RDF::Term]
|
528
453
|
def eighth
|
@@ -533,7 +458,7 @@ module RDF
|
|
533
458
|
# Returns the ninth element in this list.
|
534
459
|
#
|
535
460
|
# @example
|
536
|
-
# RDF::List[*(1..10)].ninth #=>
|
461
|
+
# RDF::List[*(1..10)].ninth #=> 9
|
537
462
|
#
|
538
463
|
# @return [RDF::Term]
|
539
464
|
def ninth
|
@@ -544,7 +469,7 @@ module RDF
|
|
544
469
|
# Returns the tenth element in this list.
|
545
470
|
#
|
546
471
|
# @example
|
547
|
-
# RDF::List[*(1..10)].tenth #=>
|
472
|
+
# RDF::List[*(1..10)].tenth #=> 10
|
548
473
|
#
|
549
474
|
# @return [RDF::Term]
|
550
475
|
def tenth
|
@@ -555,7 +480,7 @@ module RDF
|
|
555
480
|
# Returns the last element in this list.
|
556
481
|
#
|
557
482
|
# @example
|
558
|
-
# RDF::List[
|
483
|
+
# RDF::List[1, 2, 3].last #=> 3
|
559
484
|
#
|
560
485
|
# @return [RDF::Term]
|
561
486
|
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000422
|
@@ -747,7 +672,7 @@ module RDF
|
|
747
672
|
#
|
748
673
|
# @example
|
749
674
|
# RDF::List[].to_a #=> []
|
750
|
-
# RDF::List[1, 2, 3].to_a #=> [
|
675
|
+
# RDF::List[1, 2, 3].to_a #=> [1, 2, 3]
|
751
676
|
#
|
752
677
|
# @return [Array]
|
753
678
|
def to_a
|
@@ -758,7 +683,7 @@ module RDF
|
|
758
683
|
# Returns the elements in this list as a set.
|
759
684
|
#
|
760
685
|
# @example
|
761
|
-
# RDF::List[1, 2, 3].to_set #=> Set[
|
686
|
+
# RDF::List[1, 2, 3].to_set #=> Set[1, 2, 3]
|
762
687
|
#
|
763
688
|
# @return [Set]
|
764
689
|
def to_set
|