rdf 3.1.11 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb4903dd836362f2ba5883f4af56b2276d879e60c0be2b740fcfd946c2b9bc29
4
- data.tar.gz: e0abcd40f798fa08955649dda90a53f10e775d74d95f4fbbb7680cb8223594a8
3
+ metadata.gz: deb163eb0095fba5da13f3f9a03a8543cb244e4525a495f2585d49c98e72fffc
4
+ data.tar.gz: e146b2eeaf881c53cf4291362698440febbb6f45fb793c3369fc374a8909c97d
5
5
  SHA512:
6
- metadata.gz: fa91bd5cc0daa34b2055bf0504dd05a67ad433320d316247eee7ecc7e34c4b26a60be3dd944f2b480a3282b6f1175b4af03a740a6697d5a1848e14279093d025
7
- data.tar.gz: b30eea12865c58960d3ee942ff89e6e0cfb1b5bc3d1cc66187356709c389450c03e1d397715c4a807902deacfd10916a1db7c054f03ed289253986b42fefc0e3
6
+ metadata.gz: 568557c3d23702f3fb8f842d8b64a19f116403c1d21a1da6164b6ce83a8d8297556ac5d74e508916d9be6ff215de777d553591760db9ab79479d161e89a3d6a8
7
+ data.tar.gz: 7d90c6165c87710add8ed7b9359fdd38b617b1efac9c928885b88c78769d0b0a7a1898418b6a9c3d2d6e97a9eb7de61ae48047b9053e430eeb053b3ee5a75968
data/README.md CHANGED
@@ -398,16 +398,16 @@ from BNode identity (i.e., they each entail the other)
398
398
 
399
399
  ## Dependencies
400
400
 
401
- * [Ruby](https://ruby-lang.org/) (>= 2.2)
401
+ * [Ruby](https://ruby-lang.org/) (>= 2.6)
402
402
  * [LinkHeader][] (>= 0.0.8)
403
- * Soft dependency on [RestClient][] (>= 1.7)
403
+ * Soft dependency on [RestClient][] (>= 2.1)
404
404
 
405
405
  ## Installation
406
406
 
407
407
  The recommended installation method is via [RubyGems](https://rubygems.org/).
408
408
  To install the latest official release of RDF.rb, do:
409
409
 
410
- % [sudo] gem install rdf # Ruby 2+
410
+ % [sudo] gem install rdf # Ruby 2.6+
411
411
 
412
412
  ## Download
413
413
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.11
1
+ 3.2.1
data/lib/rdf/cli.rb CHANGED
@@ -256,8 +256,7 @@ module RDF
256
256
  lambda: ->(argv, opts) do
257
257
  writer_class = RDF::Writer.for(opts[:output_format]) || RDF::NTriples::Writer
258
258
  out = opts[:output]
259
- opts = opts.merge(prefixes: {})
260
- writer_opts = opts.merge(standard_prefixes: true)
259
+ writer_opts = {prefixes: {}, standard_prefixes: true}.merge(opts)
261
260
  writer_class.new(out, **writer_opts) do |writer|
262
261
  writer << repository
263
262
  end
@@ -536,6 +535,8 @@ module RDF
536
535
  count = 0
537
536
  self.parse(args, **options) do |reader|
538
537
  reader.each_statement {|st| @repository << st}
538
+ # Remember prefixes from reading
539
+ options[:prefixes] ||= reader.prefixes
539
540
  end
540
541
  secs = Time.new - start
541
542
  options[:logger].info "Parsed #{repository.count} statements with #{@readers.join(', ')} in #{secs} seconds @ #{count/secs} statements/second."
@@ -136,8 +136,13 @@ module RDF
136
136
  #
137
137
  # @param [RDF::Statement] statement
138
138
  # @return [Boolean]
139
- def statement?(statement = nil)
140
- statement && !enum_statement.find { |s| s.eql?(statement) }.nil?
139
+ def statement?(*args)
140
+ case args.length
141
+ when 0 then false
142
+ when 1
143
+ args.first && !enum_statement.find { |s| s.eql?(args.first) }.nil?
144
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
145
+ end
141
146
  end
142
147
  alias_method :has_statement?, :statement?
143
148
  alias_method :include?, :statement?
@@ -541,8 +546,12 @@ module RDF
541
546
  # @param [RDF::Resource] value
542
547
  # @return [Boolean]
543
548
  # @since 2.0
544
- def term?(value = nil)
545
- value && enum_term.include?(value)
549
+ def term?(*args)
550
+ case args.length
551
+ when 0 then super
552
+ when 1 then args.first && enum_term.include?(args.first)
553
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
554
+ end
546
555
  end
547
556
  alias_method :has_term?, :term?
548
557
 
@@ -138,11 +138,22 @@ module RDF
138
138
  end
139
139
 
140
140
  ##
141
- # Returns `true` to indicate that this is a graph.
141
+ # @overload graph?
142
+ # Returns `true` to indicate that this is a graph.
142
143
  #
143
- # @return [Boolean]
144
- def graph?
145
- true
144
+ # @return [Boolean]
145
+ # @overload graph?(name)
146
+ # Returns `true` if `self` contains the given RDF graph_name.
147
+ #
148
+ # @param [RDF::Resource, false] graph_name
149
+ # Use value `false` to query for the default graph_name
150
+ # @return [Boolean]
151
+ def graph?(*args)
152
+ case args.length
153
+ when 0 then true
154
+ when 1 then graph_name == args.first
155
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
156
+ end
146
157
  end
147
158
 
148
159
  ##
@@ -227,11 +238,15 @@ module RDF
227
238
  # @param [Statement] statement
228
239
  # @return [Boolean]
229
240
  # @see RDF::Enumerable#statement?
230
- def statement?(statement = nil)
231
- return false if statement.nil?
232
- statement = statement.dup
233
- statement.graph_name = graph_name
234
- @data.statement?(statement)
241
+ def statement?(*args)
242
+ case args.length
243
+ when 0 then false
244
+ when 1
245
+ statement = args.first.dup
246
+ statement.graph_name = graph_name
247
+ @data.statement?(statement)
248
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
249
+ end
235
250
  end
236
251
  alias_method :has_statement?, :statement?
237
252
 
@@ -43,6 +43,7 @@ module RDF; class Literal
43
43
  # Can't use simple %f transformation due to special requirements from
44
44
  # N3 tests in representation
45
45
  @string = case
46
+ when @object.nil? then 'NaN'
46
47
  when @object.nan? then 'NaN'
47
48
  when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
48
49
  when @object.zero? then '0.0E0'
@@ -11,6 +11,9 @@ module RDF; class Literal
11
11
  # @return [Integer] `-1`, `0`, or `1`
12
12
  # @since 0.3.0
13
13
  def <=>(other)
14
+ # If lexically invalid, use regular literal testing
15
+ return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)
16
+
14
17
  case other
15
18
  when ::Numeric
16
19
  to_d <=> other
@@ -30,11 +33,10 @@ module RDF; class Literal
30
33
  # @since 0.3.0
31
34
  def ==(other)
32
35
  # If lexically invalid, use regular literal testing
33
- return super unless self.valid?
36
+ return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)
34
37
 
35
38
  case other
36
39
  when Literal::Numeric
37
- return super unless other.valid?
38
40
  (cmp = (self <=> other)) ? cmp.zero? : false
39
41
  when RDF::URI, RDF::Node
40
42
  # Interpreting SPARQL data-r2/expr-equal/eq-2-2, numeric can't be compared with other types
@@ -166,12 +166,12 @@ module RDF
166
166
  @object = value.freeze
167
167
  @string = lexical if lexical
168
168
  @string = value if !defined?(@string) && value.is_a?(String)
169
- @string = @string.encode(Encoding::UTF_8).freeze if @string
170
- @object = @string if @string && @object.is_a?(String)
169
+ @string = @string.encode(Encoding::UTF_8).freeze if instance_variable_defined?(:@string)
170
+ @object = @string if instance_variable_defined?(:@string) && @object.is_a?(String)
171
171
  @language = language.to_s.downcase.to_sym if language
172
172
  @datatype = RDF::URI(datatype).freeze if datatype
173
173
  @datatype ||= self.class.const_get(:DATATYPE) if self.class.const_defined?(:DATATYPE)
174
- @datatype ||= @language ? RDF.langString : RDF::URI("http://www.w3.org/2001/XMLSchema#string")
174
+ @datatype ||= instance_variable_defined?(:@language) && @language ? RDF.langString : RDF::URI("http://www.w3.org/2001/XMLSchema#string")
175
175
  end
176
176
 
177
177
  ##
@@ -179,7 +179,7 @@ module RDF
179
179
  #
180
180
  # @return [String]
181
181
  def value
182
- @string || to_s
182
+ instance_variable_defined?(:@string) && @string || to_s
183
183
  end
184
184
 
185
185
  ##
@@ -308,6 +308,37 @@ module RDF
308
308
  end
309
309
  alias_method :===, :==
310
310
 
311
+ ##
312
+ # Compares `self` to `other` for sorting purposes (with type check).
313
+ #
314
+ # @param [Object] other
315
+ # @return [Integer] `-1`, `0`, or `1`
316
+ def <=>(other)
317
+ case other
318
+ when Literal
319
+ case
320
+ when self.eql?(other)
321
+ 0
322
+ when self.language? && other.language?
323
+ # Literals with languages can compare if languages are identical
324
+ self.to_s <=> other.to_s
325
+ when self.simple? && other.simple?
326
+ self.to_s <=> other.to_s
327
+ when !self.valid?
328
+ type_error("#{self.inspect} is invalid") || 0
329
+ when !other.valid?
330
+ type_error("#{other.inspect} is invalid") || 0
331
+ when self.comperable_datatype2?(other)
332
+ self.object <=> other.object
333
+ else
334
+ type_error("#{self.inspect} and #{other.inspect} are not comperable") || 0
335
+ end
336
+ when String
337
+ self.simple? && self.value <=> other
338
+ else 1
339
+ end
340
+ end
341
+
311
342
  ##
312
343
  # Returns `true` if this is a plain literal. A plain literal
313
344
  # may have a language, but may not have a datatype. For
@@ -399,6 +430,26 @@ module RDF
399
430
  end
400
431
  end
401
432
 
433
+ ##
434
+ # Returns `true` if the literals are comperable.
435
+ #
436
+ # Used for <=> operator.
437
+ #
438
+ # @return [Boolean]
439
+ def comperable_datatype2?(other)
440
+ case self
441
+ when RDF::Literal::Numeric, RDF::Literal::Boolean
442
+ case other
443
+ when RDF::Literal::Numeric, RDF::Literal::Boolean
444
+ true
445
+ else
446
+ false
447
+ end
448
+ else
449
+ self.datatype == other.datatype
450
+ end
451
+ end
452
+
402
453
  ##
403
454
  # Converts this literal into its canonical lexical representation.
404
455
  #
@@ -136,23 +136,45 @@ module RDF
136
136
  end
137
137
 
138
138
  ##
139
- # Returns `true` to indicate that this value is a statement.
139
+ # @overload statement?
140
+ # Returns `true` if `self` is a {RDF::Statement}.
140
141
  #
141
- # @return [Boolean]
142
- def statement?
143
- true
142
+ # @return [Boolean]
143
+ # @overload statement?(statement)
144
+ # Returns `true` if `self` contains the given {RDF::Statement}.
145
+ #
146
+ # @param [RDF::Statement] statement
147
+ # @return [Boolean]
148
+ def statement?(*args)
149
+ case args.length
150
+ when 0 then true
151
+ when 1 then self == args.first || subject.statement?(*args) || object.statement?(*args)
152
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
153
+ end
144
154
  end
145
155
 
146
156
  ##
147
- # Returns `true` if any element of the statement is not a
157
+ # @overload variable?
158
+ # Returns `true` if any element of the statement is not a
148
159
  # URI, Node or Literal.
149
160
  #
150
- # @return [Boolean]
151
- def variable?
152
- !(subject? && subject.constant? &&
153
- predicate? && predicate.constant? &&
154
- object? && object.constant? &&
155
- (graph? ? graph_name.constant? : true))
161
+ # @return [Boolean]
162
+ # @overload variable?(variables)
163
+ # Returns `true` if this statement contains any of the variables.
164
+ #
165
+ # @param [Array<Symbol, #to_sym>] variables
166
+ # @return [Boolean]
167
+ def variable?(*args)
168
+ case args.length
169
+ when 0
170
+ !(subject? && subject.constant? &&
171
+ predicate? && predicate.constant? &&
172
+ object? && object.constant? &&
173
+ (graph? ? graph_name.constant? : true))
174
+ when 1
175
+ to_quad.any? {|t| t.respond_to?(:variable?) && t.variable?(*args)}
176
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
177
+ end
156
178
  end
157
179
 
158
180
  ##
@@ -215,9 +237,22 @@ module RDF
215
237
  end
216
238
 
217
239
  ##
218
- # @return [Boolean]
219
- def graph?
220
- !!graph_name
240
+ # @overload graph?
241
+ # Returns `true` if the statement has a graph name.
242
+ #
243
+ # @return [Boolean]
244
+ # @overload graph?(name)
245
+ # Returns `true` if `self` contains the given RDF graph_name.
246
+ #
247
+ # @param [RDF::Resource, false] graph_name
248
+ # Use value `false` to query for the default graph_name
249
+ # @return [Boolean]
250
+ def graph?(*args)
251
+ case args.length
252
+ when 0 then !!graph_name
253
+ when 1 then graph_name == args.first
254
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
255
+ end
221
256
  end
222
257
  alias_method :name?, :graph?
223
258
  alias_method :has_graph?, :graph?
@@ -266,7 +301,7 @@ module RDF
266
301
  # @see RDF::Literal#==
267
302
  # @see RDF::Query::Variable#==
268
303
  def eql?(other)
269
- other.is_a?(Statement) && self == other && (self.graph_name || false) == (other.graph_name || false)
304
+ other.is_a?(Statement) && self.to_a.eql?(other.to_a) && (self.graph_name || false) == (other.graph_name || false)
270
305
  end
271
306
 
272
307
  ##
@@ -57,11 +57,21 @@ module RDF
57
57
  end
58
58
 
59
59
  ##
60
- # Returns `true` if `self` is a {RDF::Term}.
60
+ # @overload term?
61
+ # Returns `true` if `self` is a {RDF::Term}.
61
62
  #
62
- # @return [Boolean]
63
- def term?
64
- true
63
+ # @return [Boolean]
64
+ # @overload term?(name)
65
+ # Returns `true` if `self` contains the given RDF subject term.
66
+ #
67
+ # @param [RDF::Resource] value
68
+ # @return [Boolean]
69
+ def term?(*args)
70
+ case args.length
71
+ when 0 then true
72
+ when 1 then false
73
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
74
+ end
65
75
  end
66
76
 
67
77
  ##
data/lib/rdf/model/uri.rb CHANGED
@@ -621,16 +621,22 @@ module RDF
621
621
  end
622
622
 
623
623
  ##
624
- # Returns a qualified name (QName) for this URI based on available vocabularies, if possible.
624
+ # Returns a qualified name (QName) as a tuple of `[prefix, suffix]` for this URI based on available vocabularies, if possible.
625
625
  #
626
626
  # @example
627
627
  # RDF::URI('http://www.w3.org/2000/01/rdf-schema#').qname #=> [:rdfs, nil]
628
628
  # RDF::URI('http://www.w3.org/2000/01/rdf-schema#label').qname #=> [:rdfs, :label]
629
629
  # RDF::RDFS.label.qname #=> [:rdfs, :label]
630
630
  #
631
+ # @param [Hash{Symbol => String}] prefixes
632
+ # Explicit set of prefixes to look for matches, defaults to loaded vocabularies.
631
633
  # @return [Array(Symbol, Symbol)] or `nil` if no QName found
632
- def qname
633
- if self.to_s =~ %r([:/#]([^:/#]*)$)
634
+ def qname(prefixes: nil)
635
+ if prefixes
636
+ prefixes.each do |prefix, uri|
637
+ return [prefix, self.to_s[uri.length..-1].to_sym] if self.start_with?(uri)
638
+ end
639
+ elsif self.to_s =~ %r([:/#]([^:/#]*)$)
634
640
  local_name = $1
635
641
  vocab_uri = local_name.empty? ? self.to_s : self.to_s[0...-(local_name.length)]
636
642
  Vocabulary.each do |vocab|
@@ -655,9 +661,11 @@ module RDF
655
661
  ##
656
662
  # Returns a string version of the QName or the full IRI
657
663
  #
664
+ # @param [Hash{Symbol => String}] prefixes
665
+ # Explicit set of prefixes to look for matches, defaults to loaded vocabularies.
658
666
  # @return [String] or `nil`
659
- def pname
660
- (q = self.qname) ? q.join(":") : to_s
667
+ def pname(prefixes: nil)
668
+ (q = self.qname(prefixes: prefixes)) ? q.join(":") : to_s
661
669
  end
662
670
 
663
671
  ##
@@ -29,19 +29,38 @@ module RDF
29
29
  # @see RDF::Statement
30
30
  module Value
31
31
  ##
32
- # Returns `true` if `self` is a {RDF::Graph}.
32
+ # @overload graph?
33
+ # Returns `true` if `self` is a {RDF::Graph}.
33
34
  #
34
- # @return [Boolean]
35
- def graph?
36
- false
35
+ # @return [Boolean]
36
+ # @overload graph?(name)
37
+ # Returns `true` if `self` contains the given RDF graph_name.
38
+ #
39
+ # @param [RDF::Resource, false] graph_name
40
+ # Use value `false` to query for the default graph_name
41
+ # @return [Boolean]
42
+ def graph?(*args)
43
+ case args.length
44
+ when 0, 1 then false
45
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
46
+ end
37
47
  end
38
48
 
39
49
  ##
40
- # Is this a {RDF::Statement}?
50
+ # @overload statement?
51
+ # Returns `true` if `self` is a {RDF::Statement}.
41
52
  #
42
- # @return [Boolean]
43
- def statement?
44
- false
53
+ # @return [Boolean]
54
+ # @overload statement?(statement)
55
+ # Returns `true` if `self` contains the given {RDF::Statement}.
56
+ #
57
+ # @param [RDF::Statement] statement
58
+ # @return [Boolean]
59
+ def statement?(*args)
60
+ case args.length
61
+ when 0, 1 then false
62
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
63
+ end
45
64
  end
46
65
 
47
66
  ##
@@ -53,11 +72,20 @@ module RDF
53
72
  end
54
73
 
55
74
  ##
56
- # Is this a {RDF::Term}?
75
+ # @overload term?
76
+ # Returns `true` if `self` is a {RDF::Term}.
57
77
  #
58
- # @return [Boolean]
59
- def term?
60
- false
78
+ # @return [Boolean]
79
+ # @overload term?(name)
80
+ # Returns `true` if `self` contains the given RDF subject term.
81
+ #
82
+ # @param [RDF::Resource] value
83
+ # @return [Boolean]
84
+ def term?(*args)
85
+ case args.length
86
+ when 0, 1 then false
87
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
88
+ end
61
89
  end
62
90
 
63
91
  ##
@@ -103,12 +131,21 @@ module RDF
103
131
  end
104
132
 
105
133
  ##
106
- # Is this a {RDF::Query::Variable}, or does it contain a variable?
134
+ # @overload variable?
135
+ # Returns `true` if `self` is a {RDF::Query::Variable}, or does it contain a variable?
107
136
  #
108
- # @return [Boolean]
137
+ # @return [Boolean]
138
+ # @overload variable?(variable)
139
+ # Returns `true` if `self` contains the given variable.
140
+ #
141
+ # @param [RDF::Resource] value
142
+ # @return [Boolean]
109
143
  # @since 0.1.7
110
- def variable?
111
- false
144
+ def variable?(*args)
145
+ case args.length
146
+ when 0, 1 then false
147
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
148
+ end
112
149
  end
113
150
 
114
151
  ##
data/lib/rdf/nquads.rb CHANGED
@@ -69,9 +69,9 @@ module RDF
69
69
 
70
70
  begin
71
71
  unless blank? || read_comment
72
- subject = read_uriref || read_node || read_embTriple || fail_subject
72
+ subject = read_uriref || read_node || read_quotedTriple || fail_subject
73
73
  predicate = read_uriref(intern: true) || fail_predicate
74
- object = read_uriref || read_node || read_literal || read_embTriple || fail_object
74
+ object = read_uriref || read_node || read_literal || read_quotedTriple || fail_object
75
75
  graph_name = read_uriref || read_node
76
76
  if validate? && !read_eos
77
77
  log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
@@ -213,7 +213,7 @@ module RDF::NTriples
213
213
  begin
214
214
  read_statement
215
215
  rescue RDF::ReaderError
216
- value = read_uriref || read_node || read_literal || read_embTriple
216
+ value = read_uriref || read_node || read_literal || read_quotedTriple
217
217
  log_recover
218
218
  value
219
219
  end
@@ -229,9 +229,9 @@ module RDF::NTriples
229
229
 
230
230
  begin
231
231
  unless blank? || read_comment
232
- subject = read_uriref || read_node || read_embTriple || fail_subject
232
+ subject = read_uriref || read_node || read_quotedTriple || fail_subject
233
233
  predicate = read_uriref(intern: true) || fail_predicate
234
- object = read_uriref || read_node || read_literal || read_embTriple || fail_object
234
+ object = read_uriref || read_node || read_literal || read_quotedTriple || fail_object
235
235
 
236
236
  if validate? && !read_eos
237
237
  log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
@@ -247,11 +247,11 @@ module RDF::NTriples
247
247
 
248
248
  ##
249
249
  # @return [RDF::Statement]
250
- def read_embTriple
250
+ def read_quotedTriple
251
251
  if @options[:rdfstar] && match(ST_START)
252
- subject = read_uriref || read_node || read_embTriple || fail_subject
252
+ subject = read_uriref || read_node || read_quotedTriple || fail_subject
253
253
  predicate = read_uriref(intern: true) || fail_predicate
254
- object = read_uriref || read_node || read_literal || read_embTriple || fail_object
254
+ object = read_uriref || read_node || read_literal || read_quotedTriple || fail_object
255
255
  if !match(ST_END)
256
256
  log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
257
257
  end
@@ -227,7 +227,7 @@ module RDF::NTriples
227
227
  # @param [RDF::Statement] statement
228
228
  # @param [Hash{Symbol => Object}] options ({})
229
229
  # @return [String]
230
- def format_embTriple(statement, **options)
230
+ def format_quotedTriple(statement, **options)
231
231
  "<<%s %s %s>>" % statement.to_a.map { |value| format_term(value, **options) }
232
232
  end
233
233
  ##
@@ -59,6 +59,12 @@ module RDF; class Query
59
59
  super
60
60
  end
61
61
 
62
+ ##
63
+ # Create a new pattern from the quads, recursivly dupping sub-patterns.
64
+ def dup
65
+ self.class.from(self.to_quad.map {|t| t.is_a?(RDF::Query::Pattern) ? t.dup : t})
66
+ end
67
+
62
68
  ##
63
69
  # Any additional options for this pattern.
64
70
  #
@@ -23,10 +23,13 @@ class RDF::Query
23
23
  class Solution
24
24
  # Undefine all superfluous instance methods:
25
25
  alias_method :__send, :send
26
+
27
+ # Temporarily remember instance method for deprecation message in `method_missing`.
28
+ INSTANCE_METHODS = instance_methods
26
29
  undef_method(*instance_methods.
27
30
  map(&:to_s).
28
31
  select {|m| m.match?(/^\w+$/)}.
29
- reject {|m| %w(object_id dup instance_eval inspect to_s private_methods class should should_not pretty_print).include?(m) || m[0,2] == '__'}.
32
+ reject {|m| %w(object_id dup instance_eval inspect to_s private_methods public_methods class method pretty_print).include?(m) || m[0,2] == '__'}.
30
33
  map(&:to_sym))
31
34
 
32
35
  include Enumerable
@@ -114,15 +117,24 @@ class RDF::Query
114
117
  end
115
118
 
116
119
  ##
117
- # Returns `true` if this solution contains bindings for any of the given
120
+ # @overload variable?
121
+ # Returns `false`.
122
+ #
123
+ # @return [Boolean]
124
+ # @overload variable?(variables)
125
+ # Returns `true` if this solution contains bindings for any of the given
118
126
  # `variables`.
119
127
  #
120
- # @param [Array<Symbol, #to_sym>] variables
121
- # an array of variables to check
122
- # @return [Boolean] `true` or `false`
128
+ # @param [Array<Symbol, #to_sym>] variables
129
+ # @return [Boolean]
123
130
  # @since 0.3.0
124
- def variable?(variables)
125
- variables.any? { |variable| bound?(variable) }
131
+ def variable?(*args)
132
+ case args.length
133
+ when 0 then false
134
+ when 1
135
+ args.first.any? { |variable| bound?(variable) }
136
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
137
+ end
126
138
  end
127
139
  alias_method :variables?, :variable?
128
140
  alias_method :has_variables?, :variable?
@@ -335,6 +347,12 @@ class RDF::Query
335
347
  # @return [RDF::Term]
336
348
  def method_missing(name, *args, &block)
337
349
  if args.empty? && @bindings.key?(name.to_sym)
350
+ if INSTANCE_METHODS.include?(name)
351
+ warn "[DEPRECATION] RDF::Query::Solution##{name} is an overridden instance method.\n" +
352
+ "Its use as a solution accessor is deprecated and will be removed in a future version.\n" +
353
+ "Use #[] for safe access.\n" +
354
+ "Called from #{Gem.location_of_caller.join(':')}"
355
+ end
338
356
  @bindings[name.to_sym]
339
357
  else
340
358
  super # raises NoMethodError