123456789_123456789_123456789_123456789_123456789_

Class: Gem::Version

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, Comparable
Inherits: Object
Defined in: lib/rubygems/version.rb,
lib/rubygems/requirement.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(version) ⇒ Version

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 198

def self.new(version) # :nodoc:
  return super unless self == Gem::Version

  @@all[version] ||= super
end

#initialize(version) ⇒ Version

Constructs a Version from the #version string. A version string is a series of digits or ASCII letters separated by dots.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 208

def initialize(version)
  unless self.class.correct?(version)
    raise ArgumentError, "Malformed version number string #{version}"
  end

  # If version is an empty string convert it to 0
  version = 0 if version.nil? || (version.is_a?(String) && /\A\s*\Z/.match?(version))

  @version = version.to_s

  # optimization to avoid allocation when given an integer, since we know
  # it's to_s won't have any spaces or dashes
  unless version.is_a?(Integer)
    @version = @version.strip
    @version.gsub!("-",".pre.")
  end
  @version = -@version
  @segments = nil
  @sort_key = compute_sort_key
end

Class Method Details

.correct?(version) ⇒ Boolean

True if the #version string matches RubyGems’ requirements.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 175

def self.correct?(version)
  version.nil? || ANCHORED_VERSION_PATTERN.match?(version.to_s)
end

.create(input)

Factory method to create a Version object. Input may be a Version or a String. Intended to simplify client code.

ver1 = Version.create('1.3.17')   # -> (Version object)
ver2 = Version.create(ver1)       # -> (ver1)
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 186

def self.create(input)
  if self === input # check yourself before you wreck yourself
    input
  else
    new input
  end
end

Instance Attribute Details

#prerelease?Boolean (readonly)

A version is considered a prerelease if it contains a letter.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 298

def prerelease?
  unless instance_variable_defined? :@prerelease
    @prerelease = /[a-zA-Z]/.match?(version)
  end
  @prerelease
end

#sort_key (readonly, protected)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 424

attr_reader :sort_key # :nodoc:

Instance Method Details

#<=>(other)

Compares this version with other returning -1, 0, or 1 if the other version is larger, the same, or smaller than this one. other must be an instance of Version, comparing with other types may raise an exception.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 348

def <=>(other)
  if Gem::Version === other
    # Fast path for comparison when available.
    if @sort_key && other.sort_key
      return @sort_key <=> other.sort_key
    end

    return 0 if @version == other.version || canonical_segments == other.canonical_segments

    lhsegments = canonical_segments
    rhsegments = other.canonical_segments

    lhsize = lhsegments.size
    rhsize = rhsegments.size
    limit  = (lhsize > rhsize ? rhsize : lhsize)

    i = 0

    while i < limit
      lhs = lhsegments[i]
      rhs = rhsegments[i]
      i += 1

      next      if lhs == rhs
      return -1 if String  === lhs && Numeric === rhs
      return  1 if Numeric === lhs && String  === rhs

      return lhs <=> rhs
    end

    lhs = lhsegments[i]

    if lhs.nil?
      rhs = rhsegments[i]

      while i < rhsize
        return 1 if String === rhs
        return -1 unless rhs.zero?
        rhs = rhsegments[i += 1]
      end
    else
      while i < lhsize
        return -1 if String === lhs
        return 1 unless lhs.zero?
        lhs = lhsegments[i += 1]
      end
    end

    0
  elsif String === other
    return unless self.class.correct?(other)
    self <=> self.class.new(other)
  end
end

#_segments (protected)

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 442

def _segments
  # segments is lazy so it can pick up version values that come from
  # old marshaled versions, which don't go through marshal_load.
  # since this version object is cached in @@all, its @segments should be frozen
  @segments ||= partition_segments(@version)
end

#approximate_recommendation

A recommended version for use with a ~> Requirement.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 330

def approximate_recommendation
  segments = self.segments

  segments.pop    while segments.any? {|s| String === s }
  segments.pop    while segments.size > 2
  segments.push 0 while segments.size < 2

  recommendation = "~> #{segments.join(".")}"
  recommendation += ".a" if prerelease?
  recommendation
end

#bump

Return a new version object where the next to the last revision number is one greater (e.g., 5.3.1 => 5.4).

Pre-release (alpha) parts, e.g, 5.3.1.b.2 => 5.4, are ignored.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 235

def bump
  @@bump[self] ||= begin
                     segments = self.segments
                     segments.pop while segments.any? {|s| String === s }
                     segments.pop if segments.size > 1

                     segments[-1] = segments[-1].succ
                     self.class.new segments.join(".")
                   end
end

#canonical_segments

remove trailing zeros segments before first letter or at the end of the version

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 404

def canonical_segments
  @canonical_segments ||= begin
    # remove trailing 0 segments, using dot or letter as anchor
    # may leave a trailing dot which will be ignored by partition_segments
    canonical_version = @version.sub(/(?<=[a-zA-Z.])[.0]+\z/, "")
    # remove 0 segments before the first letter in a prerelease version
    canonical_version.sub!(/(?<=\.|\A)[0.]+(?=[a-zA-Z])/, "") if prerelease?
    partition_segments(canonical_version)
  end
end

#compute_sort_key (protected)

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 426

def compute_sort_key
  return if prerelease?

  segments = canonical_segments
  return if segments.size > 5

  key = 0
  RADIX_OPT.each_with_index do |radix, i|
    seg = segments.fetch(i, 0)
    return nil if seg >= radix
    key = key * radix + seg
  end

  key
end

#encode_with(coder)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 291

def encode_with(coder) # :nodoc:
  coder.add "version", @version
end

#eql?(other) ⇒ Boolean

A Version is only eql? to another version if it’s specified to the same precision. Version “1.0” is not the same as version “1”.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 250

def eql?(other)
  self.class === other && @version == other.version
end

#freeze

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 415

def freeze
  prerelease?
  _segments
  canonical_segments
  super
end

#hash

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 254

def hash # :nodoc:
  canonical_segments.hash
end

#init_with(coder)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 258

def init_with(coder) # :nodoc:
  yaml_initialize coder.tag, coder.map
end

#inspect

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 262

def inspect # :nodoc:
  "#<#{self.class} #{version.inspect}>"
end

#marshal_dump

Dump only the raw version string, not the complete object. It’s a string for backwards (RubyGems 1.3.5 and earlier) compatibility.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 270

def marshal_dump
  [@version]
end

#marshal_load(array)

Load custom marshal format. It’s a string for backwards (RubyGems 1.3.5 and earlier) compatibility.

Raises:

  • (TypeError)
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 278

def marshal_load(array)
  string = array[0]
  raise TypeError, "wrong version string" unless string.is_a?(String)

  initialize string
end

#partition_segments(ver) (protected)

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 449

def partition_segments(ver)
  ver.scan(/\d|[a-z]/i).map! do |s|
    /\A\d/.match?(s) ? s.to_i : -s
  end.freeze
end

#pretty_print(q)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 305

def pretty_print(q) # :nodoc:
  q.text "Gem::Version.new(#{version.inspect})"
end

#release

The release for this version (e.g. 1.2.0.a -> 1.2.0). Non-prerelease versions return themselves.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 313

def release
  @@release[self] ||= if prerelease?
    segments = self.segments
    segments.pop while segments.any? {|s| String === s }
    self.class.new segments.join(".")
  else
    self
  end
end

#segments

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 323

def segments # :nodoc:
  _segments.dup
end

#to_s

Alias for #version.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 170

alias_method :to_s, :version

#version Also known as: #to_s

A string representation of this Version.

[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 166

def version
  @version
end

#yaml_initialize(tag, map)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/version.rb', line 285

def yaml_initialize(tag, map) # :nodoc:
  @version = -map["version"]
  @segments = nil
  @hash = nil
end