Skip to content

Commit ee0dcc1

Browse files
committed
Updates for Ruby 2.7 compatibility.
1 parent a6e4b40 commit ee0dcc1

21 files changed

Lines changed: 129 additions & 107 deletions

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,4 @@ sudo: false
1313
matrix:
1414
allow_failures:
1515
- rvm: jruby
16-
- rvm: 2.7
1716
dist: trusty

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ gemspec
55
group :develop do
66
gem 'rdf-isomorphic', git: "https://github.com/ruby-rdf/rdf-isomorphic", branch: "develop"
77
gem "rdf-reasoner", git: "https://github.com/ruby-rdf/rdf-reasoner", branch: "develop"
8-
gem "rdf-spec", git: "https://github.com/ruby-rdf/rdf-spec", branch: "develop"
8+
gem 'rdf-spec', path: '../rdf-spec'
9+
#gem "rdf-spec", git: "https://github.com/ruby-rdf/rdf-spec", branch: "develop"
910
gem "rdf-turtle", git: "https://github.com/ruby-rdf/rdf-turtle", branch: "develop"
1011
gem "rdf-vocab", git: "https://github.com/ruby-rdf/rdf-vocab", branch: "develop"
1112
gem "rdf-xsd", git: "https://github.com/ruby-rdf/rdf-xsd", branch: "develop"

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ This is a pure-Ruby library for working with [Resource Description Framework
3030
* Based entirely on Ruby's autoloading, meaning that you can generally make
3131
use of any one part of the library without needing to load up the rest.
3232
* Compatible with Ruby Ruby >= 2.4, Rubinius and JRuby 9.0+.
33+
* Note, changes in mapping hashes to keyword arguments for Ruby 2.7+ may require that arguments be passed more explicitly, especially when the first argument is a Hash and there are optional keyword arguments. In this case, Hash argument may need to be explicitly included within `{}` and the optional keyword arguments may need to be specified using `**{}` if there are no keyword arguments.
3334
* Performs auto-detection of input to select appropriate Reader class if one
3435
cannot be determined from file characteristics.
3536

@@ -189,7 +190,7 @@ Note that no prefixes are loaded automatically, however they can be provided as
189190
FOAF.name => :name,
190191
FOAF.mbox => :email,
191192
}
192-
})
193+
}, **{})
193194

194195
query.execute(graph) do |solution|
195196
puts "name=#{solution.name} email=#{solution.email}"

examples/query_bench.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
require 'rdf/ntriples'
77
graph = RDF::Graph.load("etc/doap.nt")
88

9-
puts graph.query(predicate: RDF::Vocab::FOAF.name).is_a?(RDF::Queryable)
9+
puts graph.query({predicate: RDF::Vocab::FOAF.name}).is_a?(RDF::Queryable)
1010

1111
Benchmark.ips do |x|
1212
x.config(:time => 10, :warmup => 5)
13-
x.report('query_pattern') { graph.query(predicate: RDF::Vocab::FOAF.name) {} }
13+
x.report('query_pattern') { graph.query({predicate: RDF::Vocab::FOAF.name}) {} }
1414
end

lib/rdf/format.rb

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ def self.each(file_name: nil,
145145
# @param [String, RDF::URI] filename
146146
# @return [Class]
147147
#
148-
# @overload for(**options)
148+
# @overload for(options)
149149
# Finds an RDF serialization format class based on various options.
150150
#
151-
# @param [Hash{Symbol => Object}] options
151+
# @param [Hash{Symbol => Object}] options ({})
152152
# @option options [String, #to_s] :file_name (nil)
153153
# @option options [Symbol, #to_sym] :file_extension (nil)
154154
# @option options [String, #to_s] :content_type (nil)
@@ -164,19 +164,26 @@ def self.each(file_name: nil,
164164
# @yieldreturn [String] another way to provide a sample, allows lazy for retrieving the sample.
165165
#
166166
# @return [Class]
167-
def self.for(*args, **options, &block)
167+
def self.for(*arg, &block)
168+
case arg.length
169+
when 0 then arg = nil
170+
when 1 then arg = arg.first
171+
else
172+
raise ArgumentError, "Format.for accepts zero or one argument, got #{arg.length}."
173+
end
174+
175+
options = arg.is_a?(Hash) ? arg : {}
168176
options = {sample: block}.merge(options) if block_given?
169-
formats = case args.first
177+
formats = case arg
170178
when String, RDF::URI
171179
# Find a format based on the file name
172-
self.each(file_name: args.first, **options).to_a
180+
self.each(file_name: arg, **options).to_a
173181
when Symbol
174182
# Try to find a match based on the full class name
175183
# We want this to work even if autoloading fails
176-
fmt = args.first
177-
classes = self.each(**options).select {|f| f.symbols.include?(fmt)}
184+
classes = self.each(**options).select {|f| f.symbols.include?(arg)}
178185
if classes.empty?
179-
classes = case fmt
186+
classes = case arg
180187
when :ntriples then [RDF::NTriples::Format]
181188
when :nquads then [RDF::NQuads::Format]
182189
else []

lib/rdf/mixin/queryable.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module Queryable
1919
#
2020
# @example Querying for statements having a given predicate
2121
# queryable.query([nil, RDF::Vocab::DOAP.developer, nil])
22-
# queryable.query(predicate: RDF::Vocab::DOAP.developer) do |statement|
22+
# queryable.query({predicate: RDF::Vocab::DOAP.developer}) do |statement|
2323
# puts statement.inspect
2424
# end
2525
#
@@ -116,7 +116,7 @@ def query_execute(query, **options, &block)
116116
# query execution by breaking down the query into its constituent
117117
# triple patterns and invoking `RDF::Query::Pattern#execute` on each
118118
# pattern.
119-
query.execute(self, options, &block)
119+
query.execute(self, **options, &block)
120120
end
121121
protected :query_execute
122122

lib/rdf/model/graph.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def anonymous?
211211
# @return [Integer]
212212
# @see RDF::Enumerable#count
213213
def count
214-
@data.query(graph_name: graph_name || false).count
214+
@data.query({graph_name: graph_name || false}).count
215215
end
216216

217217
##
@@ -237,7 +237,7 @@ def has_statement?(statement)
237237
# @see RDF::Enumerable#each_statement
238238
def each(&block)
239239
if @data.respond_to?(:query)
240-
@data.query(graph_name: graph_name || false, &block)
240+
@data.query({graph_name: graph_name || false}, &block)
241241
elsif @data.respond_to?(:each)
242242
@data.each(&block)
243243
else

lib/rdf/model/list.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def self.[](*values)
5959
def initialize(subject: nil, graph: nil, values: nil, &block)
6060
@subject = subject || RDF.nil
6161
@graph = graph || RDF::Graph.new
62-
is_empty = @graph.query(subject: subject, predicate: RDF.first).empty?
62+
is_empty = @graph.query({subject: subject, predicate: RDF.first}).empty?
6363

6464
if subject && is_empty
6565
# An empty list with explicit subject and value initializers
@@ -115,7 +115,7 @@ def valid?
115115
list_nodes << li
116116
rest = nil
117117
firsts = rests = 0
118-
@graph.query(subject: li) do |st|
118+
@graph.query({subject: li}) do |st|
119119
return false unless st.subject.node?
120120
case st.predicate
121121
when RDF.first
@@ -136,7 +136,7 @@ def valid?
136136

137137
# All elements other than the head must be referenced exactly once
138138
return list_nodes.all? do |li|
139-
refs = @graph.query(object: li).count
139+
refs = @graph.query({object: li}).count
140140
case refs
141141
when 0 then li == subject
142142
when 1 then true
@@ -479,7 +479,7 @@ def <=>(other)
479479
# @return [Boolean]
480480
# @see http://ruby-doc.org/core-2.2.2/Array.html#method-i-empty-3F
481481
def empty?
482-
graph.query(subject: subject, predicate: RDF.first).empty?
482+
graph.query({subject: subject, predicate: RDF.first}).empty?
483483
end
484484

485485
##
@@ -822,7 +822,7 @@ def each_statement(&block)
822822
return enum_statement unless block_given?
823823

824824
each_subject do |subject|
825-
graph.query(subject: subject, &block)
825+
graph.query({subject: subject}, &block)
826826
end
827827
end
828828
alias_method :to_rdf, :each_statement

lib/rdf/query.rb

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ def self.Solutions(*args)
134134
# @return [Hash]
135135
attr_reader :options
136136

137+
##
138+
# Scope the query to named graphs matching value
139+
#
140+
# @return [RDF::Resource, RDF::Query::Variable, false] graph_name
141+
attr_accessor :graph_name
142+
137143
##
138144
# Initializes a new basic graph pattern query.
139145
#
@@ -180,6 +186,7 @@ def initialize(*patterns, solutions: nil, graph_name: nil, name: nil, validate:
180186
@options = options.dup
181187
@solutions = Query::Solutions(solutions)
182188
graph_name = name if graph_name.nil?
189+
@graph_name = graph_name
183190

184191
patterns << @options if patterns.empty?
185192

@@ -189,8 +196,6 @@ def initialize(*patterns, solutions: nil, graph_name: nil, name: nil, validate:
189196
else patterns
190197
end
191198

192-
self.graph_name = graph_name
193-
194199
if block_given?
195200
case block.arity
196201
when 1 then block.call(self)
@@ -223,7 +228,7 @@ def <<(pattern)
223228
# whether this is an optional pattern
224229
# @return [void] self
225230
def pattern(pattern, **options)
226-
@patterns << Pattern.from(pattern, options)
231+
@patterns << Pattern.from(pattern, **options)
227232
self
228233
end
229234

@@ -235,7 +240,7 @@ def pattern(pattern, **options)
235240
# @return [RDF::Query] a copy of `self`
236241
# @since 0.3.0
237242
def optimize(**options)
238-
self.dup.optimize!(options)
243+
self.dup.optimize!(**options)
239244
end
240245

241246
##
@@ -294,9 +299,7 @@ def optimize!(**options)
294299
# the resulting solution sequence
295300
# @see http://www.holygoat.co.uk/blog/entry/2005-10-25-1
296301
# @see http://www.w3.org/TR/sparql11-query/#emptyGroupPattern
297-
def execute(queryable, solutions: Solution.new, graph_name: nil, name: nil, **options, &block)
298-
options = {bindings: {}}.merge(options)
299-
302+
def execute(queryable, bindings: {}, solutions: Solution.new, graph_name: nil, name: nil, **options, &block)
300303
# Use provided solutions to allow for query chaining
301304
# Otherwise, a quick empty solution simplifies the logic below; no special case for
302305
# the first pattern
@@ -310,31 +313,30 @@ def execute(queryable, solutions: Solution.new, graph_name: nil, name: nil, **op
310313

311314
patterns = @patterns
312315
graph_name = name if graph_name.nil?
313-
graph_name = self.graph_name if graph_name.nil?
314-
options[:graph_name] = graph_name unless graph_name.nil?
316+
@graph_name = graph_name unless graph_name.nil?
315317

316318
# Add graph_name to pattern, if necessary
317-
unless graph_name.nil?
319+
unless @graph_name.nil?
318320
if patterns.empty?
319-
patterns = [Pattern.new(nil, nil, nil, graph_name: graph_name)]
321+
patterns = [Pattern.new(nil, nil, nil, graph_name: @graph_name)]
320322
else
321-
apply_graph_name(graph_name)
323+
apply_graph_name(@graph_name)
322324
end
323325
end
324326

325327
patterns.each do |pattern|
326328

327329
old_solutions, @solutions = @solutions, Query::Solutions()
328330

329-
options[:bindings].each_key do |variable|
331+
bindings.each_key do |variable|
330332
if pattern.variables.include?(variable)
331333
unbound_solutions, old_solutions = old_solutions, Query::Solutions()
332-
options[:bindings][variable].each do |binding|
334+
bindings[variable].each do |binding|
333335
unbound_solutions.each do |solution|
334336
old_solutions << solution.merge(variable => binding)
335337
end
336338
end
337-
options[:bindings].delete(variable)
339+
bindings.delete(variable)
338340
end
339341
end
340342

@@ -407,38 +409,26 @@ def +(other)
407409
# Is this query scoped to a named graph?
408410
# @return [Boolean]
409411
def named?
410-
!!options[:graph_name]
412+
!!graph_name
411413
end
412414

413415
# Is this query scoped to the default graph?
414416
# @return [Boolean]
415417
def default?
416-
options[:graph_name] == false
418+
graph_name == false
417419
end
418420

419421
# Is this query unscoped? This indicates that it can return results from
420422
# either a named graph or the default graph.
421423
# @return [Boolean]
422424
def unnamed?
423-
options[:graph_name].nil?
424-
end
425-
426-
# Scope the query to named graphs matching value
427-
# @param [RDF::IRI, RDF::Query::Variable] value
428-
# @return [RDF::IRI, RDF::Query::Variable]
429-
def graph_name=(value)
430-
options[:graph_name] = value
431-
end
432-
433-
# Scope of this query, if any
434-
# @return [RDF::IRI, RDF::Query::Variable]
435-
def graph_name
436-
options[:graph_name]
425+
graph_name.nil?
437426
end
438427

439428
# Apply the graph name specified (or configured) to all patterns that have no graph name
440429
# @param [RDF::IRI, RDF::Query::Variable] graph_name (self.graph_name)
441-
def apply_graph_name(graph_name = options[:graph_name])
430+
def apply_graph_name(graph_name = nil)
431+
graph_name ||= self.graph_name
442432
patterns.each {|pattern| pattern.graph_name = graph_name if pattern.graph_name.nil?} unless graph_name.nil?
443433
end
444434

@@ -515,8 +505,7 @@ def each_statement(&block)
515505
# @return [RDF::Query]
516506
def dup
517507
patterns = @patterns.map {|p| p.dup}
518-
patterns << @options.merge(solutions: @solutions.dup)
519-
Query.new(*patterns)
508+
Query.new(patterns, solutions: @solutions.dup, **options)
520509
end
521510

522511
##

lib/rdf/query/hash_pattern_normalizer.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,14 @@ class << self
8585
# the string format for anonymous subjects.
8686
# @return [Hash{Symbol => Object}]
8787
# the resulting query pattern as a normalized hash.
88-
def normalize!(hash_pattern = {}, options = {})
88+
def normalize!(*args)
89+
hash_pattern = args.shift
90+
options = args.shift || {}
91+
anonymous_subject_format = options.fetch(:anonymous_subject_format, '__%s__')
8992
raise ArgumentError, "invalid hash pattern: #{hash_pattern.inspect}" unless hash_pattern.is_a?(Hash)
9093

9194
counter = RDF::Query::HashPatternNormalizer::Counter.new
9295

93-
anonymous_subject_format = (options[:anonymous_subject_format] || '__%s__').to_s
94-
9596
hash_pattern.inject({}) { |acc, pair|
9697
subject, predicate_to_object = pair
9798

@@ -184,7 +185,7 @@ def initialize(**options)
184185
# the query pattern as a hash.
185186
# @return [Hash{Symbol => Object}]
186187
# the resulting query pattern as a normalized hash.
187-
def normalize!(**hash_pattern)
188+
def normalize!(hash_pattern)
188189
self.class.normalize!(hash_pattern, @options)
189190
end
190191
end # RDF::Query::HashPatternNormalizer

0 commit comments

Comments
 (0)