rdf 3.1.15 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,14 @@ module RDF
5
5
  # A {Vocabulary} can also serve as a Domain Specific Language (DSL) for generating an RDF Graph definition for the vocabulary (see {RDF::Vocabulary#to_enum}).
6
6
  #
7
7
  # ### Defining a vocabulary using the DSL
8
- # Vocabularies can be defined based on {RDF::Vocabulary} or {RDF::StrictVocabulary} using a simple Domain Specific Language (DSL). Terms of the vocabulary are specified using either `property` or `term` (alias), with the attributes of the term listed in a hash. See {property} for description of the hash.
8
+ # Vocabularies can be defined based on {RDF::Vocabulary} or {RDF::StrictVocabulary} using a simple Domain Specific Language (DSL).
9
+ #
10
+ # * Ontology information for the vocabulary itself can be specified using the {ontology} method.
11
+ # * Terms of the vocabulary are specified using either `property` or `term` (alias), with the attributes of the term listed in a hash. See {property} for description of the hash. Term attributes become properties of the associated {RDF::Vocabulary::Term} (see {RDF::Vocabulary::Term#attributes}).
12
+ #
13
+ # Note that, by default, the prefix associated with the vocabulary for forming and interpreting PNames is created from the class name of the vocabulary. See {\_\_prefix\_\_=} for overriding this at runtime.
14
+ #
15
+ # The simplest way to generate a DSL representation of a vocabulary is using {RDF::Vocabulary::Writer} given an {RDF::Graph} representation of the vocabulary.
9
16
  #
10
17
  # ### Vocabularies:
11
18
  #
@@ -31,6 +38,31 @@ module RDF
31
38
  # foaf.knows #=> RDF::URI("http://xmlns.com/foaf/0.1/knows")
32
39
  # foaf[:name] #=> RDF::URI("http://xmlns.com/foaf/0.1/name")
33
40
  # foaf['mbox'] #=> RDF::URI("http://xmlns.com/foaf/0.1/mbox")
41
+ #
42
+ # @example Defining a simple vocabulary
43
+ # EX = Class.new(RDF::StrictVocabulay("http://example/ns#")) do
44
+ # # Ontology definition
45
+ # ontology :"http://example/ns#",
46
+ # label: "The RDF Example Vocablary",
47
+ # type: "http://www.w3.org/2002/07/owl#Ontology"
48
+ #
49
+ # # Class definitions
50
+ # term :Class,
51
+ # label: "My Class",
52
+ # comment: "Good to use as an example",
53
+ # type: "rdfs:Class",
54
+ # subClassOf: "http://example/SuperClass",
55
+ # "ex:prop": "Some annotation property not having a shortcut"
56
+ #
57
+ # # Property definitions
58
+ # property :prop,
59
+ # comment: "A description of the property",
60
+ # label: "property",
61
+ # domain: "http://example/ns#Class",
62
+ # range: "rdfs:Literal",
63
+ # isDefinedBy: %(ex:),
64
+ # type: "rdf:Property"
65
+ # end
34
66
  #
35
67
  # @example Method calls are converted to the typical RDF camelcase convention
36
68
  # foaf = RDF::Vocabulary.new("http://xmlns.com/foaf/0.1/")
@@ -44,17 +76,7 @@ module RDF
44
76
  # graph = RDF::Graph.new << RDF::RDFS.to_enum
45
77
  # graph.dump(:ntriples)
46
78
  #
47
- # @example Defining a simple vocabulary
48
- # class EX < RDF::StrictVocabulay("http://example/ns#")
49
- # term :Class,
50
- # label: "My Class",
51
- # comment: "Good to use as an example",
52
- # "rdf:type" => "rdfs:Class",
53
- # "rdfs:subClassOf" => "http://example/SuperClass"
54
- # end
55
- #
56
- # @see http://www.w3.org/TR/curie/
57
- # @see http://en.wikipedia.org/wiki/QName
79
+ # @see https://www.w3.org/TR/rdf-sparql-query/#prefNames
58
80
  class Vocabulary
59
81
  extend ::Enumerable
60
82
 
@@ -70,7 +92,7 @@ module RDF
70
92
  # @return [Enumerator]
71
93
  def each(&block)
72
94
  if self.equal?(Vocabulary)
73
- if @vocabs
95
+ if instance_variable_defined?(:@vocabs) && @vocabs
74
96
  @vocabs.select(&:name).each(&block)
75
97
  else
76
98
  # This is needed since all vocabulary classes are defined using
@@ -177,16 +199,28 @@ module RDF
177
199
  # @return [RDF::Vocabulary::Term]
178
200
  #
179
201
  # @overload property(name, options)
180
- # Defines a new property or class in the vocabulary.
202
+ # Defines a new property or class in the vocabulary as a {RDF::Vocabulary::Term}.
181
203
  #
182
204
  # @example A simple term definition
183
205
  # property :domain,
184
- # comment: %(A domain of the subject property.).freeze,
185
- # domain: "rdf:Property".freeze,
186
- # label: "domain".freeze,
187
- # range: "rdfs:Class".freeze,
188
- # isDefinedBy: %(rdfs:).freeze,
189
- # type: "rdf:Property".freeze
206
+ # comment: %(A domain of the subject property.),
207
+ # domain: "rdf:Property",
208
+ # label: "domain",
209
+ # range: "rdfs:Class",
210
+ # isDefinedBy: %(rdfs:),
211
+ # type: "rdf:Property"
212
+ #
213
+ # @example A term definition with tagged values
214
+ # property :actor,
215
+ # comment: {en: "Subproperty of as:attributedTo that identifies the primary actor"},
216
+ # domain: "https://www.w3.org/ns/activitystreams#Activity",
217
+ # label: {en: "actor"},
218
+ # range: term(
219
+ # type: "http://www.w3.org/2002/07/owl#Class",
220
+ # unionOf: list("https://www.w3.org/ns/activitystreams#Object", "https://www.w3.org/ns/activitystreams#Link")
221
+ # ),
222
+ # subPropertyOf: "https://www.w3.org/ns/activitystreams#attributedTo",
223
+ # type: "http://www.w3.org/2002/07/owl#ObjectProperty"
190
224
  #
191
225
  # @example A SKOS term with anonymous values
192
226
  # term: :af,
@@ -205,76 +239,8 @@ module RDF
205
239
  # "foaf:name": "Aland Islands"
206
240
  #
207
241
  # @param [String, #to_s] name
208
- # @param [Hash{Symbol=>String,Array<String,Term>}] options
209
- # Any other values are expected to expands to a {URI} using built-in vocabulary prefixes. The value is a `String`, `Array<String>` or `Array<Term>` which is interpreted according to the `range` of the associated property.
210
- # @option options [String, Array<String,Term>] :type
211
- # Shortcut for `rdf:type`, values are interpreted as a {Term}.
212
- # @option options [String, Array<String>] :comment
213
- # Shortcut for `rdfs:comment`, values are interpreted as a {Literal}.
214
- # @option options [String, Array<String,Term>] :domain
215
- # Shortcut for `rdfs:domain`, values are interpreted as a {Term}.
216
- # @option options [String, Array<String,Term>] :isDefinedBy
217
- # Shortcut for `rdfs:isDefinedBy`, values are interpreted as a {Term}.
218
- # @option options [String, Array<String>] :label
219
- # Shortcut for `rdfs:label`, values are interpreted as a {Literal}.
220
- # @option options [String, Array<String,Term>] :range
221
- # Shortcut for `rdfs:range`, values are interpreted as a {Term}.
222
- # @option options [String, Array<String,Term>] :subClassOf
223
- # Shortcut for `rdfs:subClassOf`, values are interpreted as a {Term}.
224
- # @option options [String, Array<String,Term>] :subPropertyOf
225
- # Shortcut for `rdfs:subPropertyOf`, values are interpreted as a {Term}.
226
- # @option options [String, Array<String,Term>] :allValuesFrom
227
- # Shortcut for `owl:allValuesFrom`, values are interpreted as a {Term}.
228
- # @option options [String, Array<String,Term>] :cardinality
229
- # Shortcut for `owl:cardinality`, values are interpreted as a {Literal}.
230
- # @option options [String, Array<String,Term>] :equivalentClass
231
- # Shortcut for `owl:equivalentClass`, values are interpreted as a {Term}.
232
- # @option options [String, Array<String,Term>] :equivalentProperty
233
- # Shortcut for `owl:equivalentProperty`, values are interpreted as a {Term}.
234
- # @option options [String, Array<String,Term>] :intersectionOf
235
- # Shortcut for `owl:intersectionOf`, values are interpreted as a {Term}.
236
- # @option options [String, Array<String,Term>] :inverseOf
237
- # Shortcut for `owl:inverseOf`, values are interpreted as a {Term}.
238
- # @option options [String, Array<String,Term>] :maxCardinality
239
- # Shortcut for `owl:maxCardinality`, values are interpreted as a {Literal}.
240
- # @option options [String, Array<String,Term>] :minCardinality
241
- # Shortcut for `owl:minCardinality`, values are interpreted as a {Literal}.
242
- # @option options [String, Array<String,Term>] :onProperty
243
- # Shortcut for `owl:onProperty`, values are interpreted as a {Term}.
244
- # @option options [String, Array<String,Term>] :someValuesFrom
245
- # Shortcut for `owl:someValuesFrom`, values are interpreted as a {Term}.
246
- # @option options [String, Array<String,Term>] :unionOf
247
- # Shortcut for `owl:unionOf`, values are interpreted as a {Term}.
248
- # @option options [String, Array<String,Term>] :domainIncludes
249
- # Shortcut for `schema:domainIncludes`, values are interpreted as a {Term}.
250
- # @option options [String, Array<String,Term>] :rangeIncludes
251
- # Shortcut for `schema:rangeIncludes`, values are interpreted as a {Term}.
252
- # @option options [String, Array<String>] :altLabel
253
- # Shortcut for `skos:altLabel`, values are interpreted as a {Literal}.
254
- # @option options [String, Array<String,Term>] :broader
255
- # Shortcut for `skos:broader`, values are interpreted as a {Term}.
256
- # @option options [String, Array<String>] :definition
257
- # Shortcut for `skos:definition`, values are interpreted as a {Literal}.
258
- # @option options [String, Array<String>] :editorialNote
259
- # Shortcut for `skos:editorialNote`, values are interpreted as a {Literal}.
260
- # @option options [String, Array<String,Term>] :exactMatch
261
- # Shortcut for `skos:exactMatch`, values are interpreted as a {Term}.
262
- # @option options [String, Array<String,Term>] :hasTopConcept
263
- # Shortcut for `skos:hasTopConcept`, values are interpreted as a {Term}.
264
- # @option options [String, Array<String,Term>] :inScheme
265
- # Shortcut for `skos:inScheme`, values are interpreted as a {Term}.
266
- # @option options [String, Array<String,Term>] :member
267
- # Shortcut for `skos:member`, values are interpreted as a {Term}.
268
- # @option options [String, Array<String,Term>] :narrower
269
- # Shortcut for `skos:narrower`, values are interpreted as a {Term}.
270
- # @option options [String, Array<String>] :notation
271
- # Shortcut for `skos:notation`, values are interpreted as a {Literal}.
272
- # @option options [String, Array<String>] :note
273
- # Shortcut for `skos:note`, values are interpreted as a {Literal}.
274
- # @option options [String, Array<String>] :prefLabel
275
- # Shortcut for `skos:prefLabel`, values are interpreted as a {Literal}.
276
- # @option options [String, Array<String,Term>] :related
277
- # Shortcut for `skos:related`, values are interpreted as a {Term}.
242
+ # @param [Hash{Symbol=>String,Array<String>}] options
243
+ # Any other values are expected to expands to a {URI} using built-in vocabulary prefixes. The value is a `String`, 'Hash{Symbol=>String,Array<String>}' or `Array<String,Hash{Symbol=>Array<String>}>` which is interpreted according to the `range` of the associated property and by heuristically determining the value datatype. See `attributes` argument to {Term#initialize}.
278
244
  # @return [RDF::Vocabulary::Term]
279
245
  def property(*args)
280
246
  case args.length
@@ -287,15 +253,6 @@ module RDF
287
253
  uri_str = [to_s, name.to_s].join('')
288
254
  URI.cache.delete(uri_str.to_sym) # Clear any previous entry
289
255
 
290
- # Transform attribute keys that are PNames with a warning
291
- # FIXME: add back later
292
- #if !@is_deprecated && options.is_a?(Hash) &&
293
- # options.keys.map(&:to_s).any? {|k| k.include?(':') && !k.match?(/^https?:/)}
294
- #
295
- # @is_deprecated = true
296
- # warn "[DEPRECATION] Vocabulary #{to_uri} includes pname attribute keys, regenerate"
297
- #end
298
-
299
256
  # Term attributes passed in a block for lazy evaluation. This helps to avoid load-time circular dependencies
300
257
  prop = Term.intern(uri_str, vocab: self, attributes: options || {})
301
258
  props[name.to_sym] = prop
@@ -356,7 +313,7 @@ module RDF
356
313
  def ontology(*args)
357
314
  case args.length
358
315
  when 0
359
- @ontology
316
+ @ontology if instance_variable_defined?(:@ontology)
360
317
  else
361
318
  uri, options = args
362
319
  URI.cache.delete(uri.to_s.to_sym) # Clear any previous entry
@@ -379,15 +336,20 @@ module RDF
379
336
  alias_method :__properties__, :properties
380
337
 
381
338
  ##
382
- # Attempt to expand a Compact IRI/PName/QName using loaded vocabularies
339
+ # Attempt to expand a Compact IRI/PName using loaded vocabularies
383
340
  #
384
341
  # @param [String, #to_s] pname
342
+ # The local-part of the PName will will have [reserved character escapes](https://www.w3.org/TR/turtle/#reserved) unescaped.
385
343
  # @return [Term]
386
- # @raise [KeyError] if pname suffix not found in identified vocabulary
344
+ # @raise [KeyError] if pname suffix not found in identified vocabulary.
387
345
  # @raise [ArgumentError] if resulting URI is not valid
388
346
  def expand_pname(pname)
389
347
  return pname unless pname.is_a?(String) || pname.is_a?(Symbol)
390
348
  prefix, suffix = pname.to_s.split(":", 2)
349
+ # Unescape escaped PN_ESCAPE_CHARS
350
+ if suffix.match?(RDF::URI::PN_ESCAPES)
351
+ suffix = suffix.gsub(RDF::URI::PN_ESCAPES) {|matched| matched[1..-1]}
352
+ end
391
353
  if prefix == "rdf"
392
354
  RDF[suffix]
393
355
  elsif vocab_detail = RDF::Vocabulary.vocab_map[prefix.to_sym]
@@ -417,9 +379,10 @@ module RDF
417
379
  end
418
380
 
419
381
  ##
420
- # Return the Vocabulary term associated with a URI
382
+ # Return the Vocabulary term associated with a URI
421
383
  #
422
- # @param [RDF::URI] uri
384
+ # @param [RDF::URI, String] uri
385
+ # If `uri` has is a pname in a locded vocabulary, the suffix portion of the PName will have escape characters unescaped before resolving against the vocabulary.
423
386
  # @return [Vocabulary::Term]
424
387
  def find_term(uri)
425
388
  uri = RDF::URI(uri)
@@ -428,7 +391,8 @@ module RDF
428
391
  if vocab.ontology == uri
429
392
  vocab.ontology
430
393
  else
431
- vocab[uri.to_s[vocab.to_uri.to_s.length..-1].to_s]
394
+ suffix = uri.to_s[vocab.to_uri.to_s.length..-1].to_s
395
+ vocab[suffix]
432
396
  end
433
397
  end
434
398
  end
@@ -507,7 +471,7 @@ module RDF
507
471
  end
508
472
 
509
473
  # Also include the ontology, if it's not also a property
510
- @ontology.each_statement(&block) if @ontology && @ontology != self
474
+ @ontology.each_statement(&block) if self.ontology && self.ontology != self
511
475
  end
512
476
 
513
477
  ##
@@ -557,10 +521,6 @@ module RDF
557
521
  statement.predicate.to_s.to_sym
558
522
  end
559
523
 
560
- # Skip literals other than plain or english
561
- # This is because the ruby representation does not preserve language
562
- next if statement.object.literal? && (statement.object.language || :en).to_s !~ /^en-?/
563
-
564
524
  (term[key] ||= []) << statement.object
565
525
  end
566
526
 
@@ -642,12 +602,31 @@ module RDF
642
602
  alias_method :__name__, :name
643
603
 
644
604
  ##
645
- # Returns a suggested CURIE/PName prefix for this vocabulary class.
605
+ # Returns a suggested vocabulary prefix for this vocabulary class.
646
606
  #
647
607
  # @return [Symbol]
648
608
  # @since 0.3.0
649
609
  def __prefix__
650
- __name__.split('::').last.downcase.to_sym
610
+ instance_variable_defined?(:@__prefix__) ?
611
+ @__prefix__ :
612
+ __name__.split('::').last.downcase.to_sym
613
+ end
614
+
615
+ ##
616
+ # Sets the vocabulary prefix to use for this vocabulary..
617
+ #
618
+ # @example Overriding a standard vocabulary prefix.
619
+ # RDF::Vocab::DC.__prefix__ = :dcterms
620
+ # RDF::Vocab::DC.title.pname #=> 'dcterms:title'
621
+ #
622
+ # @param [Symbol] prefix
623
+ # @return [Symbol]
624
+ # @since 3.2.3
625
+ def __prefix__=(prefix)
626
+ params = RDF::Vocabulary.vocab_map[__prefix__]
627
+ @__prefix__ = prefix.to_sym
628
+ RDF::Vocabulary.register(@__prefix__, self, **params)
629
+ @__prefix__
651
630
  end
652
631
 
653
632
  protected
@@ -937,6 +916,10 @@ module RDF
937
916
  #
938
917
  # Symbols which are accessors may also be looked up by their associated URI.
939
918
  #
919
+ # Values may be Strings, Hash (Map), or Terms, or an Array including a combination of these. A Hash (Map) is used to create a datatype/language map to one or more string values which represent either datatyped literals, or language-tagged literals as interpreted by {#attribute_value}.
920
+ #
921
+ # In general, this accessor is used internally. The {#properties} method interprets these values as {RDF::Value}.
922
+ #
940
923
  # @note lookup by PName is DEPRECATED and will be removed in a future version.
941
924
  #
942
925
  # @example looking up term label
@@ -945,23 +928,23 @@ module RDF
945
928
  # RDF::RDFS.Literal.attributes[RDF::RDFS.label] #=> "Literal"
946
929
  # RDF::RDFS.Literal.attributes["http://www.w3.org/2000/01/rdf-schema#label"] #=> "Literal"
947
930
  # RDF::RDFS.Literal.attributes[:"http://www.w3.org/2000/01/rdf-schema#label"] #=> "Literal"
948
- # @return [Hash{Symbol,Resource => Term, #to_s}]
931
+ # @return [Hash{Symbol => String, Term, Hash{Symbol => String}, Array<String, Term, Hash{Symbol => String}>}]
932
+ # @see #properties
949
933
  attr_reader :attributes
950
934
 
951
935
  ##
952
- # @overload new(uri, attributes:, **options)
936
+ # @overload new(uri, attributes:, vocab:, **options)
953
937
  # @param [URI, String, #to_s] uri
954
938
  # @param [Vocabulary] vocab Vocabulary of this term.
955
- # @param [Hash{Symbol => Symbol,Array<String,Term>}] attributes ({})
939
+ # @param [Hash{Symbol => String,Term,Hash{Symbol=>String,Array<String>},Array<String>}] attributes ({})
956
940
  # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF. See {#attributes} and {#properties} for other ways to access.
957
941
  # @param [Hash{Symbol => Object}] options
958
942
  # Options from {URI#initialize}
959
943
  #
960
- # @overload new(attributes:, **options)
961
- # @param [Hash{Symbol => Object}] options
944
+ # @overload new(attributes:, vocab:, **options)
962
945
  # @param [Vocabulary] vocab Vocabulary of this term.
963
- # @param [Hash{Symbol => Symbol,Array<String,Term>}] attributes ({})
964
- # Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF. See {#attributes} and {#properties} for other ways to access.
946
+ # @param [Hash{Symbol => String,Term,Hash{Symbol=>String,Array<String>},Array<String>}] attributes ({})
947
+ # Attributes of this vocabulary term, used for finding `label`, `comment` and other term properties, and to serialize the term back to RDF. See {#attributes} and {#properties} for other ways to access.
965
948
  # @param [Hash{Symbol => Object}] options
966
949
  # Options from {URI#initialize}
967
950
  def self.new(*args, vocab: nil, attributes: {}, **options)
@@ -1084,7 +1067,7 @@ module RDF
1084
1067
 
1085
1068
  ##
1086
1069
  # Enumerate attributes with values transformed into {RDF::Value} instances
1087
- # Uses an empty hash with a default_proc which looks up values in attributes.
1070
+ # Uses an empty hash with a default_proc which looks up values in attributes. The prevents specific attributes from being evaluated until acessed.
1088
1071
  #
1089
1072
  # Properties are indexed by symbol. Symbols directly interpreted by a term are the accessors defined for the {RDF::Vocabulary::Term} class, also in {Term::ATTR_URIs}. Other keys are interpreted as absolute URIs or PNames for properties defined on this term.
1090
1073
  #
@@ -1101,12 +1084,27 @@ module RDF
1101
1084
  # RDF::RDFS.Literal.properties[:"http://www.w3.org/2000/01/rdf-schema#label"] #=> RDF::Literal("Literal")
1102
1085
  #
1103
1086
  # @return [Hash{Symbol => Array<RDF::Value>}]
1087
+ # @see #attribute_value
1104
1088
  def properties
1105
1089
  Hash.new {|hash, key| attribute_value(key)}
1106
1090
  end
1107
1091
 
1108
1092
  ##
1109
- # Values of an attributes as {RDF::Value}
1093
+ # Values of an attributes as {RDF::Value}.
1094
+ #
1095
+ # Attribute values are returned as either an {RDF::Value} or {Array<RDf::Value} if there is more than one value.
1096
+ #
1097
+ # Attribute values which are not already a {RDF::Value} (including strings and symbols) are converted by a heuristic loookup as follows:
1098
+ #
1099
+ # * An {RDF::URI} if it can be turned into a valid IRI using {RDF::Vocabulary.expand_pname}. This includes IRIs already in non-relative form.
1100
+ # * A {Hash{Symbol=>String,Array<String>}} is interpreted as a datatype/language map. If the key contains a ':', it is treated as a PName or IRI datatype applied to the values. Otherwise, it is treated as a language-tag applied to the values.
1101
+ # * {RDF::Literal::Date} if valid,
1102
+ # * {RDF::Literal::DateTime} if valid,
1103
+ # * {RDF::Literal::Integer} if valid,
1104
+ # * {RDF::Literal::Decimal} if valid,
1105
+ # * {RDF::Literal::Double} if valid,
1106
+ # * {RDF::Literal::Boolean} if valid
1107
+ # * Otherwise, {RDF::Literal} where type may be inferred by the class of the value.
1110
1108
  #
1111
1109
  # @param [Symbol] prop
1112
1110
  # @return [RDF::Value, Array<RDF::Value>]
@@ -1118,9 +1116,22 @@ module RDF
1118
1116
  v = value.is_a?(Symbol) ? value.to_s : value
1119
1117
  value = (RDF::Vocabulary.expand_pname(v) rescue nil) if v.is_a?(String) && v.include?(':')
1120
1118
  value = value.to_uri if value.respond_to?(:to_uri)
1121
- unless value.is_a?(RDF::Value) && value.valid?
1119
+ value = if value.is_a?(RDF::Value) && value.valid?
1120
+ value
1121
+ elsif value.is_a?(Hash)
1122
+ # type/language map
1123
+ value.inject([]) do |memo, (k,v)|
1124
+ vv = [v] unless v.is_a?(Array)
1125
+ memo << if k.to_s.include?(':')
1126
+ dt = RDF::Vocabulary.expand_pname(v) rescue nil
1127
+ vv.map {|val| RDF::Literal(val, datatype: dt)}
1128
+ else
1129
+ vv.map {|val| RDF::Literal(val, language: k)}
1130
+ end
1131
+ end.flatten.compact.select(&:valid?)
1132
+ else
1122
1133
  # Use as most appropriate literal
1123
- value = [
1134
+ [
1124
1135
  RDF::Literal::Date,
1125
1136
  RDF::Literal::DateTime,
1126
1137
  RDF::Literal::Integer,
@@ -1135,9 +1146,7 @@ module RDF
1135
1146
  end
1136
1147
  end
1137
1148
  end
1138
-
1139
- value
1140
- end
1149
+ end.flatten
1141
1150
 
1142
1151
  prop_values.length <= 1 ? prop_values.first : prop_values
1143
1152
  end
@@ -1221,7 +1230,9 @@ module RDF
1221
1230
  rangeIncludes
1222
1231
  end
1223
1232
 
1224
- # Serialize back to a Ruby source initializer
1233
+ ##
1234
+ # Serialize back to a Ruby source initializer. This is used primarily by {RDF::Vocabulary::Writer}.
1235
+ #
1225
1236
  # @param [String] indent
1226
1237
  # @return [String]
1227
1238
  def to_ruby(indent: "")
@@ -1233,24 +1244,24 @@ module RDF
1233
1244
  values = [values].compact unless values.is_a?(Array)
1234
1245
  values = values.map do |value|
1235
1246
  if value.is_a?(Literal) && %w(: comment definition notation note editorialNote).include?(k.to_s)
1236
- "%(#{value.to_s.gsub('(', '\(').gsub(')', '\)')}).freeze"
1237
- # elsif value.is_a?(RDF::Vocabulary::Term)
1238
- # value.to_ruby(indent: indent + " ")
1247
+ "%(#{value.to_s.gsub('(', '\(').gsub(')', '\)')})"
1248
+ elsif value.node? && value.is_a?(RDF::Vocabulary::Term)
1249
+ "#{value.to_ruby(indent: indent + " ")}"
1239
1250
  elsif value.is_a?(RDF::Term)
1240
- "#{value.to_s.inspect}.freeze"
1251
+ "#{value.to_s.inspect}"
1241
1252
  elsif value.is_a?(RDF::List)
1242
1253
  list_elements = value.map do |u|
1243
1254
  if u.uri?
1244
- "#{u.to_s.inspect}.freeze"
1245
- # elsif u.respond_to?(:to_ruby)
1246
- # u.to_ruby(indent: indent + " ")
1255
+ "#{u.to_s.inspect}"
1256
+ elsif u.node? && u.respond_to?(:to_ruby)
1257
+ u.to_ruby(indent: indent + " ")
1247
1258
  else
1248
- "#{u.to_s.inspect}.freeze"
1259
+ "#{u.to_s.inspect}"
1249
1260
  end
1250
1261
  end
1251
1262
  "list(#{list_elements.join(', ')})"
1252
1263
  else
1253
- "#{value.inspect}.freeze"
1264
+ "#{value.inspect}"
1254
1265
  end
1255
1266
  end
1256
1267
  "#{k.to_s.include?(':') ? k.to_s.inspect : k}: " +
@@ -1314,7 +1325,7 @@ module RDF
1314
1325
  def [](name)
1315
1326
  props.fetch(name.to_sym)
1316
1327
  rescue KeyError
1317
- raise KeyError, "#{name} not found in vocabulary #{self.__name__}"
1328
+ raise KeyError, "#{name.inspect} not found in vocabulary #{self.__name__}"
1318
1329
  end
1319
1330
  end
1320
1331
  end # StrictVocabulary
data/lib/rdf/writer.rb CHANGED
@@ -516,7 +516,7 @@ module RDF
516
516
  when RDF::Literal then format_literal(term, **options)
517
517
  when RDF::URI then format_uri(term, **options)
518
518
  when RDF::Node then format_node(term, **options)
519
- when RDF::Statement then format_embTriple(term, **options)
519
+ when RDF::Statement then format_quotedTriple(term, **options)
520
520
  else nil
521
521
  end
522
522
  end
@@ -574,7 +574,7 @@ module RDF
574
574
  # @return [String]
575
575
  # @raise [NotImplementedError] unless implemented in subclass
576
576
  # @abstract
577
- def format_embTriple(value, **options)
577
+ def format_quotedTriple(value, **options)
578
578
  raise NotImplementedError.new("#{self.class}#format_statement") # override in subclasses
579
579
  end
580
580
 
data/lib/rdf.rb CHANGED
@@ -7,9 +7,6 @@ require "ostruct"
7
7
  require 'rdf/version'
8
8
  require 'rdf/extensions'
9
9
 
10
- # When loading, issue deprecation warning on forthcoming unsupported versions of Ruby
11
- warn "[DEPRECATION] Ruby 2.4+ required in next version 3.1 of RDF.rb" if RUBY_VERSION < "2.4"
12
-
13
10
  module RDF
14
11
  # RDF mixins
15
12
  autoload :Countable, 'rdf/mixin/countable'