rdf 3.0.3 → 3.0.4

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: cbddc1758793b9251e0f2e6570a5a222bf32aa39fcc2e73d1d454b84af90062a
4
- data.tar.gz: 4ad7cca943663997855d26d6a741138c0bad7ad3258d8a8fa081e701d5657785
3
+ metadata.gz: 932836f4b2fae338cfabd3acc588c98b035868f4d8ec5a1d92fbd035ef25f23f
4
+ data.tar.gz: 7b173b18ff4586198f5554083d12df3147d3a1f1cb363078ee0d3e92dcb6b9aa
5
5
  SHA512:
6
- metadata.gz: 587ff46cfde46b088a9b5994a350bffffc189c96e26a6c9c426ae204b731872858c6b80379a36b3b17c69192b47b81f67b005bd728fd858a0db385f44e70e09e
7
- data.tar.gz: 0a048848ce6db55add239882c35a2e0df981ec9ea0afbd3070f1cde536168382d00177a6d2467e196d69ee14a816367c29133263d39c921b5876af63b4dd1d19
6
+ metadata.gz: f7833c0a0177907b32702d1ccf8b34b26e0f3c78525f46b35277995e7bb377e1bbe7cf28d01a189d42ae29515c58e7b80ab70e2068fc6d9eb379460e15ab0496
7
+ data.tar.gz: 5afb152c0526dc5efd5784a2e2496f52f1668bef49ba942885981cfefe1c485326f68c76456bb2c13720c396454558218a4fbe6585372c36a2a7c3cbfc9f2540
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.3
1
+ 3.0.4
data/lib/rdf.rb CHANGED
@@ -4,6 +4,7 @@ require 'date'
4
4
  require 'time'
5
5
 
6
6
  require 'rdf/version'
7
+ require 'rdf/extensions'
7
8
 
8
9
  module RDF
9
10
  # RDF mixins
@@ -197,7 +198,7 @@ module RDF
197
198
  # @return [#to_s] property
198
199
  # @return [URI]
199
200
  def self.[](property)
200
- property.to_s =~ %r{_\d+} ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV[property]
201
+ property.to_s.match?(%r{_\d+}) ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV[property]
201
202
  end
202
203
 
203
204
  ##
@@ -227,7 +228,7 @@ module RDF
227
228
  def self.method_missing(property, *args, &block)
228
229
  if args.empty?
229
230
  # Special-case rdf:_n for all integers
230
- RDF_N_REGEXP.match(property) ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV.send(property)
231
+ RDF_N_REGEXP.match?(property) ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV.send(property)
231
232
  else
232
233
  super
233
234
  end
@@ -0,0 +1,22 @@
1
+ ##
2
+ # This file provides compatibility monkeypatches to standard library classes
3
+ # Implementation taken from MIT-licensed https://github.com/marcandre/backports
4
+ #
5
+
6
+ # https://github.com/marcandre/backports/blob/master/lib/backports/2.4.0/regexp/match.rb
7
+ unless Regexp.method_defined? :match?
8
+ class Regexp
9
+ def match?(*args)
10
+ !match(*args).nil?
11
+ end
12
+ end
13
+ end
14
+
15
+ # https://github.com/marcandre/backports/blob/master/lib/backports/2.4.0/string/match.rb
16
+ unless String.method_defined? :match?
17
+ class String
18
+ def match?(*args)
19
+ !match(*args).nil?
20
+ end
21
+ end
22
+ end
@@ -100,11 +100,12 @@ module RDF
100
100
 
101
101
  ##
102
102
  # Validate the list ensuring that
103
+ # * each node is referenced exactly once (except for the head, which may have no reference)
103
104
  # * rdf:rest values are all BNodes are nil
104
105
  # * each subject has exactly one value for `rdf:first` and
105
106
  # `rdf:rest`.
106
107
  # * The value of `rdf:rest` must be either a BNode or `rdf:nil`.
107
- # * All other properties are ignored.
108
+ # * only the list head may have any other properties
108
109
  # @return [Boolean]
109
110
  def valid?
110
111
  li = subject
@@ -123,12 +124,25 @@ module RDF
123
124
  rest = st.object
124
125
  return false unless rest.node? || rest == RDF.nil
125
126
  rests += 1
127
+ when RDF.type
128
+ else
129
+ # It may have no other properties
130
+ return false unless li == subject
126
131
  end
127
132
  end
128
133
  return false unless firsts == 1 && rests == 1
129
134
  li = rest
130
135
  end
131
- true
136
+
137
+ # All elements other than the head must be referenced exactly once
138
+ return list_nodes.all? do |li|
139
+ refs = @graph.query(object: li).count
140
+ case refs
141
+ when 0 then li == subject
142
+ when 1 then true
143
+ else false
144
+ end
145
+ end
132
146
  end
133
147
 
134
148
  # @!attribute [r] subject
@@ -363,7 +363,7 @@ module RDF
363
363
  return false if language? && language.to_s !~ /^[a-zA-Z]+(-[a-zA-Z0-9]+)*$/
364
364
  return false if datatype? && datatype.invalid?
365
365
  grammar = self.class.const_get(:GRAMMAR) rescue nil
366
- grammar.nil? || !!(value =~ grammar)
366
+ grammar.nil? || value.match?(grammar)
367
367
  end
368
368
 
369
369
  ##
@@ -1006,7 +1006,7 @@ module RDF
1006
1006
  def path=(value)
1007
1007
  if value
1008
1008
  # Always lead with a slash
1009
- value = "/#{value}" if host && value.to_s =~ /^[^\/]/
1009
+ value = "/#{value}" if host && value.to_s.match?(/^[^\/]/)
1010
1010
  object[:path] = value.to_s.force_encoding(Encoding::UTF_8)
1011
1011
  else
1012
1012
  object[:path] = nil
@@ -36,7 +36,7 @@ module RDF
36
36
  # @param [String] sample Beginning several bytes (about 1K) of input.
37
37
  # @return [Boolean]
38
38
  def self.detect(sample)
39
- !!sample.match(%r(
39
+ sample.match?(%r(
40
40
  (?:\s*(?:<[^>]*>) | (?:_:\w+)) # Subject
41
41
  \s*
42
42
  (?:\s*<[^>]*>) # Predicate
@@ -46,8 +46,8 @@ module RDF
46
46
  (?:\s*(?:<[^>]*>) | (?:_:\w+)) # Graph Name
47
47
  \s*\.
48
48
  )x) && !(
49
- sample.match(%r(@(base|prefix|keywords)|\{)) || # Not Turtle/N3/TriG
50
- sample.match(%r(<(html|rdf))i) # Not HTML or XML
49
+ sample.match?(%r(@(base|prefix|keywords)|\{)) || # Not Turtle/N3/TriG
50
+ sample.match?(%r(<(html|rdf))i) # Not HTML or XML
51
51
  )
52
52
  end
53
53
 
@@ -32,7 +32,7 @@ module RDF::NTriples
32
32
  # @param [String] sample Beginning several bytes (about 1K) of input.
33
33
  # @return [Boolean]
34
34
  def self.detect(sample)
35
- !!sample.match(%r(
35
+ sample.match?(%r(
36
36
  (?:(?:<[^>]*>) | (?:_:\w+)) # Subject
37
37
  \s*
38
38
  (?:<[^>]*>) # Predicate
@@ -40,8 +40,8 @@ module RDF::NTriples
40
40
  (?:(?:<[^>]*>) | (?:_:\w+) | (?:"[^"\n]*"(?:^^|@\S+)?)) # Object
41
41
  \s*\.
42
42
  )x) && !(
43
- sample.match(%r(@(base|prefix|keywords)|\{)) || # Not Turtle/N3/TriG
44
- sample.match(%r(<(html|rdf))i) # Not HTML or XML
43
+ sample.match?(%r(@(base|prefix|keywords)|\{)) || # Not Turtle/N3/TriG
44
+ sample.match?(%r(<(html|rdf))i) # Not HTML or XML
45
45
  ) && !RDF::NQuads::Format.detect(sample)
46
46
  end
47
47
 
@@ -154,6 +154,14 @@ module RDF::NTriples
154
154
  end
155
155
  end
156
156
 
157
+ # cache constants to optimize escaping the escape chars in self.unescape
158
+ ESCAPE_CHARS_ESCAPED = ESCAPE_CHARS.each_with_object({}) do |escape, memo|
159
+ memo[escape.inspect[1...-1]] = escape
160
+ end.freeze
161
+ ESCAPE_CHARS_ESCAPED_REGEXP = Regexp.union(
162
+ ESCAPE_CHARS_ESCAPED.keys
163
+ ).freeze
164
+
157
165
  ##
158
166
  # @param [String] string
159
167
  # @return [String]
@@ -161,15 +169,26 @@ module RDF::NTriples
161
169
  # @see http://blog.grayproductions.net/articles/understanding_m17n
162
170
  # @see http://yehudakatz.com/2010/05/17/encodings-unabridged/
163
171
  def self.unescape(string)
164
- string = string.dup.force_encoding(Encoding::UTF_8)
172
+ # Note: avoiding copying the input string when no escaping is needed
173
+ # greatly reduces the number of allocations and the processing time.
174
+ unless string.encoding == Encoding::UTF_8
175
+ string = string.dup.force_encoding(Encoding::UTF_8)
176
+ end
177
+
178
+ has_escape_chars = ESCAPE_CHARS_ESCAPED_REGEXP.match?(string)
179
+ has_uchar = UCHAR.match?(string)
165
180
 
166
- # Decode \t|\n|\r|\"|\\ character escapes:
167
- ESCAPE_CHARS.each { |escape| string.gsub!(escape.inspect[1...-1], escape) }
181
+ string = string.dup if has_escape_chars || has_uchar
182
+
183
+ # Decode \t|\n|\r|\"|\\ character escapes using Regexp:
184
+ string.gsub!(ESCAPE_CHARS_ESCAPED_REGEXP) do
185
+ ESCAPE_CHARS_ESCAPED.fetch($~[0])
186
+ end if has_escape_chars
168
187
 
169
188
  # Decode \uXXXX and \UXXXXXXXX code points:
170
189
  string.gsub!(UCHAR) do
171
190
  [($1 || $2).hex].pack('U*')
172
- end
191
+ end if has_uchar
173
192
 
174
193
  string
175
194
  end
@@ -56,7 +56,7 @@ module RDF::NTriples
56
56
  # @see http://www.w3.org/TR/rdf-testcases/#ntrip_strings
57
57
  def self.escape(string, encoding = nil)
58
58
  ret = case
59
- when string =~ ESCAPE_PLAIN # a shortcut for the simple case
59
+ when string.match?(ESCAPE_PLAIN) # a shortcut for the simple case
60
60
  string
61
61
  when string.ascii_only?
62
62
  StringIO.open do |buffer|
@@ -164,7 +164,7 @@ module RDF::NTriples
164
164
  # @return [String]
165
165
  # @raise [ArgumentError] if `value` is not an `RDF::Statement` or `RDF::Term`
166
166
  def self.serialize(value)
167
- writer = self.new
167
+ writer = (@serialize_writer_memo ||= self.new)
168
168
  case value
169
169
  when nil then nil
170
170
  when FalseClass then value.to_s
@@ -256,7 +256,7 @@ module RDF::NTriples
256
256
  def format_uri(uri, **options)
257
257
  string = uri.to_s
258
258
  iriref = case
259
- when string =~ ESCAPE_PLAIN_U # a shortcut for the simple case
259
+ when string.match?(ESCAPE_PLAIN_U) # a shortcut for the simple case
260
260
  string
261
261
  when string.ascii_only? || (encoding && encoding != Encoding::ASCII)
262
262
  StringIO.open do |buffer|
@@ -24,7 +24,7 @@ class RDF::Query
24
24
  # Undefine all superfluous instance methods:
25
25
  undef_method(*instance_methods.
26
26
  map(&:to_s).
27
- select {|m| m =~ /^\w+$/}.
27
+ select {|m| m.match?(/^\w+$/)}.
28
28
  reject {|m| %w(object_id dup instance_eval inspect to_s private_methods class should should_not pretty_print).include?(m) || m[0,2] == '__'}.
29
29
  map(&:to_sym))
30
30
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module RDF
2
3
  ##
3
4
  # The base class for RDF parsers.
@@ -610,7 +611,8 @@ module RDF
610
611
  def readline
611
612
  @line = @line_rest || @input.readline
612
613
  @line, @line_rest = @line.split("\r", 2)
613
- @line = @line.to_s.chomp
614
+ @line = String.new if @line.nil? # not frozen
615
+ @line.chomp!
614
616
  begin
615
617
  @line.encode!(encoding)
616
618
  rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError, Encoding::ConverterNotFoundError
@@ -290,7 +290,7 @@ module RDF; module Util
290
290
  filename_or_url = $1 if filename_or_url.to_s.match(/^file:(.*)$/)
291
291
  remote_document = nil
292
292
 
293
- if filename_or_url.to_s =~ /^https?/
293
+ if filename_or_url.to_s.match?(/^https?/)
294
294
  base_uri = filename_or_url.to_s
295
295
 
296
296
  remote_document = self.http_adapter(!!options[:use_net_http]).
@@ -1,5 +1,6 @@
1
1
  # coding: utf-8
2
2
  require 'logger'
3
+ require 'delegate'
3
4
 
4
5
  module RDF; module Util
5
6
  ##
@@ -8,6 +9,9 @@ module RDF; module Util
8
9
  # Modules must provide `@logger`, which returns an instance of `Logger`, or something responding to `#<<`. Logger may also be specified using an `@options` hash containing a `:logger` entry.
9
10
  # @since 2.0.0
10
11
  module Logger
12
+ # The IOWrapper class is used to store per-logger state while wrapping an IO such as $stderr.
13
+ IOWrapper = DelegateClass(IO)
14
+
11
15
  ##
12
16
  # Logger instance, found using `options[:logger]`, `@logger`, or `@options[:logger]`
13
17
  # @param [Hash{Symbol => Object}] options
@@ -18,7 +22,7 @@ module RDF; module Util
18
22
  logger = @options[:logger] if logger.nil? && @options
19
23
  if logger.nil?
20
24
  # Unless otherwise specified, use $stderr
21
- logger = (@options || options)[:logger] = $stderr
25
+ logger = (@options || options)[:logger] = IOWrapper.new($stderr)
22
26
 
23
27
  # Reset log_statistics so that it's not inherited across different instances
24
28
  logger.log_statistics.clear if logger.respond_to?(:log_statistics)
@@ -620,7 +620,7 @@ module RDF
620
620
  # Undefine all superfluous instance methods:
621
621
  undef_method(*instance_methods.
622
622
  map(&:to_s).
623
- select {|m| m =~ /^\w+$/}.
623
+ select {|m| m.match?(/^\w+$/)}.
624
624
  reject {|m| %w(object_id dup instance_eval inspect to_s class send public_send).include?(m) || m[0,2] == '__'}.
625
625
  map(&:to_sym))
626
626
 
@@ -892,7 +892,7 @@ module RDF
892
892
  # @since 0.3.9
893
893
  def valid?
894
894
  # Validate relative to RFC3987
895
- node? || RDF::URI::IRI.match(to_s) || false
895
+ node? || RDF::URI::IRI.match?(to_s) || false
896
896
  end
897
897
 
898
898
  ##
@@ -927,7 +927,7 @@ module RDF
927
927
  # Is this neither a class, property or datatype term?
928
928
  # @return [Boolean]
929
929
  def other?
930
- Array(self.type).none? {|t| t.to_s =~ /(Class|Property|Datatype|Restriction)/}
930
+ Array(self.type).none? {|t| t.to_s.match?(/(Class|Property|Datatype|Restriction)/)}
931
931
  end
932
932
 
933
933
  ##
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.3
4
+ version: 3.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-09-09 00:00:00.000000000 Z
13
+ date: 2018-09-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: link_header
@@ -218,6 +218,7 @@ files:
218
218
  - lib/rdf.rb
219
219
  - lib/rdf/changeset.rb
220
220
  - lib/rdf/cli.rb
221
+ - lib/rdf/extensions.rb
221
222
  - lib/rdf/format.rb
222
223
  - lib/rdf/mixin/countable.rb
223
224
  - lib/rdf/mixin/durable.rb