[Rubygems-developers] What plans now?

Chad Fowler chad at chadfowler.com
Mon May 17 07:17:51 EDT 2004


On 16/5/2004, at 7:13 PM, Gavin Sinclair wrote:

>> Gavin Sinclair wrote:
>>>
>>>> Curt Hibbs wrote:
>>>
>>>> I haven't looked at this in a few weeks, to maybe it has
>>>> changed, but the
>>>> main file that implements the command line interface mixes API with
>>> command
>>>> interface. I remember wanting to separate these so that the command
>>> line process requires/uses the same API file my GUI browser would
>>> use,
>>>
>>> No, nothing's changed :(  That's definitely something we need to
>>> address, but it may take a bit of sleeves-up dirty work.  I'm happy 
>>> to
>>> do the dirty work, but I'd like some help from you on what the API
>>> should look like.
>>
>> It seems to me that, logically, you have a repository object that lets
>> you do things with a repository, and a gem object that lets you do
>> things with a particular gem. Then I could do things like:
>>
>>    remote = GemRepository.new("rubyforge.org")
>>    local  = GemRepository.new("local")
>>    remote = GemRepository.new("default")
>
> Yeah, not bad, though I'd rather see one giant repository (which can be
> sliced, diced, and searched in various ways).
>
> The benefit of a giant repository integrating local and remote gems is
> that you can do easily things that are useful for the user; e.g. 
> searching
> for uninstalled gems matching X, without returning duplicate results 
> from
> different sources.
>
>>    remote.each { |gem| remote_gems.add(gem) }
>>    local.each  { |gem| local_gems.add(gem) }
>>
>>    a_gem = remote_gems[some_gem_name]
>
> What are local_gems and remote_gems here?
>
>>    # retrieving gem information
>>    a_gem.name
>>    a_gem.version
>>    a_gem.installed?
>
> I like it.
>
>>    # performing an actions
>>    a_gem.install
>>    a_gem.upgrade   # upgrade to latest version
>
> I like it.
>
>>> It's important to remember that various events can happen inside the
>>> API that different clients will handle differently.  For example,
>>> getting confirmation before installing a slew of dependencies.  Your
>>> client does something with dialog boxes; 'gem' uses STDOUT/STDIN.  We
>>> need to model that sort of interaction adequately.
>>
>> Could yield blocks handle this?
>>
>>    a_gem.install do |uninstalled_dependent_list|
>>       <ask-the-user>
>>       <return-true-or-false>
>>    end
>
> Yes, but I'm pretty sure there are cases where more than one 'signal' 
> can
> be generated by the method.  In which case we could get by with 
> something
> like this:
>
>   a.gem.install do |signal, arg|
>     case signal
>     when :uninstalled_dependencies
>       <ask the user>(arg)
>       <return true or false>
>     when :something_else
>       ...
>     end
>   end
>
> That has a certain appeal, but I've never seen Ruby code like it 
> before.
> Something to think about.  I'll see if I can find a case where more 
> than
> one "handler" is necessary.
>
> As for Chad's continuation-based idea, down that road lies madness!
> (Sorry, just had to say that.)  I think that would get rather 
> complicated,
> rather quickly.  And to do it properly, we'd end up reimplementing 
> Borges
> :)
>

It's early, so I might be missing something elementary, but:

tashi-delek:~/experiment chadfowler$ expand -t2 deepyield.rb
def foo
   bar
end

def bar
   yield "hello"
end

foo do |message|
   puts message
end
tashi-delek:~/experiment chadfowler$ ruby deepyield.rb
deepyield.rb:6:in `bar': no block given (LocalJumpError)
         from deepyield.rb:2:in `foo'
         from deepyield.rb:11

All yields will have to either be done in the (e.g.) gem.install method 
or the block will have to be passed down from one method to the next 
like:

def foo(&block)
   bar(&block)
end

That gets pretty nasty too, especially as we add more classes and 
methods to those classes.

Is there a way to do a catch that will respond to *any* symbol?  A 
mixture of our two approaches might solve the problem if it was 
possible.

What makes you say continuations are complicated?   The continuations 
part of Borges, for example, is really nothing to implement or 
understand.  Borges (Seaside, really) is only complicated because of 
the amount of functionality included--not the continuations trick.

Chad



More information about the Rubygems-developers mailing list