rdf 3.1.5 → 3.1.10
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.
- checksums.yaml +4 -4
- data/README.md +27 -15
- data/VERSION +1 -1
- data/lib/rdf.rb +24 -0
- data/lib/rdf/cli.rb +38 -10
- data/lib/rdf/mixin/enumerable.rb +46 -28
- data/lib/rdf/mixin/mutable.rb +1 -1
- data/lib/rdf/model/dataset.rb +1 -1
- data/lib/rdf/model/graph.rb +14 -7
- data/lib/rdf/model/list.rb +44 -19
- data/lib/rdf/model/literal.rb +15 -14
- data/lib/rdf/model/literal/date.rb +5 -3
- data/lib/rdf/model/literal/datetime.rb +11 -7
- data/lib/rdf/model/literal/decimal.rb +12 -6
- data/lib/rdf/model/literal/double.rb +8 -8
- data/lib/rdf/model/literal/numeric.rb +34 -0
- data/lib/rdf/model/literal/time.rb +7 -5
- data/lib/rdf/model/node.rb +2 -6
- data/lib/rdf/model/statement.rb +36 -23
- data/lib/rdf/model/term.rb +8 -0
- data/lib/rdf/model/uri.rb +27 -19
- data/lib/rdf/nquads.rb +2 -2
- data/lib/rdf/ntriples/reader.rb +6 -6
- data/lib/rdf/ntriples/writer.rb +3 -3
- data/lib/rdf/query.rb +8 -1
- data/lib/rdf/query/pattern.rb +32 -38
- data/lib/rdf/query/solution.rb +8 -6
- data/lib/rdf/query/solutions.rb +5 -3
- data/lib/rdf/query/variable.rb +12 -1
- data/lib/rdf/reader.rb +6 -19
- data/lib/rdf/repository.rb +34 -25
- data/lib/rdf/transaction.rb +9 -3
- data/lib/rdf/util/cache.rb +10 -6
- data/lib/rdf/util/logger.rb +1 -1
- data/lib/rdf/vocab/writer.rb +1 -1
- data/lib/rdf/vocabulary.rb +4 -4
- data/lib/rdf/writer.rb +2 -2
- metadata +12 -12
data/lib/rdf/model/list.rb
CHANGED
@@ -45,18 +45,27 @@ module RDF
|
|
45
45
|
# identified by `subject`, but will be invalid.
|
46
46
|
#
|
47
47
|
# @example add constructed list to existing graph
|
48
|
-
# l = RDF::List(
|
48
|
+
# l = RDF::List(values: (1, 2, 3))
|
49
49
|
# g = RDF::Graph.new << l
|
50
50
|
# g.count # => l.count
|
51
51
|
#
|
52
|
+
# @example use a transaction for block initialization
|
53
|
+
# l = RDF::List(graph: graph, wrap_transaction: true) do |list|
|
54
|
+
# list << RDF::Literal(1)
|
55
|
+
# # list.graph.rollback will rollback all list changes within this block.
|
56
|
+
# end
|
57
|
+
# list.count #=> 1
|
58
|
+
#
|
52
59
|
# @param [RDF::Resource] subject (RDF.nil)
|
53
60
|
# Subject should be an {RDF::Node}, not a {RDF::URI}. A list with an IRI head will not validate, but is commonly used to detect if a list is valid.
|
54
61
|
# @param [RDF::Graph] graph (RDF::Graph.new)
|
55
62
|
# @param [Array<RDF::Term>] values
|
56
63
|
# Any values which are not terms are coerced to `RDF::Literal`.
|
64
|
+
# @param [Boolean] wrap_transaction (false)
|
65
|
+
# Wraps the callback in a transaction, and replaces the graph with that transaction for the duraction of the callback. This has the effect of allowing any list changes to be made atomically, or rolled back.
|
57
66
|
# @yield [list]
|
58
67
|
# @yieldparam [RDF::List] list
|
59
|
-
def initialize(subject: nil, graph: nil, values: nil, &block)
|
68
|
+
def initialize(subject: nil, graph: nil, values: nil, wrap_transaction: false, &block)
|
60
69
|
@subject = subject || RDF.nil
|
61
70
|
@graph = graph || RDF::Graph.new
|
62
71
|
is_empty = @graph.query({subject: subject, predicate: RDF.first}).empty?
|
@@ -68,8 +77,8 @@ module RDF
|
|
68
77
|
if first || values.length > 0
|
69
78
|
# Intantiate the list from values, and insert the first value using subject.
|
70
79
|
values.reverse_each {|value| self.unshift(value)}
|
71
|
-
graph.insert RDF::Statement(subject, RDF.first, first || RDF.nil)
|
72
|
-
graph.insert RDF::Statement(subject, RDF.rest, @subject)
|
80
|
+
@graph.insert RDF::Statement(subject, RDF.first, first || RDF.nil)
|
81
|
+
@graph.insert RDF::Statement(subject, RDF.rest, @subject)
|
73
82
|
end
|
74
83
|
@subject = subject
|
75
84
|
else
|
@@ -78,9 +87,25 @@ module RDF
|
|
78
87
|
end
|
79
88
|
|
80
89
|
if block_given?
|
81
|
-
|
82
|
-
|
83
|
-
|
90
|
+
if wrap_transaction
|
91
|
+
old_graph = @graph
|
92
|
+
begin
|
93
|
+
Transaction.begin(@graph, graph_name: @graph.graph_name, mutable: @graph.mutable?) do |trans|
|
94
|
+
@graph = trans
|
95
|
+
case block.arity
|
96
|
+
when 1 then block.call(self)
|
97
|
+
else instance_eval(&block)
|
98
|
+
end
|
99
|
+
trans.execute if trans.mutated?
|
100
|
+
end
|
101
|
+
ensure
|
102
|
+
@graph = old_graph
|
103
|
+
end
|
104
|
+
else
|
105
|
+
case block.arity
|
106
|
+
when 1 then block.call(self)
|
107
|
+
else instance_eval(&block)
|
108
|
+
end
|
84
109
|
end
|
85
110
|
end
|
86
111
|
end
|
@@ -175,7 +200,7 @@ module RDF
|
|
175
200
|
# @return [RDF::List]
|
176
201
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-26
|
177
202
|
def &(other)
|
178
|
-
|
203
|
+
self.class.new(values: (to_a & other.to_a))
|
179
204
|
end
|
180
205
|
|
181
206
|
##
|
@@ -193,7 +218,7 @@ module RDF
|
|
193
218
|
# @return [RDF::List]
|
194
219
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-7C
|
195
220
|
def |(other)
|
196
|
-
|
221
|
+
self.class.new(values: (to_a | other.to_a))
|
197
222
|
end
|
198
223
|
|
199
224
|
##
|
@@ -206,7 +231,7 @@ module RDF
|
|
206
231
|
# @return [RDF::List]
|
207
232
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-2B
|
208
233
|
def +(other)
|
209
|
-
|
234
|
+
self.class.new(values: (to_a + other.to_a))
|
210
235
|
end
|
211
236
|
|
212
237
|
##
|
@@ -220,7 +245,7 @@ module RDF
|
|
220
245
|
# @return [RDF::List]
|
221
246
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-2D
|
222
247
|
def -(other)
|
223
|
-
|
248
|
+
self.class.new(values: (to_a - other.to_a))
|
224
249
|
end
|
225
250
|
|
226
251
|
##
|
@@ -250,7 +275,7 @@ module RDF
|
|
250
275
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-2A
|
251
276
|
def *(int_or_str)
|
252
277
|
case int_or_str
|
253
|
-
when Integer then
|
278
|
+
when Integer then self.class.new(values: (to_a * int_or_str))
|
254
279
|
else join(int_or_str.to_s)
|
255
280
|
end
|
256
281
|
end
|
@@ -538,13 +563,13 @@ module RDF
|
|
538
563
|
##
|
539
564
|
# @private
|
540
565
|
def slice_with_start_and_length(start, length)
|
541
|
-
|
566
|
+
self.class.new(values: to_a.slice(start, length))
|
542
567
|
end
|
543
568
|
|
544
569
|
##
|
545
570
|
# @private
|
546
571
|
def slice_with_range(range)
|
547
|
-
|
572
|
+
self.class.new(values: to_a.slice(range))
|
548
573
|
end
|
549
574
|
|
550
575
|
protected :slice_with_start_and_length
|
@@ -851,7 +876,7 @@ module RDF
|
|
851
876
|
# @return [RDF::List]
|
852
877
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-reverse
|
853
878
|
def reverse
|
854
|
-
|
879
|
+
self.class.new(values: to_a.reverse)
|
855
880
|
end
|
856
881
|
|
857
882
|
##
|
@@ -863,7 +888,7 @@ module RDF
|
|
863
888
|
# @return [RDF::List]
|
864
889
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-sort
|
865
890
|
def sort(&block)
|
866
|
-
|
891
|
+
self.class.new(values: super)
|
867
892
|
end
|
868
893
|
|
869
894
|
##
|
@@ -875,7 +900,7 @@ module RDF
|
|
875
900
|
# @return [RDF::List]
|
876
901
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-sort_by
|
877
902
|
def sort_by(&block)
|
878
|
-
|
903
|
+
self.class.new(values: super)
|
879
904
|
end
|
880
905
|
|
881
906
|
##
|
@@ -887,7 +912,7 @@ module RDF
|
|
887
912
|
# @return [RDF::List]
|
888
913
|
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-uniq
|
889
914
|
def uniq
|
890
|
-
|
915
|
+
self.class.new(values: to_a.uniq)
|
891
916
|
end
|
892
917
|
|
893
918
|
##
|
@@ -964,7 +989,7 @@ module RDF
|
|
964
989
|
case value
|
965
990
|
when nil then RDF.nil
|
966
991
|
when RDF::Value then value
|
967
|
-
when Array then
|
992
|
+
when Array then self.class.new(subject: nil, graph: graph, values: value)
|
968
993
|
else value
|
969
994
|
end
|
970
995
|
end
|
data/lib/rdf/model/literal.rb
CHANGED
@@ -25,7 +25,7 @@ module RDF
|
|
25
25
|
#
|
26
26
|
# @example Creating a language-tagged literal (1)
|
27
27
|
# value = RDF::Literal.new("Hello!", language: :en)
|
28
|
-
# value.
|
28
|
+
# value.language? #=> true
|
29
29
|
# value.language #=> :en
|
30
30
|
#
|
31
31
|
# @example Creating a language-tagged literal (2)
|
@@ -35,12 +35,12 @@ module RDF
|
|
35
35
|
#
|
36
36
|
# @example Creating an explicitly datatyped literal
|
37
37
|
# value = RDF::Literal.new("2009-12-31", datatype: RDF::XSD.date)
|
38
|
-
# value.
|
38
|
+
# value.datatype? #=> true
|
39
39
|
# value.datatype #=> RDF::XSD.date
|
40
40
|
#
|
41
41
|
# @example Creating an implicitly datatyped literal
|
42
42
|
# value = RDF::Literal.new(Date.today)
|
43
|
-
# value.
|
43
|
+
# value.datatype? #=> true
|
44
44
|
# value.datatype #=> RDF::XSD.date
|
45
45
|
#
|
46
46
|
# @example Creating implicitly datatyped literals
|
@@ -118,6 +118,7 @@ module RDF
|
|
118
118
|
when ::Integer then RDF::Literal::Integer
|
119
119
|
when ::Float then RDF::Literal::Double
|
120
120
|
when ::BigDecimal then RDF::Literal::Decimal
|
121
|
+
when ::Rational then RDF::Literal::Double
|
121
122
|
when ::DateTime then RDF::Literal::DateTime
|
122
123
|
when ::Time then RDF::Literal::DateTime
|
123
124
|
when ::Date then RDF::Literal::Date
|
@@ -224,7 +225,7 @@ module RDF
|
|
224
225
|
# * The arguments are simple literals or literals typed as xsd:string
|
225
226
|
# * The arguments are plain literals with identical language tags
|
226
227
|
# * The first argument is a plain literal with language tag and the second argument is a simple literal or literal typed as xsd:string
|
227
|
-
|
228
|
+
language? ?
|
228
229
|
(language == other.language || other.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string")) :
|
229
230
|
other.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string")
|
230
231
|
end
|
@@ -288,7 +289,7 @@ module RDF
|
|
288
289
|
case
|
289
290
|
when self.eql?(other)
|
290
291
|
true
|
291
|
-
when self.
|
292
|
+
when self.language? && self.language.to_s == other.language.to_s
|
292
293
|
# Literals with languages can compare if languages are identical
|
293
294
|
self.value_hash == other.value_hash && self.value == other.value
|
294
295
|
when self.simple? && other.simple?
|
@@ -334,10 +335,10 @@ module RDF
|
|
334
335
|
#
|
335
336
|
# @return [Boolean] `true` or `false`
|
336
337
|
# @see http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal
|
337
|
-
def
|
338
|
+
def language?
|
338
339
|
datatype == RDF.langString
|
339
340
|
end
|
340
|
-
alias_method :
|
341
|
+
alias_method :has_language?, :language?
|
341
342
|
|
342
343
|
##
|
343
344
|
# Returns `true` if this is a datatyped literal.
|
@@ -346,12 +347,12 @@ module RDF
|
|
346
347
|
#
|
347
348
|
# @return [Boolean] `true` or `false`
|
348
349
|
# @see http://www.w3.org/TR/rdf-concepts/#dfn-typed-literal
|
349
|
-
def
|
350
|
+
def datatype?
|
350
351
|
!plain? && !language?
|
351
352
|
end
|
352
|
-
alias_method :
|
353
|
-
alias_method :typed?,
|
354
|
-
alias_method :datatyped?,
|
353
|
+
alias_method :has_datatype?, :datatype?
|
354
|
+
alias_method :typed?, :datatype?
|
355
|
+
alias_method :datatyped?, :datatype?
|
355
356
|
|
356
357
|
##
|
357
358
|
# Returns `true` if the value adheres to the defined grammar of the
|
@@ -385,16 +386,16 @@ module RDF
|
|
385
386
|
# This behavior is intuited from SPARQL data-r2/expr-equal/eq-2-2
|
386
387
|
# @return [Boolean]
|
387
388
|
def comperable_datatype?(other)
|
388
|
-
return false unless self.plain? || self.
|
389
|
+
return false unless self.plain? || self.language?
|
389
390
|
|
390
391
|
case other
|
391
392
|
when RDF::Literal::Numeric, RDF::Literal::Boolean,
|
392
393
|
RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime
|
393
394
|
# Invald types can be compared without raising a TypeError if literal has a language (open-eq-08)
|
394
|
-
!other.valid? && self.
|
395
|
+
!other.valid? && self.language?
|
395
396
|
else
|
396
397
|
# An unknown datatype may not be used for comparison, unless it has a language? (open-eq-8)
|
397
|
-
self.
|
398
|
+
self.language?
|
398
399
|
end
|
399
400
|
end
|
400
401
|
|
@@ -51,11 +51,13 @@ module RDF; class Literal
|
|
51
51
|
#
|
52
52
|
# @return [Boolean]
|
53
53
|
# @since 1.1.6
|
54
|
-
def
|
54
|
+
def timezone?
|
55
55
|
md = self.to_s.match(GRAMMAR)
|
56
56
|
md && !!md[2]
|
57
57
|
end
|
58
|
-
alias_method :
|
58
|
+
alias_method :tz?, :timezone?
|
59
|
+
alias_method :has_tz?, :timezone?
|
60
|
+
alias_method :has_timezone?, :timezone?
|
59
61
|
|
60
62
|
##
|
61
63
|
# Returns the value as a string.
|
@@ -72,7 +74,7 @@ module RDF; class Literal
|
|
72
74
|
# @since 1.1.6
|
73
75
|
def humanize(lang = :en)
|
74
76
|
d = object.strftime("%A, %d %B %Y")
|
75
|
-
if
|
77
|
+
if timezone?
|
76
78
|
d += if self.tz == 'Z'
|
77
79
|
" UTC"
|
78
80
|
else
|
@@ -30,7 +30,7 @@ module RDF; class Literal
|
|
30
30
|
# @see http://www.w3.org/TR/xmlschema11-2/#dateTime
|
31
31
|
def canonicalize!
|
32
32
|
if self.valid?
|
33
|
-
@string = if
|
33
|
+
@string = if timezone?
|
34
34
|
@object.new_offset.new_offset.strftime(FORMAT[0..-4] + 'Z').sub('.000', '')
|
35
35
|
else
|
36
36
|
@object.strftime(FORMAT[0..-4]).sub('.000', '')
|
@@ -45,7 +45,7 @@ module RDF; class Literal
|
|
45
45
|
# @return [RDF::Literal]
|
46
46
|
# @see http://www.w3.org/TR/sparql11-query/#func-tz
|
47
47
|
def tz
|
48
|
-
zone =
|
48
|
+
zone = timezone? ? object.zone : ""
|
49
49
|
zone = "Z" if zone == "+00:00"
|
50
50
|
RDF::Literal(zone)
|
51
51
|
end
|
@@ -85,21 +85,25 @@ module RDF; class Literal
|
|
85
85
|
#
|
86
86
|
# @return [Boolean]
|
87
87
|
# @since 1.1.6
|
88
|
-
def
|
88
|
+
def milliseconds?
|
89
89
|
self.format("%L").to_i > 0
|
90
90
|
end
|
91
|
-
alias_method :
|
91
|
+
alias_method :has_milliseconds?, :milliseconds?
|
92
|
+
alias_method :has_ms?, :milliseconds?
|
93
|
+
alias_method :ms?, :milliseconds?
|
92
94
|
|
93
95
|
##
|
94
96
|
# Does the literal representation include a timezone? Note that this is only possible if initialized using a string, or `:lexical` option.
|
95
97
|
#
|
96
98
|
# @return [Boolean]
|
97
99
|
# @since 1.1.6
|
98
|
-
def
|
100
|
+
def timezone?
|
99
101
|
md = self.to_s.match(GRAMMAR)
|
100
102
|
md && !!md[2]
|
101
103
|
end
|
102
|
-
alias_method :
|
104
|
+
alias_method :tz?, :timezone?
|
105
|
+
alias_method :has_tz?, :timezone?
|
106
|
+
alias_method :has_timezone?, :timezone?
|
103
107
|
|
104
108
|
##
|
105
109
|
# Returns the `timezone` of the literal. If the
|
@@ -118,7 +122,7 @@ module RDF; class Literal
|
|
118
122
|
# @since 1.1.6
|
119
123
|
def humanize(lang = :en)
|
120
124
|
d = object.strftime("%r on %A, %d %B %Y")
|
121
|
-
if
|
125
|
+
if timezone?
|
122
126
|
zone = if self.tz == 'Z'
|
123
127
|
"UTC"
|
124
128
|
else
|
@@ -63,9 +63,15 @@ module RDF; class Literal
|
|
63
63
|
##
|
64
64
|
# Returns the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned. An error is raised if arg is not a numeric value.
|
65
65
|
#
|
66
|
-
# @return [RDF::Literal]
|
66
|
+
# @return [RDF::Literal::Decimal]
|
67
67
|
def round
|
68
|
-
|
68
|
+
rounded = to_d.round(half: (to_d < 0 ? :down : :up))
|
69
|
+
if rounded == -0.0
|
70
|
+
# to avoid -0.0
|
71
|
+
self.class.new(0.0)
|
72
|
+
else
|
73
|
+
self.class.new(rounded)
|
74
|
+
end
|
69
75
|
end
|
70
76
|
|
71
77
|
##
|
@@ -74,9 +80,9 @@ module RDF; class Literal
|
|
74
80
|
# @example
|
75
81
|
# RDF::Literal(1).ceil #=> RDF::Literal(1)
|
76
82
|
#
|
77
|
-
# @return [RDF::Literal]
|
83
|
+
# @return [RDF::Literal::Integer]
|
78
84
|
def ceil
|
79
|
-
|
85
|
+
RDF::Literal::Integer.new(to_d.ceil)
|
80
86
|
end
|
81
87
|
|
82
88
|
##
|
@@ -85,9 +91,9 @@ module RDF; class Literal
|
|
85
91
|
# @example
|
86
92
|
# RDF::Literal(1).floor #=> RDF::Literal(1)
|
87
93
|
#
|
88
|
-
# @return [RDF::Literal]
|
94
|
+
# @return [RDF::Literal::Integer]
|
89
95
|
def floor
|
90
|
-
|
96
|
+
RDF::Literal::Integer.new(to_d.floor)
|
91
97
|
end
|
92
98
|
|
93
99
|
##
|
@@ -142,7 +142,7 @@ module RDF; class Literal
|
|
142
142
|
end
|
143
143
|
|
144
144
|
##
|
145
|
-
# Returns the smallest
|
145
|
+
# Returns the smallest integer greater than or equal to `self`.
|
146
146
|
#
|
147
147
|
# @example
|
148
148
|
# RDF::Literal(1.2).ceil #=> RDF::Literal(2)
|
@@ -150,14 +150,14 @@ module RDF; class Literal
|
|
150
150
|
# RDF::Literal(2.0).ceil #=> RDF::Literal(2)
|
151
151
|
# RDF::Literal(-2.0).ceil #=> RDF::Literal(-2)
|
152
152
|
#
|
153
|
-
# @return [RDF::Literal]
|
153
|
+
# @return [RDF::Literal::Integer]
|
154
154
|
# @since 0.2.3
|
155
155
|
def ceil
|
156
|
-
|
156
|
+
RDF::Literal::Integer.new(to_f.ceil)
|
157
157
|
end
|
158
158
|
|
159
159
|
##
|
160
|
-
# Returns the largest
|
160
|
+
# Returns the largest integer less than or equal to `self`.
|
161
161
|
#
|
162
162
|
# @example
|
163
163
|
# RDF::Literal(1.2).floor #=> RDF::Literal(1)
|
@@ -165,10 +165,10 @@ module RDF; class Literal
|
|
165
165
|
# RDF::Literal(2.0).floor #=> RDF::Literal(2)
|
166
166
|
# RDF::Literal(-2.0).floor #=> RDF::Literal(-2)
|
167
167
|
#
|
168
|
-
# @return [RDF::Literal]
|
168
|
+
# @return [RDF::Literal::Integer]
|
169
169
|
# @since 0.2.3
|
170
170
|
def floor
|
171
|
-
|
171
|
+
RDF::Literal::Integer.new(to_f.floor)
|
172
172
|
end
|
173
173
|
|
174
174
|
##
|
@@ -183,9 +183,9 @@ module RDF; class Literal
|
|
183
183
|
##
|
184
184
|
# Returns the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned. An error is raised if arg is not a numeric value.
|
185
185
|
#
|
186
|
-
# @return [RDF::Literal]
|
186
|
+
# @return [RDF::Literal::Double]
|
187
187
|
def round
|
188
|
-
self.class.new(
|
188
|
+
self.class.new(to_d.round(half: (to_d < 0 ? :down : :up)))
|
189
189
|
end
|
190
190
|
|
191
191
|
##
|
@@ -123,6 +123,40 @@ module RDF; class Literal
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
##
|
127
|
+
# Exponent − Performs exponential (power) calculation on operators.
|
128
|
+
#
|
129
|
+
# Promotes values, as necessary, with the result type depending on the input values.
|
130
|
+
#
|
131
|
+
# @param [Literal::Numeric, #to_i, #to_f, #to_d] other
|
132
|
+
# @return [RDF::Literal::Numeric]
|
133
|
+
# @since 0.2.3
|
134
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-math-pow
|
135
|
+
def **(other)
|
136
|
+
RDF::Literal(object ** (other.is_a?(RDF::Literal::Numeric) ? other.object : other))
|
137
|
+
rescue ZeroDivisionError
|
138
|
+
RDF::Literal::Double.new('INF')
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# Exponent − Performs remainder of `self` divided by `other`.
|
143
|
+
#
|
144
|
+
# @param [Literal::Numeric, #to_i, #to_f, #to_d] other
|
145
|
+
# @return [RDF::Literal]
|
146
|
+
# @since 0.2.3
|
147
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-numeric-mod
|
148
|
+
def %(other)
|
149
|
+
if self.class == Double || [Double, ::Float].include?(other.class)
|
150
|
+
self.class.new(to_f % other.to_f)
|
151
|
+
elsif ((self.class == RDF::Literal::Float || other.class == RDF::Literal::Float) rescue false)
|
152
|
+
self.class.new(to_f % other.to_f)
|
153
|
+
elsif self.class == Decimal || other.class == Decimal
|
154
|
+
self.class.new(to_d % (other.respond_to?(:to_d) ? other.to_d : BigDecimal(other.to_s)))
|
155
|
+
else
|
156
|
+
self.class.new(to_i % other.to_i)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
126
160
|
##
|
127
161
|
# Returns the quotient of `self` divided by `other`.
|
128
162
|
#
|