Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created December 8, 2011 03:49
Show Gist options
  • Save ahoward/1446030 to your computer and use it in GitHub Desktop.
Save ahoward/1446030 to your computer and use it in GitHub Desktop.
a nice and simple version class
class Version < ::String
class Error < ::StandardError; end
attr :major
attr :minor
attr :teeny
def Version.default
Version.for('0.0.0')
end
def Version.for(*args)
version = args.size == 1 && args.first
case version
when Version
version
else
Version.new(*args)
end
end
def Version.numbers(version)
Version.for(version).numbers
end
def initialize(*args, &block)
super(args.flatten.join('.'))
ensure
@major, @minor, @teeny = strip.split(/\./).map{|v| v.to_i}
end
def <=> other
numbers <=> Version.for(other).numbers
end
def numbers
[major, minor, teeny]
end
%w( major minor teeny ).each do |number|
module_eval <<-__, __FILE__, __LINE__
def bump_#{ number }!
@#{ number } += 1
replace(numbers.join('.'))
self
end
def bump_#{ number }
dup.bump_#{ number }!
end
__
end
alias_method('bump', 'bump_minor')
alias_method('bump!', 'bump_minor!')
end
@ahoward
Copy link
Author

ahoward commented Dec 8, 2011

SomeClass.for, in my code, nearly always conforms to the following interface:

"given a bucket of random arguments, do your best to make a choice at how to call 'new' with them. as a special case, iff the object is already of the class in question, simply return it"

it's a sort of cast-or-build factory that let's me do things like #L34 without needing to worry about making lots of extraneous objects. a more sophisticated example: https://github.com/ahoward/map/blob/master/lib/map.rb#L42 - note that this one even works for class Foo < ::Map...

some other examples:

@julik
Copy link

julik commented Dec 28, 2011

I'm totally in for that - but I've reverted to the Gem::Version class since in 99 percent of the cases it's there for me anyway. Like here https://github.com/julik/update_hints/blob/master/lib/update_hints.rb#L28

@ahoward
Copy link
Author

ahoward commented Jan 5, 2012

using Gem::Version is a good idea. in my case i really needed domain specific '@version.bump!'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment