Skip to content

Commit

Permalink
Fixed the duck-typing logic in RDF::Literal subclass constructors; al…
Browse files Browse the repository at this point in the history
…so added some more code comments and unified the coding conventions.
  • Loading branch information
artob committed Jun 28, 2010
1 parent b49abfe commit 51d2abb
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 37 deletions.
2 changes: 1 addition & 1 deletion lib/rdf/model/literal.rb
Expand Up @@ -162,7 +162,7 @@ def object
def literal?
true
end

##
# Returns `false`.
#
Expand Down
9 changes: 5 additions & 4 deletions lib/rdf/model/literal/date.rb
Expand Up @@ -6,7 +6,7 @@ module RDF; class Literal
# @since 0.2.1
class Date < Literal
DATATYPE = XSD.date
GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z)
GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze

##
# @param [Date] value
Expand All @@ -16,7 +16,8 @@ def initialize(value, options = {})
@string = options[:lexical] if options.has_key?(:lexical)
@string = value if !defined?(@string) && value.is_a?(String)
@object = case
when value.respond_to?(:xmlschema) then value.to_date
when value.is_a?(::Date) then value
when value.respond_to?(:to_date) then value.to_date # Ruby 1.9+
else ::Date.parse(value.to_s)
end
end
Expand All @@ -27,7 +28,7 @@ def initialize(value, options = {})
# @return [Literal]
# @see http://www.w3.org/TR/xmlschema-2/#date
def canonicalize
@string = @object.strftime("%Y-%m-%d%Z").sub(/\+00:00|UTC/, "Z")
@string = @object.strftime('%Y-%m-%d%Z').sub(/\+00:00|UTC/, 'Z')
self
end

Expand All @@ -36,7 +37,7 @@ def canonicalize
#
# @return [String]
def to_s
@string || @object.strftime("%Y-%m-%d%Z").sub(/\+00:00|UTC/, "Z")
@string || @object.strftime('%Y-%m-%d%Z').sub(/\+00:00|UTC/, 'Z')
end
end # class Date
end; end # class RDF::Literal
9 changes: 5 additions & 4 deletions lib/rdf/model/literal/datetime.rb
Expand Up @@ -6,7 +6,7 @@ module RDF; class Literal
# @since 0.2.1
class DateTime < Literal
DATATYPE = XSD.dateTime
GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z)
GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze

##
# @param [DateTime] value
Expand All @@ -16,7 +16,8 @@ def initialize(value, options = {})
@string = options[:lexical] if options.has_key?(:lexical)
@string = value if !defined?(@string) && value.is_a?(String)
@object = case
when value.respond_to?(:xmlschema) then value.to_datetime
when value.is_a?(::DateTime) then value
when value.respond_to?(:to_datetime) then value.to_datetime # Ruby 1.9+
else ::DateTime.parse(value.to_s)
end
end
Expand All @@ -27,7 +28,7 @@ def initialize(value, options = {})
# @return [Literal]
# @see http://www.w3.org/TR/xmlschema-2/#dateTime
def canonicalize
@string = @object.strftime("%Y-%m-%dT%H:%M:%S%Z").sub(/\+00:00|UTC/, "Z")
@string = @object.strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
self
end

Expand All @@ -36,7 +37,7 @@ def canonicalize
#
# @return [String]
def to_s
@string || @object.strftime("%Y-%m-%dT%H:%M:%S%Z").sub(/\+00:00|UTC/, "Z")
@string || @object.strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
end
end # class DateTime
end; end # class RDF::Literal
16 changes: 9 additions & 7 deletions lib/rdf/model/literal/decimal.rb
Expand Up @@ -77,15 +77,17 @@ def to_d
def to_r
@object.to_r # only available on Ruby 1.9+
end

private

def to_canonical
# Can't use simple %f transformation do to special requirements from N3 tests in representation
i, f = @object.to_s("F").split(".")
f = f.to_s[0,16] # Truncate after 15 decimal places
i.sub!(/^\+?0+(\d)$/, '\1')
f.sub!(/0*$/, '')
f = "0" if f.empty?
# Can't use simple %f transformation due to special requirements from
# N3 tests in representation
i, f = @object.to_s('F').split('.')
i.sub!(/^\+?0+(\d)$/, '\1') # remove the optional leading '+' sign and any extra leading zeroes
f = f[0, 16] # truncate the fractional part after 15 decimal places
f.sub!(/0*$/, '') # remove any trailing zeroes
f = '0' if f.empty? # ...but there must be a digit to the right of the decimal point
"#{i}.#{f}"
end
end # class Decimal
Expand Down
25 changes: 14 additions & 11 deletions lib/rdf/model/literal/double.rb
Expand Up @@ -29,7 +29,7 @@ def initialize(value, options = {})
# @return [Literal]
# @see http://www.w3.org/TR/xmlschema-2/#double
def canonicalize
@string = to_canonical
@string = to_canonical if @object
self
end

Expand Down Expand Up @@ -72,19 +72,22 @@ def to_d
def to_r
@object.to_r # only available on Ruby 1.9+
end

private

def to_canonical
# Can't use simple %f transformation do to special requirements from N3 tests in representation
# Can't use simple %f transformation due to special requirements from
# N3 tests in representation
case
when @object.nan? then 'NaN'
when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
else
i, f, e = ("%.16E" % @object.to_f).split(/[\.E]/)
f.sub!(/0*$/, '')
f = "0" if f.empty?
e.sub!(/^\+?0+(\d)$/, '\1')
"#{i}.#{f}E#{e}"
when @object.nan? then 'NaN'
when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
when @object.zero? then '0.0E0'
else
i, f, e = ('%.16E' % @object.to_f).split(/[\.E]/)
f.sub!(/0*$/, '') # remove any trailing zeroes
f = '0' if f.empty? # ...but there must be a digit to the right of the decimal point
e.sub!(/^\+?0+(\d)$/, '\1') # remove the optional leading '+' sign and any extra leading zeroes
"#{i}.#{f}E#{e}"
end
end
end # class Double
Expand Down
2 changes: 1 addition & 1 deletion lib/rdf/model/literal/integer.rb
Expand Up @@ -29,7 +29,7 @@ def initialize(value, options = {})
# @return [Literal]
# @see http://www.w3.org/TR/xmlschema-2/#integer
def canonicalize
@string = @object.to_s
@string = @object.to_s if @object
self
end

Expand Down
25 changes: 16 additions & 9 deletions lib/rdf/model/literal/time.rb
@@ -1,15 +1,16 @@
module RDF; class Literal
##
# A date/time literal.
# A time literal.
#
# The lexical representation for time is the left truncated lexical representation for
# dateTime: hh:mm:ss.sss with optional following time zone indicator.
# The lexical representation for time is the left truncated lexical
# representation for `xsd:dateTime`: "hh:mm:ss.sss" with an optional
# following time zone indicator.
#
# @see http://www.w3.org/TR/xmlschema-2/#time
# @since 0.2.1
class Time < Literal
DATATYPE = XSD.time
GRAMMAR = %r(\A\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z)
GRAMMAR = %r(\A\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze

##
# @param [Time] value
Expand All @@ -19,21 +20,27 @@ def initialize(value, options = {})
@string = options[:lexical] if options.has_key?(:lexical)
@string = value if !defined?(@string) && value.is_a?(String)
@object = case
when value.respond_to?(:xmlschema) then value.to_time
when value.is_a?(::Time) then value
when value.respond_to?(:to_time) then value.to_time # Ruby 1.9+
else ::Time.parse(value.to_s)
end
end

##
# Converts the literal into its canonical lexical representation.
#
# 3.2.8.2 Canonical representation
# The canonical representation for time is defined by prohibiting certain options from the Lexical representation (§3.2.8.1). Specifically, either the time zone must be omitted or, if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z". Additionally, the canonical representation for midnight is 00:00:00.
# §3.2.8.2 Canonical representation
#
# The canonical representation for time is defined by prohibiting
# certain options from the Lexical representation (§3.2.8.1).
# Specifically, either the time zone must be omitted or, if present, the
# time zone must be Coordinated Universal Time (UTC) indicated by a "Z".
# Additionally, the canonical representation for midnight is 00:00:00.
#
# @return [Literal]
# @see http://www.w3.org/TR/xmlschema-2/#time
def canonicalize
@string = @object.strftime("%H:%M:%S%Z").sub(/\+00:00|UTC/, "Z")
@string = @object.strftime('%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
self
end

Expand All @@ -42,7 +49,7 @@ def canonicalize
#
# @return [String]
def to_s
@string || @object.strftime("%H:%M:%S%Z").sub(/\+00:00|UTC/, "Z")
@string || @object.strftime('%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
end
end # class Time
end; end # class RDF::Literal

0 comments on commit 51d2abb

Please sign in to comment.