class Versionomy::Value

Version number value

A version number value is an ordered list of values, corresponding to an ordered list of fields defined by a schema. For example, if the schema is a simple one of the form “major.minor.tiny”, then the the version number “1.4.2” would have the values [1, 4, 2] in that order, corresponding to the fields [:major, :minor, :tiny].

Version number values are comparable with other values that have an equivalent schema.

Public Class Methods

new(values_, format_, unparse_params_=nil) click to toggle source

Create a value, given a hash or array of values, and a format. Both these parameters are required.

The values should either be a hash of field names and values, or an array of values that will be interpreted in field order.

You can also optionally provide default unparsing parameters for the value.

# File lib/versionomy/value.rb, line 70
def initialize(values_, format_, unparse_params_=nil)
  unless values_.kind_of?(::Hash) || values_.kind_of?(::Array)
    raise ::ArgumentError, "Expected hash or array but got #{values_.class}"
  end
  @_format = format_
  @_unparse_params = unparse_params_
  @_field_path = []
  @_values = {}
  values_ = _canonicalize_values_hash(values_) if values_.kind_of?(::Hash)
  field_ = @_format.schema.root_field
  while field_
    value_ = values_.kind_of?(::Hash) ? values_[field_.name] : values_.shift
    value_ = value_ ? field_.canonicalize_value(value_) : field_.default_value
    @_field_path << field_
    @_values[field_.name] = value_
    field_ = field_.child(value_)
  end
  modules_ = @_format.schema.modules
  extend(*modules_) if modules_.size > 0
end

Public Instance Methods

<(obj_) click to toggle source

Compare this version number with the given version number. The comparison may succeed even if the two have different schemas, if the RHS can be converted to the LHS's format.

# File lib/versionomy/value.rb, line 386
def <(obj_)
  val_ = (self <=> obj_)
  unless val_
    raise Errors::SchemaMismatchError
  end
  val_ < 0
end
<=>(obj_) click to toggle source

Compare this version number with the given version number, returning 0 if the two are value-equal, a negative number if the RHS is greater, or a positive number if the LHS is greater. The comparison may succeed even if the two have different schemas, if the RHS can be converted to the LHS's format.

# File lib/versionomy/value.rb, line 362
def <=>(obj_)
  if obj_.kind_of?(::String)
    obj_ = @_format.parse(obj_)
  end
  return nil unless obj_.kind_of?(Value)
  if obj_.schema != @_format.schema
    begin
      obj_ = obj_.convert(@_format)
    rescue
      return nil
    end
  end
  obj_.each_field_object do |field_, value_|
    val_ = field_.compare_values(@_values[field_.name], value_)
    return val_ if val_ != 0
  end
  0
end
==(obj_) click to toggle source

Returns true if this version number is value-equal to the given number. This type of equality means that they are equivalent, or that it is possible to convert the RHS to the LHS's format, and that they would be equivalent after such a conversion has taken place. Note that this is different from the definition of eql?.

# File lib/versionomy/value.rb, line 351
def ==(obj_)
  (self <=> obj_) == 0
end
>(obj_) click to toggle source

Compare this version number with the given version number. The comparison may succeed even if the two have different schemas, if the RHS can be converted to the LHS's format.

# File lib/versionomy/value.rb, line 399
def >(obj_)
  val_ = (self <=> obj_)
  unless val_
    raise Errors::SchemaMismatchError
  end
  val_ > 0
end
[](field_) click to toggle source

Returns the value of the given field, or nil if the field is not recognized. The field may be specified as a field object, field name, or field index.

# File lib/versionomy/value.rb, line 202
def [](field_)
  @_values[_interpret_field(field_)]
end
bump(field_) click to toggle source

Returns a new version number created by bumping the given field. The field may be specified as a field object, field name, or field index. Returns self unchanged if the field was not recognized or could not be modified.

# File lib/versionomy/value.rb, line 228
def bump(field_)
  name_ = _interpret_field(field_)
  return self unless name_ && @_values.include?(name_)
  values_ = []
  @_field_path.each do |fld_|
    oldval_ = @_values[fld_.name]
    if fld_.name == name_
      newval_ = fld_.bump_value(oldval_)
      return self if newval_ == oldval_
      values_ << newval_
      return Value.new(values_, @_format, @_unparse_params)
    else
      values_ << oldval_
    end
  end
  self
end
change(values_={}, unparse_params_={}) click to toggle source

Returns a new version number created by cloning this version number and changing the given field values.

You should pass in a hash of field names to values. These are the fields to modify; any other fields will be left alone, unless they are implicitly changed by the modifications you are making. For example, changing the :release_type on a value using the standard format, may change which fields are present in the resulting value.

You may also pass a delta hash to modify the unparse params stored in the value.

# File lib/versionomy/value.rb, line 281
def change(values_={}, unparse_params_={})
  unparse_params_ = @_unparse_params.merge(unparse_params_) if @_unparse_params
  values_ = _canonicalize_values_hash(values_)
  Value.new(@_values.merge(values_), @_format, unparse_params_)
end
convert(format_, convert_params_=nil) click to toggle source

Attempts to convert this value to the given format, and returns the resulting value.

Raises Versionomy::Errors::ConversionError if the value could not be converted.

# File lib/versionomy/value.rb, line 294
def convert(format_, convert_params_=nil)
  if format_.kind_of?(::String) || format_.kind_of?(::Symbol)
    format_ = Format.get(format_)
  end
  return self if @_format == format_
  from_schema_ = @_format.schema
  to_schema_ = format_.schema
  if from_schema_ == to_schema_
    return Value.new(@_values, format_, convert_params_)
  end
  conversion_ = Conversion.get(from_schema_, to_schema_)
  if conversion_
    conversion_.convert_value(self, format_, convert_params_)
  else
    standard_format_ = Format.get(:standard)
    conversion1_ = Conversion.get(from_schema_, standard_format_)
    conversion2_ = Conversion.get(standard_format_, to_schema_)
    if conversion1_ && conversion2_
      value_ = conversion1_.convert_value(self, standard_format_, convert_params_)
      conversion2_.convert_value(value_, format_, convert_params_)
    else
      raise Errors::UnknownConversionError
    end
  end
end
each_field() { |field_, _values| ... } click to toggle source

Iterates over each field, in field order, yielding the field name and value.

# File lib/versionomy/value.rb, line 155
def each_field
  @_field_path.each do |field_|
    yield(field_, @_values[field_.name])
  end
end
eql?(obj_) click to toggle source

Returns true if this version number is equivalent to the given number. This type of equality means their schemas are compatible and their field values are equal. Note that this is different from the definition of ==.

# File lib/versionomy/value.rb, line 331
def eql?(obj_)
  if obj_.kind_of?(::String)
    obj_ = @_format.parse(obj_) rescue nil
  end
  return false unless obj_.kind_of?(Value)
  index_ = 0
  obj_.each_field_object do |field_, value_|
    return false if field_ != @_field_path[index_] || value_ != @_values[field_.name]
    index_ += 1
  end
  true
end
field_names() click to toggle source

Returns an array of recognized field names for this value, in field order. This is the order of the fields actually present in this value, in order from most to least significant.

# File lib/versionomy/value.rb, line 176
def field_names
  @_field_path.map{ |field_| field_.name }
end
format() click to toggle source

Return the format defining the schema and formatting/parsing of this version number.

# File lib/versionomy/value.rb, line 140
def format
  @_format
end
has_field?(field_) click to toggle source

Returns true if this value contains the given field, which may be specified as a field object, name, or index.

# File lib/versionomy/value.rb, line 184
def has_field?(field_)
  case field_
  when Schema::Field
    @_field_path.include?(field_)
  when ::Integer
    @_field_path.size > field_ && field_ >= 0
  when ::String, ::Symbol
    @_values.has_key?(@_format.schema.canonical_name(field_))
  else
    raise ::ArgumentError
  end
end
method_missing(symbol_) click to toggle source

Field values may be retrieved by calling them as methods.

Calls superclass method
# File lib/versionomy/value.rb, line 413
def method_missing(symbol_)
  self[symbol_] || super
end
reset(field_) click to toggle source

Returns a new version number created by resetting the given field. The field may be specified as a field object, field name, or field index. Returns self unchanged if the field was not recognized or could not be modified.

# File lib/versionomy/value.rb, line 252
def reset(field_)
  name_ = _interpret_field(field_)
  return self unless name_ && @_values.include?(name_)
  values_ = []
  @_field_path.each do |fld_|
    oldval_ = @_values[fld_.name]
    if fld_.name == name_
      values_ << fld_.default_value
      return Value.new(values_, @_format, @_unparse_params)
    else
      values_ << oldval_
    end
  end
  self
end
schema() click to toggle source

Return the schema defining the structure and semantics of this version number.

# File lib/versionomy/value.rb, line 132
def schema
  @_format.schema
end
to_s() click to toggle source

Returns a string representation generated by unparsing. If unparsing fails, does not raise Versionomy::Errors::UnparseError, but instead returns the string generated by inspect.

# File lib/versionomy/value.rb, line 111
def to_s
  begin
    unparse
  rescue Errors::UnparseError
    _inspect
  end
end
unparse(params_=nil) click to toggle source

Unparse this version number and return a string.

Raises Versionomy::Errors::UnparseError if unparsing failed.

# File lib/versionomy/value.rb, line 124
def unparse(params_=nil)
  @_format.unparse(self, params_)
end
unparse_params() click to toggle source

Return the unparsing parameters for this value. Returns nil if this value was not created using a parser.

# File lib/versionomy/value.rb, line 148
def unparse_params
  @_unparse_params ? @_unparse_params.dup : nil
end
values_array() click to toggle source

Returns the value as an array of field values, in field order. This is the order of the fields actually present in this value, in order from most to least significant.

# File lib/versionomy/value.rb, line 211
def values_array
  @_field_path.map{ |field_| @_values[field_.name] }
end
values_hash() click to toggle source

Returns the value as a hash of values keyed by field name.

# File lib/versionomy/value.rb, line 218
def values_hash
  @_values.dup
end