Sorting Versions is Hard
Posted by kev Fri, 16 Mar 2007 17:58:00 GMT
class Package < ActiveRecord::Base
def <=>(other)
versions = self.version.split(".").push self.rel
other_versions = other.version.split(".").push other.rel
versions.size.times do |n|
if versions[n] =~ /[^\d]/ || other_versions[n] =~ /[^\d]/
comparison = versions[n] <=> other_versions[n]
else
comparison = versions[n].to_i <=> other_versions[n].to_i
end
return comparison unless comparison.zero?
end
return 0
end
end
[Package.new(:version => "0.0.8a"),
Package.new(:version => "0.0.8c"),
Package.new(:version => "0.0.8b")].sort.map(&:version)
# => ["0.0.8a", "0.0.8b", "0.0.8c"]
[Package.new(:version => "0.0.8"),
Package.new(:version => "0.0.10"),
Package.new(:version => "0.0.9")].sort.map(&:version)
# => ["0.0.8", "0.0.9", "0.0.10"] 

And if you want to handle all the versioning schemes out there in use, it gets insane. Take for example just a few described here: http://peak.telecommunity.com/DevCenter/setuptools#specifying-your-project-s-version
I wrote a Version library that might help you out: http://railsaddict.com/past/2007/3/26/sorting_versions_is_easy/, thanks for the inspiration!
Facets to the rescue: http://facets.rubyforge.org/src/doc/rdoc/more/classes/VersionNumber.html