Class: RDF::Literal
- Inherits:
-
Object
- Object
- RDF::Literal
- Includes:
- Term
- Defined in:
- lib/rdf/model/literal.rb,
lib/rdf/model/literal/date.rb,
lib/rdf/model/literal/time.rb,
lib/rdf/model/literal/token.rb,
lib/rdf/model/literal/double.rb,
lib/rdf/model/literal/boolean.rb,
lib/rdf/model/literal/decimal.rb,
lib/rdf/model/literal/integer.rb,
lib/rdf/model/literal/numeric.rb,
lib/rdf/model/literal/datetime.rb,
lib/rdf/model/literal/temporal.rb
Overview
An RDF literal.
Subclasses of Literal should define DATATYPE and GRAMMAR constants, which are used for identifying the appropriate class to use for a datatype URI and to perform lexical matching on the value.
Literal comparison with other Value instances call Value#type_error, which, returns false. Implementations wishing to have TypeError raised should mix-in TypeCheck. This is required for strict SPARQL conformance.
Specific typed literals may have behavior different from the default implementation. See the following defined sub-classes for specific documentation. Additional sub-classes may be defined, and will interoperate by defining DATATYPE
and GRAMMAR
constants, in addition other required overrides of RDF::Literal behavior.
In RDF 1.1, all literals are typed, including plain literals and language tagged literals. Internally, plain literals are given the xsd:string
datatype and language tagged literals are given the rdf:langString
datatype. Creating a plain literal, without a datatype or language, will automatically provide the xsd:string
datatype; similar for language tagged literals. Note that most serialization formats will remove this datatype. Code which depends on a literal having the xsd:string
datatype being different from a plain literal (formally, without a datatype) may break. However note that the #has\_datatype?
will continue to return false
for plain or language-tagged literals.
Defined Under Namespace
Classes: Boolean, Date, DateTime, Decimal, Double, Integer, Numeric, Temporal, Time, Token
Constant Summary collapse
Instance Attribute Summary collapse
-
#datatype ⇒ URI
The XML Schema datatype URI (optional).
-
#language ⇒ Symbol
The language tag (optional).
Instance Method Summary collapse
-
#<=>(other) ⇒ Integer
Compares
self
toother
for sorting purposes (with type check). -
#==(other) ⇒ Boolean
(also: #===)
Returns
true
if this literal is equivalent toother
(with type check). -
#canonicalize! ⇒ RDF::Literal
Converts this literal into its canonical lexical representation.
-
#compatible?(other) ⇒ Boolean
Term compatibility according to SPARQL.
-
#comperable_datatype2?(other) ⇒ Boolean
Returns
true
if the literals are comperable. -
#comperable_datatype?(other) ⇒ Boolean
Returns
true
if the literal has a datatype and the comparison should return false instead of raise a type error. -
#datatype? ⇒ Boolean
(also: #has_datatype?, #typed?, #datatyped?)
Returns
true
if this is a datatyped literal. -
#eql?(other) ⇒ Boolean
Determins if
self
is the same term asother
. -
#escape(string) ⇒ String
Escape a literal using ECHAR escapes.
-
#hash ⇒ Integer
Returns a hash code for this literal.
-
#humanize(lang = :en) ⇒ String
Returns a human-readable value for the literal.
-
#initialize(value, language: nil, datatype: nil, lexical: nil, validate: false, canonicalize: false, **options) ⇒ Literal
constructor
Literals without a datatype are given either xsd:string or rdf:langString depending on if there is language.
-
#inspect ⇒ String
Returns a developer-friendly representation of
self
. -
#language? ⇒ Boolean
(also: #has_language?)
Returns
true
if this is a language-tagged literal. -
#literal? ⇒ Boolean
Returns
true
. -
# ⇒ String
protected
This method is implemented when the datatype is
xsd:string
orrdf:langString
. - #object ⇒ Object
-
#plain? ⇒ Boolean
Returns
true
if this is a plain literal. - #respond_to_missing?(name, include_private = false) ⇒ Boolean protected
-
#simple? ⇒ Boolean
Returns
true
if this is a simple literal. -
#squish(*other_string) ⇒ RDF::Literal
Returns the literal, first removing all whitespace on both ends of the value, and then changing remaining consecutive whitespace groups into one space each.
-
#squish! ⇒ Object
Performs a destructive #squish.
-
#to_s ⇒ String
Returns the value as a string.
-
#valid? ⇒ Boolean
Returns
true
if the value adheres to the defined grammar of the datatype. -
#validate! ⇒ RDF::Literal
Validates the value using Value#valid?, raising an error if the value is invalid.
-
#value ⇒ String
Returns the value as a string.
-
#value_hash ⇒ Integer
Returns a hash code for the value.
Methods included from Term
#term?, #terms, #to_base, #to_term
Methods included from Value
#anonymous?, #canonicalize, #constant?, #graph?, #inspect!, #invalid?, #iri?, #list?, #node?, #resource?, #start_with?, #statement?, #term?, #to_nquads, #to_ntriples, #to_rdf, #to_term, #type_error, #uri?, #variable?
Constructor Details
#initialize(value, language: nil, datatype: nil, lexical: nil, validate: false, canonicalize: false, **options) ⇒ Literal
Literals without a datatype are given either xsd:string or rdf:langString depending on if there is language
166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/rdf/model/literal.rb', line 166 def initialize(value, language: nil, datatype: nil, lexical: nil, validate: false, canonicalize: false, **) @object = value.freeze @string = lexical if lexical @string = value if !defined?(@string) && value.is_a?(String) @string = @string.encode(Encoding::UTF_8).freeze if instance_variable_defined?(:@string) @object = @string if instance_variable_defined?(:@string) && @object.is_a?(String) @language = language.to_s.downcase.to_sym if language @datatype = RDF::URI(datatype).freeze if datatype @datatype ||= self.class.const_get(:DATATYPE) if self.class.const_defined?(:DATATYPE) @datatype ||= instance_variable_defined?(:@language) && @language ? RDF.langString : RDF::URI("http://www.w3.org/2001/XMLSchema#string") end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
Instance Attribute Details
#datatype ⇒ URI
Returns The XML Schema datatype URI (optional).
145 146 147 |
# File 'lib/rdf/model/literal.rb', line 145 def datatype @datatype end |
#language ⇒ Symbol
Returns The language tag (optional).
142 143 144 |
# File 'lib/rdf/model/literal.rb', line 142 def language @language end |
Instance Method Details
#<=>(other) ⇒ Integer
Compares self
to other
for sorting purposes (with type check).
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/rdf/model/literal.rb', line 317 def <=>(other) case other when Literal case when self.eql?(other) 0 when self.language? && other.language? # Literals with languages can compare if languages are identical self.to_s <=> other.to_s when self.simple? && other.simple? self.to_s <=> other.to_s when !self.valid? type_error("#{self.inspect} is invalid") || 0 when !other.valid? type_error("#{other.inspect} is invalid") || 0 when self.comperable_datatype2?(other) self.object <=> other.object else type_error("#{self.inspect} and #{other.inspect} are not comperable") || 0 end when String self.simple? && self.value <=> other else 1 end end |
#==(other) ⇒ Boolean Also known as: ===
Returns true
if this literal is equivalent to other
(with type check).
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/rdf/model/literal.rb', line 287 def ==(other) case other when Literal case when self.eql?(other) true when self.language? && self.language.to_s == other.language.to_s # Literals with languages can compare if languages are identical self.value_hash == other.value_hash && self.value == other.value when self.simple? && other.simple? self.value_hash == other.value_hash && self.value == other.value when other.comperable_datatype?(self) || self.comperable_datatype?(other) # Comparing plain with undefined datatypes does not generate an error, but returns false # From data-r2/expr-equal/eq-2-2. false else type_error("unable to determine whether #{self.inspect} and #{other.inspect} are equivalent") end when String self.simple? && self.value.eql?(other) else false end end |
#canonicalize! ⇒ RDF::Literal
Converts this literal into its canonical lexical representation.
Subclasses should override this as needed and appropriate.
461 462 463 |
# File 'lib/rdf/model/literal.rb', line 461 def canonicalize! self end |
#compatible?(other) ⇒ Boolean
Term compatibility according to SPARQL
Compatibility of two arguments is defined as:
- The arguments are simple literals or literals typed as xsd:string
- The arguments are plain literals with identical language tags
- The first argument is a plain literal with language tag and the second argument is a simple literal or literal typed as xsd:string
223 224 225 226 227 228 229 230 231 232 |
# File 'lib/rdf/model/literal.rb', line 223 def compatible?(other) return false unless other.literal? && plain? && other.plain? # * The arguments are simple literals or literals typed as xsd:string # * The arguments are plain literals with identical language tags # * The first argument is a plain literal with language tag and the second argument is a simple literal or literal typed as xsd:string language? ? (language == other.language || other.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string")) : other.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string") end |
#comperable_datatype2?(other) ⇒ Boolean
Returns true
if the literals are comperable.
Used for <=> operator.
440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/rdf/model/literal.rb', line 440 def comperable_datatype2?(other) case self when RDF::Literal::Numeric, RDF::Literal::Boolean case other when RDF::Literal::Numeric, RDF::Literal::Boolean true else false end else self.datatype == other.datatype end end |
#comperable_datatype?(other) ⇒ Boolean
Returns true
if the literal has a datatype and the comparison should
return false instead of raise a type error.
This behavior is intuited from SPARQL data-r2/expr-equal/eq-2-2
420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/rdf/model/literal.rb', line 420 def comperable_datatype?(other) return false unless self.plain? || self.language? case other when RDF::Literal::Numeric, RDF::Literal::Boolean, RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime # Invald types can be compared without raising a TypeError if literal has a language (open-eq-08) !other.valid? && self.language? else # An unknown datatype may not be used for comparison, unless it has a language? (open-eq-8) self.language? end end |
#datatype? ⇒ Boolean Also known as: has_datatype?, typed?, datatyped?
Returns true
if this is a datatyped literal.
For historical reasons, this excludes xsd:string and rdf:langString
382 383 384 |
# File 'lib/rdf/model/literal.rb', line 382 def datatype? !plain? && !language? end |
#eql?(other) ⇒ Boolean
Determins if self
is the same term as other
.
267 268 269 270 271 272 273 274 |
# File 'lib/rdf/model/literal.rb', line 267 def eql?(other) self.equal?(other) || (self.class.eql?(other.class) && self.value_hash == other.value_hash && self.value.eql?(other.value) && self.language.to_s.eql?(other.language.to_s) && self.datatype.eql?(other.datatype)) end |
#escape(string) ⇒ String
N-Triples only requires '\"\n\r' to be escaped.
Escape a literal using ECHAR escapes.
ECHAR ::= '\' [tbnrf"']
499 500 501 502 503 504 505 506 507 508 |
# File 'lib/rdf/model/literal.rb', line 499 def escape(string) string.gsub('\\', '\\\\'). gsub("\t", '\\t'). gsub("\b", '\\b'). gsub("\n", '\\n'). gsub("\r", '\\r'). gsub("\f", '\\f'). gsub('"', '\\"'). freeze end |
#hash ⇒ Integer
Returns a hash code for this literal.
238 239 240 |
# File 'lib/rdf/model/literal.rb', line 238 def hash @hash ||= [to_s, datatype, language].hash end |
#humanize(lang = :en) ⇒ String
Returns a human-readable value for the literal
523 524 525 |
# File 'lib/rdf/model/literal.rb', line 523 def humanize(lang = :en) to_s.freeze end |
#inspect ⇒ String
Returns a developer-friendly representation of self
.
531 532 533 |
# File 'lib/rdf/model/literal.rb', line 531 def inspect sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, RDF::NTriples.serialize(self)) end |
#language? ⇒ Boolean Also known as: has_language?
Returns true
if this is a language-tagged literal.
370 371 372 |
# File 'lib/rdf/model/literal.rb', line 370 def language? datatype == RDF.langString end |
#literal? ⇒ Boolean
Returns true
.
196 197 198 |
# File 'lib/rdf/model/literal.rb', line 196 def literal? true end |
#object ⇒ Object
188 189 190 |
# File 'lib/rdf/model/literal.rb', line 188 def object defined?(@object) ? @object : value end |
#plain? ⇒ Boolean
Returns true
if this is a plain literal. A plain literal
may have a language, but may not have a datatype. For
all practical purposes, this includes xsd:string literals
too.
351 352 353 |
# File 'lib/rdf/model/literal.rb', line 351 def plain? [RDF.langString, RDF::URI("http://www.w3.org/2001/XMLSchema#string")].include?(datatype) end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean (protected)
549 550 551 552 553 554 555 |
# File 'lib/rdf/model/literal.rb', line 549 def respond_to_missing?(name, include_private = false) case name when :to_str return true if @datatype == RDF.langString || @datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string") end super end |
#simple? ⇒ Boolean
Returns true
if this is a simple literal.
A simple literal has no datatype or language.
361 362 363 |
# File 'lib/rdf/model/literal.rb', line 361 def simple? datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string") end |
#squish(*other_string) ⇒ RDF::Literal
Returns the literal, first removing all whitespace on both ends of the value, and then changing remaining consecutive whitespace groups into one space each.
Note that it handles both ASCII and Unicode whitespace.
472 473 474 |
# File 'lib/rdf/model/literal.rb', line 472 def squish(*other_string) self.dup.squish! end |
#squish! ⇒ Object
Performs a destructive #squish.
481 482 483 484 485 486 487 |
# File 'lib/rdf/model/literal.rb', line 481 def squish! @string = value. gsub(/\A[[:space:]]+/, ''). gsub(/[[:space:]]+\z/, ''). gsub(/[[:space:]]+/, ' ') self end |
#to_s ⇒ String
Returns the value as a string.
514 515 516 |
# File 'lib/rdf/model/literal.rb', line 514 def to_s @object.to_s.freeze end |
#valid? ⇒ Boolean
Returns true
if the value adheres to the defined grammar of the
datatype.
395 396 397 398 399 400 |
# File 'lib/rdf/model/literal.rb', line 395 def valid? return false if language? && language.to_s !~ /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/ return false if datatype? && datatype.invalid? grammar = self.class.const_get(:GRAMMAR) rescue nil grammar.nil? || value.match?(grammar) end |
#validate! ⇒ RDF::Literal
Validates the value using Value#valid?, raising an error if the value is invalid.
409 410 411 412 |
# File 'lib/rdf/model/literal.rb', line 409 def validate! raise ArgumentError, "#{to_s.inspect} is not a valid <#{datatype.to_s}> literal" if invalid? self end |
#value ⇒ String
Returns the value as a string.
182 183 184 |
# File 'lib/rdf/model/literal.rb', line 182 def value instance_variable_defined?(:@string) && @string || to_s end |
#value_hash ⇒ Integer
Returns a hash code for the value.
247 248 249 |
# File 'lib/rdf/model/literal.rb', line 247 def value_hash @value_hash ||= value.hash end |