rdf 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +1 -1
- data/VERSION +1 -1
- data/lib/rdf.rb +4 -0
- data/lib/rdf/mixin/writable.rb +20 -0
- data/lib/rdf/model/list.rb +698 -0
- data/lib/rdf/model/literal.rb +13 -1
- data/lib/rdf/model/literal/decimal.rb +91 -0
- data/lib/rdf/model/literal/double.rb +165 -0
- data/lib/rdf/model/literal/integer.rb +131 -0
- data/lib/rdf/model/literal/token.rb +47 -0
- data/lib/rdf/model/statement.rb +0 -1
- data/lib/rdf/query/pattern.rb +0 -1
- data/lib/rdf/query/variable.rb +8 -3
- data/lib/rdf/reader.rb +14 -0
- data/lib/rdf/util/cache.rb +2 -2
- data/lib/rdf/version.rb +1 -1
- data/lib/rdf/writer.rb +19 -9
- metadata +9 -7
data/README
CHANGED
@@ -148,7 +148,7 @@ Dependencies
|
|
148
148
|
------------
|
149
149
|
|
150
150
|
* [Ruby](http://ruby-lang.org/) (>= 1.8.7) or (>= 1.8.1 with [Backports][])
|
151
|
-
* [Addressable](http://rubygems.org/gems/addressable) (>= 2.
|
151
|
+
* [Addressable](http://rubygems.org/gems/addressable) (>= 2.2.0)
|
152
152
|
|
153
153
|
Installation
|
154
154
|
------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
data/lib/rdf.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'enumerator'
|
2
2
|
require 'open-uri'
|
3
|
+
require 'stringio'
|
3
4
|
require 'bigdecimal'
|
4
5
|
require 'date'
|
5
6
|
require 'time'
|
@@ -43,6 +44,9 @@ module RDF
|
|
43
44
|
autoload :URI, 'rdf/model/uri'
|
44
45
|
autoload :Value, 'rdf/model/value'
|
45
46
|
|
47
|
+
# RDF collections
|
48
|
+
autoload :List, 'rdf/model/list'
|
49
|
+
|
46
50
|
# RDF serialization
|
47
51
|
autoload :Format, 'rdf/format'
|
48
52
|
autoload :Reader, 'rdf/reader'
|
data/lib/rdf/mixin/writable.rb
CHANGED
@@ -19,6 +19,8 @@ module RDF
|
|
19
19
|
# @return [Writable]
|
20
20
|
def <<(data)
|
21
21
|
case data
|
22
|
+
when RDF::Reader
|
23
|
+
insert_reader(data)
|
22
24
|
when RDF::Graph
|
23
25
|
insert_graph(data)
|
24
26
|
when RDF::Enumerable
|
@@ -63,6 +65,24 @@ module RDF
|
|
63
65
|
|
64
66
|
protected
|
65
67
|
|
68
|
+
##
|
69
|
+
# Inserts statements from the given RDF reader into the underlying
|
70
|
+
# storage or output stream.
|
71
|
+
#
|
72
|
+
# Defaults to passing the reader to the {#insert_statements} method.
|
73
|
+
#
|
74
|
+
# Subclasses of {RDF::Repository} may wish to override this method in
|
75
|
+
# case their underlying storage can efficiently import RDF data directly
|
76
|
+
# in particular serialization formats, thus avoiding the intermediate
|
77
|
+
# parsing overhead.
|
78
|
+
#
|
79
|
+
# @param [RDF::Reader] reader
|
80
|
+
# @return [void]
|
81
|
+
# @since 0.2.3
|
82
|
+
def insert_reader(reader)
|
83
|
+
insert_statements(reader)
|
84
|
+
end
|
85
|
+
|
66
86
|
##
|
67
87
|
# Inserts the given RDF graph into the underlying storage or output
|
68
88
|
# stream.
|
@@ -0,0 +1,698 @@
|
|
1
|
+
module RDF
|
2
|
+
##
|
3
|
+
# An RDF list.
|
4
|
+
#
|
5
|
+
# @example Constructing a new list
|
6
|
+
# RDF::List[1, 2, 3]
|
7
|
+
#
|
8
|
+
# @since 0.2.3
|
9
|
+
class RDF::List
|
10
|
+
include RDF::Enumerable
|
11
|
+
include RDF::Resource
|
12
|
+
|
13
|
+
##
|
14
|
+
# Constructs a new list from the given `values`.
|
15
|
+
#
|
16
|
+
# The list will be identified by a new autogenerated blank node, and
|
17
|
+
# backed by an initially empty in-memory graph.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# RDF::List[]
|
21
|
+
# RDF::List[*(1..10)]
|
22
|
+
# RDF::List[1, 2, 3]
|
23
|
+
# RDF::List["foo", "bar"]
|
24
|
+
# RDF::List["a", 1, "b", 2, "c", 3]
|
25
|
+
#
|
26
|
+
# @param [Array<RDF::Value>] values
|
27
|
+
# @return [RDF::List]
|
28
|
+
def self.[](*values)
|
29
|
+
self.new(nil, nil, values)
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Initializes a newly-constructed list.
|
34
|
+
#
|
35
|
+
# @param [RDF::Resource] subject
|
36
|
+
# @param [RDF::Graph] graph
|
37
|
+
# @param [Array<RDF::Value>] values
|
38
|
+
# @yield [list]
|
39
|
+
# @yieldparam [RDF::List] list
|
40
|
+
def initialize(subject = nil, graph = nil, values = nil, &block)
|
41
|
+
@subject = subject || RDF::Node.new
|
42
|
+
@graph = graph || RDF::Graph.new
|
43
|
+
|
44
|
+
values.each { |value| self << value } unless values.nil? || values.empty?
|
45
|
+
|
46
|
+
if block_given?
|
47
|
+
case block.arity
|
48
|
+
when 1 then block.call(self)
|
49
|
+
else instance_eval(&block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
UNSET = Object.new.freeze # @private
|
55
|
+
|
56
|
+
# The canonical empty list.
|
57
|
+
NIL = RDF::List.new(RDF.nil).freeze
|
58
|
+
|
59
|
+
##
|
60
|
+
# Returns the subject term of this list.
|
61
|
+
#
|
62
|
+
# @return [RDF::Resource]
|
63
|
+
attr_reader :subject
|
64
|
+
|
65
|
+
##
|
66
|
+
# Returns the underlying graph storing the statements that constitute
|
67
|
+
# this list.
|
68
|
+
#
|
69
|
+
# @return [RDF::Graph]
|
70
|
+
attr_reader :graph
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns the set intersection of this list and `other`.
|
74
|
+
#
|
75
|
+
# The resulting list contains the elements common to both lists, with no
|
76
|
+
# duplicates.
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# RDF::List[1, 2] & RDF::List[1, 2] #=> RDF::List[1, 2]
|
80
|
+
# RDF::List[1, 2] & RDF::List[2, 3] #=> RDF::List[2]
|
81
|
+
# RDF::List[1, 2] & RDF::List[3, 4] #=> RDF::List[]
|
82
|
+
#
|
83
|
+
# @param [RDF::List] other
|
84
|
+
# @return [RDF::List]
|
85
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000469
|
86
|
+
def &(other)
|
87
|
+
RDF::List[*(to_a & other.to_a)]
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Returns the set union of this list and `other`.
|
92
|
+
#
|
93
|
+
# The resulting list contains the elements from both lists, with no
|
94
|
+
# duplicates.
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# RDF::List[1, 2] | RDF::List[1, 2] #=> RDF::List[1, 2]
|
98
|
+
# RDF::List[1, 2] | RDF::List[2, 3] #=> RDF::List[1, 2, 3]
|
99
|
+
# RDF::List[1, 2] | RDF::List[3, 4] #=> RDF::List[1, 2, 3, 4]
|
100
|
+
#
|
101
|
+
# @param [RDF::List] other
|
102
|
+
# @return [RDF::List]
|
103
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000470
|
104
|
+
def |(other)
|
105
|
+
RDF::List[*(to_a | other.to_a)]
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Returns the concatenation of this list and `other`.
|
110
|
+
#
|
111
|
+
# @example
|
112
|
+
# RDF::List[1, 2] + RDF::List[3, 4] #=> RDF::List[1, 2, 3, 4]
|
113
|
+
#
|
114
|
+
# @param [RDF::List] other
|
115
|
+
# @return [RDF::List]
|
116
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000466
|
117
|
+
def +(other)
|
118
|
+
RDF::List[*(to_a + other.to_a)]
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Returns the difference between this list and `other`, removing any
|
123
|
+
# elements that appear in both lists.
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# RDF::List[1, 2, 2, 3] - RDF::List[2] #=> RDF::List[1, 3]
|
127
|
+
#
|
128
|
+
# @param [RDF::List] other
|
129
|
+
# @return [RDF::List]
|
130
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000468
|
131
|
+
def -(other)
|
132
|
+
RDF::List[*(to_a - other.to_a)]
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Returns either a repeated list or a string concatenation of the
|
137
|
+
# elements in this list.
|
138
|
+
#
|
139
|
+
# @overload *(times)
|
140
|
+
# Returns a new list built of `times` repetitions of this list.
|
141
|
+
#
|
142
|
+
# @example
|
143
|
+
# RDF::List[1, 2, 3] * 2 #=> RDF::List[1, 2, 3, 1, 2, 3]
|
144
|
+
#
|
145
|
+
# @param [Integer] times
|
146
|
+
# @return [RDF::List]
|
147
|
+
#
|
148
|
+
# @overload *(sep)
|
149
|
+
# Returns the string concatenation of the elements in this list
|
150
|
+
# separated by `sep`. Equivalent to `self.join(sep)`.
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# RDF::List[1, 2, 3] * "," #=> "1,2,3"
|
154
|
+
#
|
155
|
+
# @param [String, #to_s] sep
|
156
|
+
# @return [RDF::List]
|
157
|
+
#
|
158
|
+
# @return [RDF::List]
|
159
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000467
|
160
|
+
def *(int_or_str)
|
161
|
+
case int_or_str
|
162
|
+
when Integer then RDF::List[*(to_a * int_or_str)]
|
163
|
+
else join(int_or_str.to_s)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
##
|
168
|
+
# Returns the element at `index`.
|
169
|
+
#
|
170
|
+
# @example
|
171
|
+
# RDF::List[1, 2, 3][0] #=> 1
|
172
|
+
#
|
173
|
+
# @param [Integer] index
|
174
|
+
# @return [RDF::Value]
|
175
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000417
|
176
|
+
def [](index)
|
177
|
+
at(index)
|
178
|
+
end
|
179
|
+
|
180
|
+
##
|
181
|
+
# Appends an element to the tail of this list.
|
182
|
+
#
|
183
|
+
# @example
|
184
|
+
# RDF::List[] << 1 << 2 << 3 #=> RDF::List[1, 2, 3]
|
185
|
+
#
|
186
|
+
# @param [RDF::Value] value
|
187
|
+
# @return [RDF::List]
|
188
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000424
|
189
|
+
def <<(value)
|
190
|
+
value = case value
|
191
|
+
when nil then RDF.nil
|
192
|
+
when RDF::Value then value
|
193
|
+
when Array then RDF::List.new(nil, graph, value)
|
194
|
+
else value
|
195
|
+
end
|
196
|
+
|
197
|
+
if empty?
|
198
|
+
new_subject = subject
|
199
|
+
else
|
200
|
+
old_subject, new_subject = last_subject, RDF::Node.new
|
201
|
+
graph.delete([old_subject, RDF.rest, RDF.nil])
|
202
|
+
graph.insert([old_subject, RDF.rest, new_subject])
|
203
|
+
end
|
204
|
+
|
205
|
+
graph.insert([new_subject, RDF.type, RDF.List])
|
206
|
+
graph.insert([new_subject, RDF.first, value])
|
207
|
+
graph.insert([new_subject, RDF.rest, RDF.nil])
|
208
|
+
|
209
|
+
self
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# Compares this list to `other` for sorting purposes.
|
214
|
+
#
|
215
|
+
# @example
|
216
|
+
# RDF::List[1] <=> RDF::List[1] #=> 0
|
217
|
+
# RDF::List[1] <=> RDF::List[2] #=> -1
|
218
|
+
# RDF::List[2] <=> RDF::List[1] #=> 1
|
219
|
+
#
|
220
|
+
# @param [RDF::List] other
|
221
|
+
# @return [Integer]
|
222
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000461
|
223
|
+
def <=>(other)
|
224
|
+
to_a <=> other.to_a # TODO: optimize this
|
225
|
+
end
|
226
|
+
|
227
|
+
##
|
228
|
+
# Returns `true` if this list is empty.
|
229
|
+
#
|
230
|
+
# @example
|
231
|
+
# RDF::List[].empty? #=> true
|
232
|
+
# RDF::List[1, 2, 3].empty? #=> false
|
233
|
+
#
|
234
|
+
# @return [Boolean]
|
235
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000434
|
236
|
+
def empty?
|
237
|
+
graph.query(:subject => subject, :predicate => RDF.first).empty?
|
238
|
+
end
|
239
|
+
|
240
|
+
##
|
241
|
+
# Returns the length of this list.
|
242
|
+
#
|
243
|
+
# @example
|
244
|
+
# RDF::List[].length #=> 0
|
245
|
+
# RDF::List[1, 2, 3].length #=> 3
|
246
|
+
#
|
247
|
+
# @return [Integer]
|
248
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000433
|
249
|
+
def length
|
250
|
+
each.count
|
251
|
+
end
|
252
|
+
|
253
|
+
alias_method :size, :length
|
254
|
+
|
255
|
+
##
|
256
|
+
# Returns the index of the first element equal to `value`, or `nil` if
|
257
|
+
# no match was found.
|
258
|
+
#
|
259
|
+
# @example
|
260
|
+
# RDF::List['a', 'b', 'c'].index('a') #=> 0
|
261
|
+
# RDF::List['a', 'b', 'c'].index('d') #=> nil
|
262
|
+
#
|
263
|
+
# @param [RDF::Value] value
|
264
|
+
# @return [Integer]
|
265
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000436
|
266
|
+
def index(value)
|
267
|
+
each.with_index do |v, i|
|
268
|
+
return i if v == value
|
269
|
+
end
|
270
|
+
return nil
|
271
|
+
end
|
272
|
+
|
273
|
+
##
|
274
|
+
# Returns the element at `index`.
|
275
|
+
#
|
276
|
+
# @example
|
277
|
+
# RDF::List[1, 2, 3].at(0) #=> 1
|
278
|
+
#
|
279
|
+
# @return [RDF::Value]
|
280
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000462
|
281
|
+
def slice(*args)
|
282
|
+
case argc = args.size
|
283
|
+
when 2 then slice_with_start_and_length(*args)
|
284
|
+
when 1 then (arg = args.first).is_a?(Range) ? slice_with_range(arg) : at(arg)
|
285
|
+
when 0 then raise ArgumentError, "wrong number of arguments (0 for 1)"
|
286
|
+
else raise ArgumentError, "wrong number of arguments (#{argc} for 2)"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
##
|
291
|
+
# @private
|
292
|
+
def slice_with_start_and_length(start, length)
|
293
|
+
RDF::List[*to_a.slice(start, length)]
|
294
|
+
end
|
295
|
+
|
296
|
+
##
|
297
|
+
# @private
|
298
|
+
def slice_with_range(range)
|
299
|
+
RDF::List[*to_a.slice(range)]
|
300
|
+
end
|
301
|
+
|
302
|
+
protected :slice_with_start_and_length
|
303
|
+
protected :slice_with_range
|
304
|
+
|
305
|
+
##
|
306
|
+
# Returns the element at `index`.
|
307
|
+
#
|
308
|
+
# @example
|
309
|
+
# RDF::List[1, 2, 3].fetch(0) #=> 1
|
310
|
+
# RDF::List[1, 2, 3].fetch(4) #=> IndexError
|
311
|
+
# RDF::List[1, 2, 3].fetch(4, nil) #=> nil
|
312
|
+
# RDF::List[1, 2, 3].fetch(4) { |n| n*n } #=> 16
|
313
|
+
#
|
314
|
+
# @return [RDF::Value]
|
315
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000420
|
316
|
+
def fetch(index, default = UNSET, &block)
|
317
|
+
each.with_index do |v, i|
|
318
|
+
return v if i == index
|
319
|
+
end
|
320
|
+
|
321
|
+
case
|
322
|
+
when block_given? then block.call(index)
|
323
|
+
when !default.eql?(UNSET) then default
|
324
|
+
else raise IndexError, "index #{index} not in the list #{self.inspect}"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
##
|
329
|
+
# Returns the element at `index`.
|
330
|
+
#
|
331
|
+
# @example
|
332
|
+
# RDF::List[1, 2, 3].at(0) #=> 1
|
333
|
+
#
|
334
|
+
# @return [RDF::Value]
|
335
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000419
|
336
|
+
def at(index)
|
337
|
+
each.with_index do |v, i|
|
338
|
+
return v if i == index
|
339
|
+
end
|
340
|
+
return nil
|
341
|
+
end
|
342
|
+
|
343
|
+
alias_method :nth, :at
|
344
|
+
|
345
|
+
##
|
346
|
+
# Returns the first element in this list.
|
347
|
+
#
|
348
|
+
# @example
|
349
|
+
# RDF::List[*(1..10)].first #=> 1
|
350
|
+
#
|
351
|
+
# @return [RDF::Value]
|
352
|
+
def first
|
353
|
+
graph.first_object(:subject => first_subject, :predicate => RDF.first)
|
354
|
+
end
|
355
|
+
|
356
|
+
##
|
357
|
+
# Returns the second element in this list.
|
358
|
+
#
|
359
|
+
# @example
|
360
|
+
# RDF::List[*(1..10)].second #=> 2
|
361
|
+
#
|
362
|
+
# @return [RDF::Value]
|
363
|
+
def second
|
364
|
+
at(1)
|
365
|
+
end
|
366
|
+
|
367
|
+
##
|
368
|
+
# Returns the third element in this list.
|
369
|
+
#
|
370
|
+
# @example
|
371
|
+
# RDF::List[*(1..10)].third #=> 3
|
372
|
+
#
|
373
|
+
# @return [RDF::Value]
|
374
|
+
def third
|
375
|
+
at(2)
|
376
|
+
end
|
377
|
+
|
378
|
+
##
|
379
|
+
# Returns the fourth element in this list.
|
380
|
+
#
|
381
|
+
# @example
|
382
|
+
# RDF::List[*(1..10)].fourth #=> 4
|
383
|
+
#
|
384
|
+
# @return [RDF::Value]
|
385
|
+
def fourth
|
386
|
+
at(3)
|
387
|
+
end
|
388
|
+
|
389
|
+
##
|
390
|
+
# Returns the fifth element in this list.
|
391
|
+
#
|
392
|
+
# @example
|
393
|
+
# RDF::List[*(1..10)].fifth #=> 5
|
394
|
+
#
|
395
|
+
# @return [RDF::Value]
|
396
|
+
def fifth
|
397
|
+
at(4)
|
398
|
+
end
|
399
|
+
|
400
|
+
##
|
401
|
+
# Returns the sixth element in this list.
|
402
|
+
#
|
403
|
+
# @example
|
404
|
+
# RDF::List[*(1..10)].sixth #=> 6
|
405
|
+
#
|
406
|
+
# @return [RDF::Value]
|
407
|
+
def sixth
|
408
|
+
at(5)
|
409
|
+
end
|
410
|
+
|
411
|
+
##
|
412
|
+
# Returns the seventh element in this list.
|
413
|
+
#
|
414
|
+
# @example
|
415
|
+
# RDF::List[*(1..10)].seventh #=> 7
|
416
|
+
#
|
417
|
+
# @return [RDF::Value]
|
418
|
+
def seventh
|
419
|
+
at(6)
|
420
|
+
end
|
421
|
+
|
422
|
+
##
|
423
|
+
# Returns the eighth element in this list.
|
424
|
+
#
|
425
|
+
# @example
|
426
|
+
# RDF::List[*(1..10)].eighth #=> 8
|
427
|
+
#
|
428
|
+
# @return [RDF::Value]
|
429
|
+
def eighth
|
430
|
+
at(7)
|
431
|
+
end
|
432
|
+
|
433
|
+
##
|
434
|
+
# Returns the ninth element in this list.
|
435
|
+
#
|
436
|
+
# @example
|
437
|
+
# RDF::List[*(1..10)].ninth #=> 9
|
438
|
+
#
|
439
|
+
# @return [RDF::Value]
|
440
|
+
def ninth
|
441
|
+
at(8)
|
442
|
+
end
|
443
|
+
|
444
|
+
##
|
445
|
+
# Returns the tenth element in this list.
|
446
|
+
#
|
447
|
+
# @example
|
448
|
+
# RDF::List[*(1..10)].tenth #=> 10
|
449
|
+
#
|
450
|
+
# @return [RDF::Value]
|
451
|
+
def tenth
|
452
|
+
at(9)
|
453
|
+
end
|
454
|
+
|
455
|
+
##
|
456
|
+
# Returns the last element in this list.
|
457
|
+
#
|
458
|
+
# @example
|
459
|
+
# RDF::List[1, 2, 3].last #=> 3
|
460
|
+
#
|
461
|
+
# @return [RDF::Value]
|
462
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000422
|
463
|
+
def last
|
464
|
+
graph.first_object(:subject => last_subject, :predicate => RDF.first)
|
465
|
+
end
|
466
|
+
|
467
|
+
##
|
468
|
+
# Returns a list containing all but the first element of this list.
|
469
|
+
#
|
470
|
+
# @example
|
471
|
+
# RDF::List[1, 2, 3].rest #=> RDF::List[2, 3]
|
472
|
+
#
|
473
|
+
# @return [RDF::List]
|
474
|
+
def rest
|
475
|
+
(subject = rest_subject).eql?(RDF.nil) ? nil : self.class.new(subject, graph)
|
476
|
+
end
|
477
|
+
|
478
|
+
##
|
479
|
+
# Returns a list containing the last element of this list.
|
480
|
+
#
|
481
|
+
# @example
|
482
|
+
# RDF::List[1, 2, 3].tail #=> RDF::List[3]
|
483
|
+
#
|
484
|
+
# @return [RDF::List]
|
485
|
+
def tail
|
486
|
+
(subject = last_subject).eql?(RDF.nil) ? nil : self.class.new(subject, graph)
|
487
|
+
end
|
488
|
+
|
489
|
+
##
|
490
|
+
# Returns the first subject term constituting this list.
|
491
|
+
#
|
492
|
+
# This is equivalent to {#subject}.
|
493
|
+
#
|
494
|
+
# @example
|
495
|
+
# RDF::List[1, 2, 3].first_subject #=> RDF::Node(...)
|
496
|
+
#
|
497
|
+
# @return [RDF::Resource]
|
498
|
+
def first_subject
|
499
|
+
subject
|
500
|
+
end
|
501
|
+
|
502
|
+
##
|
503
|
+
# @example
|
504
|
+
# RDF::List[1, 2, 3].rest_subject #=> RDF::Node(...)
|
505
|
+
#
|
506
|
+
# @return [RDF::Resource]
|
507
|
+
def rest_subject
|
508
|
+
graph.first_object(:subject => subject, :predicate => RDF.rest)
|
509
|
+
end
|
510
|
+
|
511
|
+
##
|
512
|
+
# Returns the last subject term constituting this list.
|
513
|
+
#
|
514
|
+
# @example
|
515
|
+
# RDF::List[1, 2, 3].last_subject #=> RDF::Node(...)
|
516
|
+
#
|
517
|
+
# @return [RDF::Resource]
|
518
|
+
def last_subject
|
519
|
+
each_subject.to_a.last # TODO: optimize this
|
520
|
+
end
|
521
|
+
|
522
|
+
##
|
523
|
+
# Yields each subject term constituting this list.
|
524
|
+
#
|
525
|
+
# @example
|
526
|
+
# RDF::List[1, 2, 3].each_subject do |subject|
|
527
|
+
# puts subject.inspect
|
528
|
+
# end
|
529
|
+
#
|
530
|
+
# @return [Enumerator]
|
531
|
+
# @see RDF::Enumerable#each
|
532
|
+
def each_subject(&block)
|
533
|
+
return enum_subject unless block_given?
|
534
|
+
|
535
|
+
subject = self.subject
|
536
|
+
block.call(subject)
|
537
|
+
|
538
|
+
loop do
|
539
|
+
rest = graph.first_object(:subject => subject, :predicate => RDF.rest)
|
540
|
+
break if rest.nil? || rest.eql?(RDF.nil)
|
541
|
+
block.call(subject = rest)
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
##
|
546
|
+
# Yields each element in this list.
|
547
|
+
#
|
548
|
+
# @example
|
549
|
+
# RDF::List[1, 2, 3].each do |value|
|
550
|
+
# puts value.inspect
|
551
|
+
# end
|
552
|
+
#
|
553
|
+
# @return [Enumerator]
|
554
|
+
# @see http://ruby-doc.org/core-1.9/classes/Enumerable.html
|
555
|
+
def each(&block)
|
556
|
+
return to_enum unless block_given?
|
557
|
+
|
558
|
+
each_subject do |subject|
|
559
|
+
if value = graph.first_object(:subject => subject, :predicate => RDF.first)
|
560
|
+
block.call(value) # FIXME
|
561
|
+
end
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
##
|
566
|
+
# Yields each statement constituting this list.
|
567
|
+
#
|
568
|
+
# @example
|
569
|
+
# RDF::List[1, 2, 3].each_statement do |statement|
|
570
|
+
# puts statement.inspect
|
571
|
+
# end
|
572
|
+
#
|
573
|
+
# @return [Enumerator]
|
574
|
+
# @see RDF::Enumerable#each_statement
|
575
|
+
def each_statement(&block)
|
576
|
+
return enum_statement unless block_given?
|
577
|
+
|
578
|
+
each_subject do |subject|
|
579
|
+
graph.query(:subject => subject, &block)
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
##
|
584
|
+
# Returns a string created by converting each element of this list into
|
585
|
+
# a string, separated by `sep`.
|
586
|
+
#
|
587
|
+
# @example
|
588
|
+
# RDF::List[1, 2, 3].join #=> "123"
|
589
|
+
# RDF::List[1, 2, 3].join(", ") #=> "1, 2, 3"
|
590
|
+
#
|
591
|
+
# @param [String] sep
|
592
|
+
# @return [String]
|
593
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000438
|
594
|
+
def join(sep = $,)
|
595
|
+
map(&:to_s).join(sep)
|
596
|
+
end
|
597
|
+
|
598
|
+
##
|
599
|
+
# Returns the elements in this list in reversed order.
|
600
|
+
#
|
601
|
+
# @example
|
602
|
+
# RDF::List[1, 2, 3].reverse #=> RDF::List[3, 2, 1]
|
603
|
+
#
|
604
|
+
# @return [RDF::List]
|
605
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000439
|
606
|
+
def reverse
|
607
|
+
RDF::List[*to_a.reverse]
|
608
|
+
end
|
609
|
+
|
610
|
+
##
|
611
|
+
# Returns the elements in this list in sorted order.
|
612
|
+
#
|
613
|
+
# @example
|
614
|
+
# RDF::List[2, 3, 1].sort #=> RDF::List[1, 2, 3]
|
615
|
+
#
|
616
|
+
# @return [RDF::List]
|
617
|
+
# @see http://ruby-doc.org/core-1.9/classes/Enumerable.html#M003038
|
618
|
+
def sort(&block)
|
619
|
+
RDF::List[*super]
|
620
|
+
end
|
621
|
+
|
622
|
+
##
|
623
|
+
# Returns the elements in this list in sorted order.
|
624
|
+
#
|
625
|
+
# @example
|
626
|
+
# RDF::List[2, 3, 1].sort_by(&:to_i) #=> RDF::List[1, 2, 3]
|
627
|
+
#
|
628
|
+
# @return [RDF::List]
|
629
|
+
# @see http://ruby-doc.org/core-1.9/classes/Enumerable.html#M003039
|
630
|
+
def sort_by(&block)
|
631
|
+
RDF::List[*super]
|
632
|
+
end
|
633
|
+
|
634
|
+
##
|
635
|
+
# Returns a new list with the duplicates in this list removed.
|
636
|
+
#
|
637
|
+
# @example
|
638
|
+
# RDF::List[1, 2, 2, 3].uniq #=> RDF::List[1, 2, 3]
|
639
|
+
#
|
640
|
+
# @return [RDF::List]
|
641
|
+
# @see http://ruby-doc.org/core-1.9/classes/Array.html#M000471
|
642
|
+
def uniq
|
643
|
+
RDF::List[*to_a.uniq]
|
644
|
+
end
|
645
|
+
|
646
|
+
##
|
647
|
+
# Returns the elements in this list as an array.
|
648
|
+
#
|
649
|
+
# @example
|
650
|
+
# RDF::List[].to_a #=> []
|
651
|
+
# RDF::List[1, 2, 3].to_a #=> [1, 2, 3]
|
652
|
+
#
|
653
|
+
# @return [Array]
|
654
|
+
def to_a
|
655
|
+
each.to_a
|
656
|
+
end
|
657
|
+
|
658
|
+
##
|
659
|
+
# Returns the elements in this list as a set.
|
660
|
+
#
|
661
|
+
# @example
|
662
|
+
# RDF::List[1, 2, 3].to_set #=> Set[1, 2, 3]
|
663
|
+
#
|
664
|
+
# @return [Set]
|
665
|
+
def to_set
|
666
|
+
require 'set' unless defined?(::Set)
|
667
|
+
each.to_set
|
668
|
+
end
|
669
|
+
|
670
|
+
##
|
671
|
+
# Returns a string representation of this list.
|
672
|
+
#
|
673
|
+
# @example
|
674
|
+
# RDF::List[].to_s #=> "RDF::List[]"
|
675
|
+
# RDF::List[1, 2, 3].to_s #=> "RDF::List[1, 2, 3]"
|
676
|
+
#
|
677
|
+
# @return [String]
|
678
|
+
def to_s
|
679
|
+
'RDF::List[' + join(', ') + ']'
|
680
|
+
end
|
681
|
+
|
682
|
+
##
|
683
|
+
# Returns a developer-friendly representation of this list.
|
684
|
+
#
|
685
|
+
# @example
|
686
|
+
# RDF::List[].inspect #=> "#<RDF::List(_:g2163790380)>"
|
687
|
+
#
|
688
|
+
# @return [String]
|
689
|
+
def inspect
|
690
|
+
if self.equal?(NIL)
|
691
|
+
'RDF::List::NIL'
|
692
|
+
else
|
693
|
+
#sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, subject.to_s)
|
694
|
+
sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, to_s) # FIXME
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
end
|