James F. wrote in post #1055131:
Its pretty simple really. I want to be able to call an API like this:
SourceControl.checkout
SourceControl.update
You better do
sc.checkout
sc.update
i.e. not use a constant but an instance variable.
I want to be able to plugin different source control systems that
conform to the API.
Well, in Ruby there are no interfaces so you can, but do not need to use
inheritance.
My initial thought was just to go with a simple C++ style
wrapper/delegate approach:
module SourceControl
def self.checkout(repository, dest, options={})
@sourceControl.checkout(repository, dest, options)
end
def self.update(path, options={})
@sourceControl.update(parth, options)
end
class SourceControlAPI
def checkout(repository, dest, options={})
end
def update(path, options={})
end
end
end
But I bet there is a nicer way, perhaps without having to duplicate the
API?
Especially, what advantages does it have?
I’d probably simply do
class CVS
def checkout(dest, options={})
end
def update(path, options={})
end
end
class SVN
def checkout(dest, options={})
end
def update(path, options={})
end
end
class Perforce
def checkout(dest, options={})
end
def update(path, options={})
end
end
and then
connection
sc = SVN.new(“svn-repo.my.network.com”, “James”, “p@ssword”)
repository
sc.checkout(“repo”, “/tmp/work”) do |repo|
repo.update(“foo”)
File.open(repo.path + “foo”, “a”) {|io| io.write("a change)}
repo.submit(“foo”)
end # auto commit
sc.close # needed?
You could even make SVN.new accept a block which receives “sc” and
cleans up in ensure regardless how the block terminates.
http://blog.rubybestpractices.com/posts/rklemme/002_Writing_Block_Methods.html
Kind regards
robert