

The Ruby Stdlib is not a Ghetto - wvl
http://blog.segment7.net/articles/2010/11/24/the-ruby-stdlib-is-not-a-ghetto

======
erikpukinskis
People also need to be a little more careful about using the word "ghetto". It
has a long history, from Jewish ghettos in Europe during World War II, to
modern day black ghettos that persist in most big cities in the U.S.

Many people today still grow up in "The Ghetto," which is a place of
geographic, economic, and political marginalization. Before you go talking
about "Wii is a ghetto" or "Ruby is a ghetto" you should really understand
something about what that means, and who you might be affecting with your
words.

And even if you've decided that you want to throw the word around, use it
fucking properly. A ghetto is not just something that "sucks". Ghettos are
defined not just by being run-down, but by being isolated in some way. If you
want to say something sucks, just say it sucks.

~~~
philwelch
_If you want to say something sucks, just say it sucks._

People also need to be a little more careful about using the word "sucks". It
has a long history of homophobic connotations--originally it was used to
denigrate people, generally men, by suggesting (in a derogatory sense) that
they performed certain homosexual acts.

(When I was a kid, something that was really cheap and crappy was
"ghetto"--"ghetto" being an adjective. Like if you had a really crappy car
from the 80's, your car was ghetto. So maybe, even if the Ruby stdlib isn't
_a_ ghetto, the Ruby stdlib is still pretty ghetto in the adjective sense.)

~~~
deadmansshoes
You should be more careful about using the word "People" with its connotations
of common and of the masses (as distinguished from the nobility)..etc. etc.
;-)

~~~
erikpukinskis
I know you're trolling, but I'll bite. No one is hurt if you use the word
"people". People are hurt when you use the words "ghetto" and "sucks". That's
the difference.

See <http://en.wikipedia.org/wiki/Consequentialism>

------
leif
This is tangential, but I've found that ruby's non-standard libs have, for the
most part, been horribly named. Recall from the article: curb, nokogiri, syck,
psych, home_run. Others: sinatra, rack, thin, unicorn, maruku. None of these
give me the slightest clue about what they do, and if I wanted, for example,
to parse XML, how on earth would I know that I wanted to find "nokogiri" (or
"hpricot")? Could I pick what I wanted out of a lineup?

How do you ruby people find the good libraries when you need to perform a
task? Is it all word-of-mouth (word-of-blog I guess)?

~~~
rbranson
How do you propose to differentiate between multiple implementations of the
same concept otherwise? It is nice that there is a "nokogiri" and "hpricot,"
unlike the PostgreSQL gems, which are called "postgres", "pg", and "postgres-
ruby". The one you actually want to use is "pg" though.

Should "rack" be called standard-http-server-api-with-support-for-middleware,
and then "unicorn" be called pre-forking-web-server-using-standard-http-
server-api-with-support-for-middleware?

~~~
derefr
> Should "rack" be called standard-http-server-api-with-support-for-
> middleware, and then "unicorn" be called pre-forking-web-server-using-
> standard-http-server-api-with-support-for-middleware?

No, but perhaps we could have:

    
    
        WebServer = require_any_satisfying_protocol 'http-server/with-middleware-support'
        WebServer.new
    

where each rubygem installed has a table of protocols each of its classes and
modules support. For example, Mongrel would have a table that starts:

    
    
        {Mongrel::HttpServer => ['http-server', 'http-server/with-middleware-support']}

~~~
FooBarWidget
There are two problems with that.

1\. In practice you almost never want to load a random library that says it
supports a certain interface, you will want a specific library. Notable
exceptions are glibc where the interfaces are well-defined over several
decades but that brings us to...

2\. Few libraries implement the same exact interface. Mongrel and Unicorn have
totally different interfaces. Phusion Passenger is also a web server but works
in a fundamentally different way from either of them. Hpricot and Nokogiri are
both XML parsers but their usage API is different.

~~~
derefr
Thus, I imagine, why djacob's link to HTTPI talks about protocol _adapters_ ,
rather than expecting the implementations to adhere to the protocols directly.
Still, the adapters could come with each protocol-supporting gem, rather than
being housed in some third party "interface library." Then we could have
something more like this in each class of a gem:

    
    
        class Mongrel::HttpServer
          class HttpServerProtocolAdapter < Gem::ProtocolAdapter
            implements 'http-server'
            implements 'http-server/with-middleware-support'
            ...
    

and the manifests (which would then look more like this:)

    
    
        {'http-server'                         => Mongrel::HttpServer::HttpServerProtocolAdapter,
         'http-server/with-middleware-support' => Mongrel::HttpServer::HttpServerProtocolAdapter,
         ...}
    

would be generated automatically at gem installation by loading the gem and
then probing for ProtocolAdapter instances in ObjectSpace.

Of course, if you had a class that matched the protocol exactly, you could
just use something like

    
    
        class Mongrel::HttpServer
          supports_protocol 'http-server'
        end
    

and be done with it.

This is all assuming that we don't actually want our protocols to be modules
or classes or something else that we have to include in the adapter somehow
(because this is Ruby, and we do well without needing IDuck.) Instead,
protocols would just be externally specified things, with their name-strings
perhaps being the URIs of standards docs. At most, if a Gem::Protocol was a
reified type, it would be a unit test suite to determine whether a
ProtocolAdapter actually supported its protocol (minimally, via a series of
#respond_to?s.)

------
chrisbroadfoot
We should probably aim higher than "not a ghetto" :)

I didn't read the article in great detail, but I noticed this:

    
    
      it provides many ways to do the same thing for programmer convenience
    

This is not a good thing, in my opinion.

I do, however, find it peculiar that utilities like RSS, FTP and mail handling
are included in a stdlib.

~~~
124816
> This is not a good thing, in my opinion.

This is extremely common, and not at all unique to Ruby. For example,
providing defaults for parameters is perhaps the most common and simplest form
of this.

Whenever a library is used by wildly different clients, there is a good chance
the API it chooses will be better suited to one or the other. The same
Net::HTTP is presumably used for the simplest of uses, maybe 5 line download
scripts, and the most complex of cases, perhaps forwarding http requests with
all headers intact.

In general I go by "minimal, but complete"; but for widely used libraries that
have clients of very different complexities, it makes sense to provide a
simple API for convenience. I'd rather not be specifying the client headers,
user agent, supported encodings, etc, etc each time I want to fetch a file
over http.

------
aaronbrethorst
With all due respect, Net::HTTP _is_ clunky. I'm typing the following from
memory, too:

    
    
        require 'open-uri'
        response = open("http://blog.segment7.net/").read

~~~
catch23
that's great if all you're trying to do is HTTP GET. standard libs are
supposed to make all use cases fairly easy. making an http post isn't too bad:

    
    
      Net::HTTP.new(host, port).start do |http|
        post = Net::HTTP::Post.new(url)
        post.set_form_data('blah' => '123')
        http.request(post)
      end

~~~
petercooper
That's "not too bad" if you're coming from Java. Thankfully most other Ruby
libraries have significantly less verbose APIs than this.

~~~
carbon8
There's a much simpler way to do POSTs with Net::HTTP:

    
    
      response = Net::HTTP.post_form(URI.parse("http://example.com"), {:param => "val"})

------
mxcl
His counter argument seems to be that the original blog post didn't offer
alternatives or patches and so it is invalid.

Which of course is not a counter argument at all.

IMO the Ruby stdlib is a mess. Denying it won't improve it.

------
Rusky
His argument is rather poor. The other post doesn't offer details or
alternatives, but all his does is offer details that really don't support his
argument ("it's /only/ 2.4 times slower, and you should use persistent
connections anyway!"). What kind of defense is that?

