Skip to content

Commit 31a47d8

Browse files
committed
Adds RDF::Vocabulary.limit_vocabs which is used to limit the vocabularies returned by RDF::Vocabulary.each and can substantially reduce load time when the rdf-vocabs gem is used.
For #411.
1 parent 814db26 commit 31a47d8

2 files changed

Lines changed: 101 additions & 6 deletions

File tree

lib/rdf/vocabulary.rb

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,15 @@ class << self
7070
# @return [Enumerator]
7171
def each(&block)
7272
if self.equal?(Vocabulary)
73-
# This is needed since all vocabulary classes are defined using
74-
# Ruby's autoloading facility, meaning that `@@subclasses` will be
75-
# empty until each subclass has been touched or require'd.
76-
RDF::VOCABS.each { |v, p| RDF.const_get(p[:class_name].to_sym) unless v == :rdf }
77-
@@subclasses.select(&:name).each(&block)
73+
if @vocabs
74+
@vocabs.select(&:name).each(&block)
75+
else
76+
# This is needed since all vocabulary classes are defined using
77+
# Ruby's autoloading facility, meaning that `@@subclasses` will be
78+
# empty until each subclass has been touched or require'd.
79+
RDF::VOCABS.each { |v, p| RDF.const_get(p[:class_name].to_sym) unless v == :rdf }
80+
@@subclasses.select(&:name).each(&block)
81+
end
7882
else
7983
__properties__.each(&block)
8084
end
@@ -96,6 +100,38 @@ def from_sym(sym)
96100
RDF.const_get(sym.to_sym)
97101
end
98102

103+
##
104+
# Limits iteration over vocabularies to just those selected
105+
#
106+
# @example limit to set of vocabularies by symbol
107+
# RDF::Vocabulary.limit_vocabs(:rdf, :rdfs
108+
# RDF::Vocabulary.find_term('http://www.w3.org/2000/01/rdf-schema#Resource').pname
109+
# # => 'rdfs:Resource'
110+
#
111+
# @example limit to set of vocabularies by class name
112+
# RDF::Vocabulary.limit_vocabs(RDF::RDFV, RDF::RDFS)
113+
# RDF::Vocabulary.find_term('http://www.w3.org/2000/01/rdf-schema#Resource').pname
114+
# # => 'rdfs:Resource'
115+
#
116+
# @param [Array<symbol, RDF::Vocabulary>] vocabs
117+
# A list of vocabularies (symbols or classes) which may
118+
# be returned by {Vocabulary.each}. Also limits
119+
# vocabularies that will be inspeced for other methods.
120+
# Set to nil, or an empty array to reset.
121+
# @return [Array<RDF::Vocabulary>]
122+
def limit_vocabs(*vocabs)
123+
@vocabs = if Array(vocabs).empty?
124+
nil
125+
else
126+
vocabs.map do |vocab|
127+
vocab = :rdfv if vocab == :rdf
128+
vocab.is_a?(Symbol) && RDF::VOCABS.key?(vocab) ?
129+
RDF.const_get(RDF::VOCABS[vocab][:class_name].to_sym) :
130+
vocab
131+
end.compact
132+
end
133+
end
134+
99135
##
100136
# Is this a strict vocabulary, or a liberal vocabulary allowing arbitrary properties?
101137
def strict?; false; end
@@ -610,7 +646,6 @@ def inherited(subclass) # @private
610646
unless @@uri.nil?
611647
@@subclasses << subclass unless %w(http://www.w3.org/1999/02/22-rdf-syntax-ns#).include?(@@uri)
612648
subclass.send(:private_class_method, :new)
613-
#vocab_map[subclass.__prefix__] ||= {uri: @@uri, class_name: subclass.__name__.split('::').last.downcase}
614649
@@uris[subclass] = @@uri
615650
@@uri = nil
616651
end

spec/vocabulary_spec.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,66 @@
5555
expect {|b| RDF::RDFS.each(&b)}.to yield_control.at_least(5).times
5656
expect(RDF::RDFS.each.to_a).to include(RDF::RDFS.range, RDF::RDFS.subClassOf, RDF::RDFS.domain)
5757
end
58+
59+
context "with limited vocabularies" do
60+
before { RDF::Vocabulary.limit_vocabs(:rdfs)}
61+
after { RDF::Vocabulary.limit_vocabs()}
62+
63+
it "inumerates limited vocabularies" do
64+
expect {|b| RDF::Vocabulary.each(&b)}.to yield_control.exactly(1).times
65+
expect(RDF::Vocabulary.each.to_a).to include(RDF::RDFS)
66+
end
67+
end
68+
end
69+
70+
describe ".vocab_map" do
71+
it "returns map of vocabularies" do
72+
expect(RDF::Vocabulary.vocab_map).to have_key(:rdfv)
73+
expect(RDF::Vocabulary.vocab_map).to have_key(:rdfs)
74+
expect(RDF::Vocabulary.vocab_map).to have_key(:owl)
75+
end
76+
end
77+
78+
describe ".from_sym" do
79+
%w(RDFS OWL XSD).each do |sym|
80+
it "returns voabulary for #{sym}" do
81+
expect(RDF::Vocabulary.from_sym(sym)).to respond_to(:find_term)
82+
end
83+
end
84+
end
85+
86+
describe ".limit_vocabs" do
87+
before { RDF::Vocabulary.limit_vocabs(:rdf, :rdfs)}
88+
after { RDF::Vocabulary.limit_vocabs()}
89+
90+
terms = {
91+
'http://www.w3.org/2000/01/rdf-schema#Resource' => RDF::RDFS,
92+
'http://www.w3.org/2002/07/owl#Ontology' => nil,
93+
'http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement' => RDF::RDFV
94+
}
95+
describe ".find_term" do
96+
terms.each do |term, cls|
97+
it "#{cls ? 'finds' : 'does not find'} #{term}" do
98+
if cls
99+
expect(RDF::Vocabulary.find_term(term)).to be_a(RDF::Vocabulary::Term)
100+
else
101+
expect(RDF::Vocabulary.find_term(term)).to be_nil
102+
end
103+
end
104+
end
105+
end
106+
107+
describe ".find" do
108+
terms.each do |term, cls|
109+
it "#{cls ? 'finds' : 'does not find'} #{term}" do
110+
if cls
111+
expect(RDF::Vocabulary.find(term)).to eql cls
112+
else
113+
expect(RDF::Vocabulary.find_term(term)).to be_nil
114+
end
115+
end
116+
end
117+
end
58118
end
59119

60120
describe "#to_enum" do

0 commit comments

Comments
 (0)