Skip to content

Instantly share code, notes, and snippets.

@mikeys
Last active May 25, 2016 22:05
Show Gist options
  • Save mikeys/75f0c79f1d1a236da814 to your computer and use it in GitHub Desktop.
Save mikeys/75f0c79f1d1a236da814 to your computer and use it in GitHub Desktop.
Version helper class
class Version
include Comparable
PATTERN = /^(?<major>0|[1-9][0-9]*)(\.(?<minor>0|[1-9][0-9]*))?(\.(?<revision>0|[1-9][0-9]*))?$/
attr_reader :major, :minor, :revision
def initialize(options)
[:major, :minor, :revision].each do |field|
validate_field(field, options[field])
instance_variable_set("@#{field}", options[field] || 0)
end
end
def self.parse(string, options = {})
match = PATTERN.match(string)
return nil unless match
Version[match[:major], match[:minor], match[:revision]]
end
def self.[](*array)
new(major: array[0].to_i,
minor: array[1].to_i,
revision: array[2].to_i)
end
def self.parse!(string, options = {})
parse(string) || (raise ArgumentError, "invalid version format")
end
def <=>(other_version)
comparison = 0
[:major, :minor, :revision].each do |field|
comparison = self.send(field) <=> other_version.send(field)
break if comparison != 0
end
comparison
end
def to_s
@as_string ||= [major, minor, revision].join('.')
end
private
def validate_field(field, value)
if value
raise ArgumentError, "#{field} field must be an integer" unless value.is_a?(Integer)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment