Class: RDF::Literal::Decimal

Inherits:
Numeric show all
Defined in:
lib/rdf/model/literal/decimal.rb

Overview

A decimal literal.

Examples:

Arithmetic with decimal literals

RDF::Literal(BigDecimal('1.0')) + 0.5   #=> RDF::Literal(BigDecimal('1.5'))
RDF::Literal(BigDecimal('1.0')) - 0.5   #=> RDF::Literal(BigDecimal('0.5'))
RDF::Literal(BigDecimal('1.0')) * 0.5   #=> RDF::Literal(BigDecimal('0.5'))
RDF::Literal(BigDecimal('1.0')) / 0.5   #=> RDF::Literal(BigDecimal('2.0'))

See Also:

Since:

  • 0.2.1

Direct Known Subclasses

Integer

Constant Summary collapse

DATATYPE =

Since:

  • 0.2.1

RDF::URI("http://www.w3.org/2001/XMLSchema#decimal")
GRAMMAR =

Since:

  • 0.2.1

/^[\+\-]?\d+(\.\d*)?$/.freeze

Constants inherited from RDF::Literal

FALSE, TRUE, ZERO

Instance Attribute Summary

Attributes inherited from RDF::Literal

#datatype, #language

Instance Method Summary collapse

Methods inherited from Numeric

#%, #*, #**, #+, #[email protected], #-, #[email protected], #/, #<=>, #==, #acos, #asin, #atan, #atan2, #cos, #exp, #exp10, #log, #log10, #sin, #sqrt, #tan, #to_d, #to_f, #to_i, #to_r

Methods inherited from RDF::Literal

#<=>, #==, #compatible?, #comperable_datatype2?, #comperable_datatype?, #datatype?, #eql?, #escape, #hash, #humanize, #inspect, #language?, #literal?, #method_missing, #object, #plain?, #respond_to_missing?, #simple?, #squish, #squish!, #valid?, #validate!, #value, #value_hash

Methods included from Term

#<=>, #==, #compatible?, #eql?, #escape, #term?, #terms, #to_base, #to_term

Methods included from Value

#anonymous?, #canonicalize, #constant?, #graph?, #inspect, #inspect!, #invalid?, #iri?, #list?, #literal?, #node?, #resource?, #start_with?, #statement?, #term?, #to_nquads, #to_ntriples, #to_rdf, #to_term, #type_error, #uri?, #valid?, #validate!, #variable?

Constructor Details

#initialize(value, datatype: nil, lexical: nil, **options) ⇒ Decimal

Returns a new instance of Decimal.

Parameters:

  • value (String, BidDecimal, Numeric)
  • value (Object)
  • language (Symbol)

    (nil) Language is downcased to ensure proper matching

  • lexical (String) (defaults to: nil)

    (nil) Supplied lexical representation of this literal, otherwise it comes from transforming value to a string form..

  • datatype (URI) (defaults to: nil)

    (nil)

  • validate (Boolean)

    (false)

  • canonicalize (Boolean)

    (false)

Since:

  • 0.2.1


20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rdf/model/literal/decimal.rb', line 20

def initialize(value, datatype: nil, lexical: nil, **options)
  @datatype = RDF::URI(datatype || self.class.const_get(:DATATYPE))
  @string   = lexical || (value if value.is_a?(String))
  @object   = case
    when value.is_a?(::BigDecimal) then value
    when value.is_a?(::Float)      then BigDecimal(value.to_s)
    when value.is_a?(::Numeric)    then BigDecimal(value)
    else
      value = value.to_s
      value += "0" if value.end_with?(".")  # Normalization required in Ruby 2.4
      BigDecimal(value) rescue BigDecimal(0)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RDF::Literal

Instance Method Details

#absRDF::Literal

Returns the absolute value of self.

From the XQuery function fn:abs.


62
63
64
# File 'lib/rdf/model/literal/decimal.rb', line 62

def abs
  (d = to_d) && d > 0 ? self : RDF::Literal(d.abs)
end

#canonicalize!RDF::Literal

Converts this literal into its canonical lexical representation.

Returns:

See Also:

Since:

  • 0.2.1


39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rdf/model/literal/decimal.rb', line 39

def canonicalize!
  # Can't use simple %f transformation due to special requirements from
  # N3 tests in representation
  @string = begin
    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
  @object = BigDecimal(@string) unless @object.nil?
  self
end

#ceilRDF::Literal::Integer

Returns the smallest integer greater than or equal to self.

From the XQuery function fn:ceil.

Examples:

RDF::Literal(1).ceil            #=> RDF::Literal(1)

Returns:

See Also:

Since:

  • 0.2.1


93
94
95
# File 'lib/rdf/model/literal/decimal.rb', line 93

def ceil
  RDF::Literal::Integer.new(to_d.ceil)
end

#floorRDF::Literal::Integer

Returns the largest integer less than or equal to self.

From the XQuery function fn:floor.

Examples:

RDF::Literal(1).floor            #=> RDF::Literal(1)

Returns:

See Also:

Since:

  • 0.2.1


107
108
109
# File 'lib/rdf/model/literal/decimal.rb', line 107

def floor
  RDF::Literal::Integer.new(to_d.floor)
end

#nonzero?Boolean

Returns self if the value is not zero, nil otherwise.

Returns:

Since:

  • 0.2.3


125
126
127
# File 'lib/rdf/model/literal/decimal.rb', line 125

def nonzero?
  to_d.nonzero? ? self : nil
end

#roundRDF::Literal::Decimal

Returns the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned. An error is raised if arg is not a numeric value.

From the XQuery function fn:round.


73
74
75
76
77
78
79
80
81
# File 'lib/rdf/model/literal/decimal.rb', line 73

def round
  rounded = to_d.round(half: (to_d < 0 ? :down : :up))
  if rounded == -0.0
    # to avoid -0.0
    self.class.new(0.0)
  else
    self.class.new(rounded)
  end
end

#to_sString

Returns the value as a string.

Returns:

See Also:

  • BigDecimal#to_s

Since:

  • 0.2.1


134
135
136
# File 'lib/rdf/model/literal/decimal.rb', line 134

def to_s
  @string || @object.to_s('F')
end

#zero?Boolean

Returns true if the value is zero.

Returns:

Since:

  • 0.2.3


116
117
118
# File 'lib/rdf/model/literal/decimal.rb', line 116

def zero?
  to_d.zero?
end