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 197

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 207

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
end

Class Method Details

.correct?(version) ⇒ Boolean

True if the #version string matches RubyGems’ requirements.

[ GitHub ]

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

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 185

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 296

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

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 346

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

  return unless Gem::Version === other
  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
end

#_segments (protected)

[ GitHub ]

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

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 328

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 233

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 398

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

#encode_with(coder)

This method is for internal use only.
[ GitHub ]

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

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 248

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

#freeze

[ GitHub ]

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

def freeze
  prerelease?
  _segments
  canonical_segments
  super
end

#hash

This method is for internal use only.
[ GitHub ]

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

def hash # :nodoc:
  canonical_segments.hash
end

#init_with(coder)

This method is for internal use only.
[ GitHub ]

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

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 260

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 268

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 276

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 425

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 303

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 311

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 321

def segments # :nodoc:
  _segments.dup
end

#to_s

Alias for #version.

[ GitHub ]

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

alias_method :to_s, :version

#version Also known as: #to_s

A string representation of this Version.

[ GitHub ]

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

def version
  @version
end

#yaml_initialize(tag, map)

This method is for internal use only.
[ GitHub ]

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

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