Skip to content

Commit 2b3efce

Browse files
committed
Update Term#attributes to take over changes to Term#properties, which allows equivalent hash access for both.
1 parent 1ebf953 commit 2b3efce

3 files changed

Lines changed: 62 additions & 42 deletions

File tree

lib/rdf/vocab/writer.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,17 @@ module #{module_name}
169169
).each do |attr|
170170
next unless vocab.ontology.attributes[attr]
171171
Array(vocab.ontology.attributes[attr]).each do |v|
172-
ont_doc << " # # " + v.to_s.gsub(/\n/, ' ')
172+
ont_doc << " # # " + v.to_s.gsub(/\s+/, ' ')
173173
end
174174
end
175175
@output.puts ont_doc.join("\n # #\n") unless ont_doc.empty?
176176
# Version Info
177-
Array(vocab.ontology.attributes[:"owl:versionInfo"]).each do |vers|
177+
# See Also
178+
Array(vocab.ontology.attributes[:'http://www.w3.org/2002/07/owl#versionInfo']).each do |vers|
178179
@output.puts " # # @version #{vers}"
179180
end
180181
# See Also
181-
Array(vocab.ontology.attributes[:"rdfs:seeAlso"]).each do |see|
182+
Array(vocab.ontology.attributes[:'http://www.w3.org/2000/01/rdf-schema#seeAlso']).each do |see|
182183
@output.puts " # # @see #{see}"
183184
end
184185
end
@@ -222,7 +223,7 @@ module #{module_name}
222223
# Only document terms that can be accessed like a Ruby attribute
223224
next unless name.to_s.match?(/^[_[:alpha:]](?:\w*)[!?=]?$/)
224225
@output.puts(Array(attributes[:comment]).map do |comment|
225-
" # # #{comment.to_s.gsub(/\n/, ' ')}"
226+
" # # #{comment.to_s.gsub(/\s+/, ' ')}"
226227
end.join("\n # #\n")) if attributes[:comment]
227228
@output.puts " # # @return [RDF::Vocabulary::Term]"
228229
@output.puts " # attr_reader :#{name}"

lib/rdf/vocabulary.rb

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ def property(*args)
297297
#end
298298

299299
# Term attributes passed in a block for lazy evaluation. This helps to avoid load-time circular dependencies
300-
prop = Term.intern(uri_str, vocab: self, attributes: options)
300+
prop = Term.intern(uri_str, vocab: self, attributes: options || {})
301301
props[name.to_sym] = prop
302302

303303
# If name is empty, also treat it as the ontology
@@ -361,7 +361,7 @@ def ontology(*args)
361361
uri, options = args
362362
URI.cache.delete(uri.to_s.to_sym) # Clear any previous entry
363363
# Term attributes passed in a block for lazy evaluation. This helps to avoid load-time circular dependencies
364-
@ontology = Term.intern(uri.to_s, vocab: self, attributes: options)
364+
@ontology = Term.intern(uri.to_s, vocab: self, attributes: options || {})
365365

366366
# If the URI is the same as the vocabulary namespace, also define it as a term
367367
props[:""] ||= @ontology if self.to_s == uri.to_s
@@ -932,23 +932,36 @@ module Term
932932
attr_reader :vocab
933933

934934
# Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF.
935+
#
936+
# Attributes 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.
937+
#
938+
# Symbols which are accessors may also be looked up by their associated URI.
939+
#
940+
# @note lookup by PName is DEPRECATED and will be removed in a future version.
941+
#
942+
# @example looking up term label
943+
# RDF::RDFS.Literal.attributes[:label] #=> "Literal"
944+
# RDF::RDFS.Literal.attributes[:"rdfs:label"] #=> "Literal"
945+
# RDF::RDFS.Literal.attributes[RDF::RDFS.label] #=> "Literal"
946+
# RDF::RDFS.Literal.attributes["http://www.w3.org/2000/01/rdf-schema#label"] #=> "Literal"
947+
# RDF::RDFS.Literal.attributes[:"http://www.w3.org/2000/01/rdf-schema#label"] #=> "Literal"
935948
# @return [Hash{Symbol,Resource => Term, #to_s}]
936949
attr_reader :attributes
937950

938951
##
939952
# @overload new(uri, attributes:, **options)
940953
# @param [URI, String, #to_s] uri
941954
# @param [Vocabulary] vocab Vocabulary of this term.
942-
# @param [Hash{Symbol,Resource => Term, #to_s}] attributes
943-
# Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF
955+
# @param [Hash{Symbol => Symbol,Array<String,Term>}] attributes ({})
956+
# 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.
944957
# @param [Hash{Symbol => Object}] options
945958
# Options from {URI#initialize}
946959
#
947960
# @overload new(attributes:, **options)
948961
# @param [Hash{Symbol => Object}] options
949962
# @param [Vocabulary] vocab Vocabulary of this term.
950-
# @param [Hash{Symbol => String,Array<String,Term>}] attributes
951-
# Attributes of this vocabulary term, used for finding `label` and `comment` and to serialize the term back to RDF.
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.
952965
# @param [Hash{Symbol => Object}] options
953966
# Options from {URI#initialize}
954967
def self.new(*args, vocab: nil, attributes: {}, **options)
@@ -963,6 +976,28 @@ def self.new(*args, vocab: nil, attributes: {}, **options)
963976
else RDF::URI
964977
end
965978

979+
# Create default proc on attributes to allow lookup by different key types.
980+
attributes = attributes.dup if attributes.frozen?
981+
attributes.default_proc = -> (hash, key) do
982+
sym = case key
983+
when RDF::URI
984+
URI_ATTRs.fetch(key, key.to_s.to_sym)
985+
when String
986+
URI_ATTRs.fetch(RDF::URI(key), key.to_s.to_sym)
987+
when Symbol
988+
case key.to_s
989+
when /^https?:/
990+
# Lookup by associated attribute, or pname
991+
URI_ATTRs.fetch(RDF::URI(key.to_s), RDF::URI(key).pname.to_sym)
992+
when /:/
993+
uri = RDF::Vocabulary.expand_pname(key)
994+
# Lookup by associated attribute or URI
995+
URI_ATTRs.fetch(uri, uri.to_s.to_sym)
996+
end
997+
end
998+
hash.fetch(sym, nil)
999+
end
1000+
9661001
term = klass.allocate.extend(Term)
9671002
term.send(:initialize, *args)
9681003
term.instance_variable_set(:@vocab, vocab)
@@ -1067,38 +1102,7 @@ def other?
10671102
#
10681103
# @return [Hash{Symbol => Array<RDF::Value>}]
10691104
def properties
1070-
Hash.new do |hash, key|
1071-
case key
1072-
when RDF::URI
1073-
sym = URI_ATTRs.fetch(key, key.to_s.to_sym)
1074-
attribute_value(sym)
1075-
when String
1076-
sym = URI_ATTRs.fetch(RDF::URI(key), key.to_s.to_sym)
1077-
attribute_value(sym)
1078-
when Symbol
1079-
sym = case key.to_s
1080-
when /^https?:/
1081-
if attributes.key?(key)
1082-
key
1083-
else
1084-
# Lookup by associated attribute, or pname
1085-
URI_ATTRs.fetch(RDF::URI(key.to_s), RDF::URI(key).pname.to_sym)
1086-
end
1087-
when /:/
1088-
if attributes.key?(key)
1089-
key
1090-
else
1091-
uri = RDF::Vocabulary.expand_pname(key)
1092-
# Lookup by associated attribute or URI
1093-
URI_ATTRs.fetch(uri, uri.to_s.to_sym)
1094-
end
1095-
else
1096-
key
1097-
end
1098-
attribute_value(sym)
1099-
else nil
1100-
end
1101-
end
1105+
Hash.new {|hash, key| attribute_value(key)}
11021106
end
11031107

11041108
##

spec/vocabulary_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,21 @@
591591

592592
its(:label) {is_expected.to eq RDF::Literal("Literal")}
593593

594+
describe "#attributes" do
595+
[
596+
:label,
597+
:'rdfs:label',
598+
"http://www.w3.org/2000/01/rdf-schema#label",
599+
:"http://www.w3.org/2000/01/rdf-schema#label",
600+
RDF::RDFS.label,
601+
].each do |key|
602+
it key.inspect do
603+
expect(subject.attributes[key]).to be_a String
604+
expect(subject.attributes[key]).to eql "Literal"
605+
end
606+
end
607+
end
608+
594609
describe "#properties" do
595610
[
596611
:label,

0 commit comments

Comments
 (0)