James French 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

-- 
Posted via http://www.ruby-forum.com/.