Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Ruby Stdlib is not a Ghetto (segment7.net)
74 points by wvl on Nov 25, 2010 | hide | past | favorite | 41 comments


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.


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.)


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. ;-)


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


That's very true. Not just homophobic, but anti-woman. I try not to say it, but it's been very hard for me to get out of my vocabulary.

And I think "ghetto" as an adjective is even more offensive. It basically means "black". As in, "Ruby stdlib is crappy... like things black people use".


It's a bit unclear in this case, but I did read the old (well, 2008) blog-post that I think started this particular trend as implying the run-down-and-isolated meaning: http://journal.relativesanity.com/2008/11/18/php-is-a-ghetto...

It's arguing something like: you can get some things done in PHP, but it's this walled-in, limiting environment that you'll never flourish in, unless you find a way to escape it and break out of the "PHP programmer" box. It even comes with a bit of a cultural/economic walling in also, with the connotations of the "PHP programmer" label.

With language/library environments there seems to at least be the potential for that sort of metaphorical isolation and limitation. I've heard people worry about whether there's a "Lisp ghetto" in that sense, especially post-1990s. That said, I agree that for this particular series of two posts, it doesn't seem to add much. It's something more like, "the Ruby stdlib is bad / no it isn't".


I am quite confidant that the "Ruby stdlib is a ghetto" post is titled after Zed Shaw's "Rails is a ghetto" post, which has come to sort of mean "i'm going to say something inflammatory and impolitic".

Why Zed titled his post as such was partially an accident (he didn't mean to publish it in the state it had been originally published, with that title). Why he originally titled it that, i dunno.


Definitions of words evolve.

Has "it sucks" always meant that something was bad? No, but that's what it means now because that's how people started using it.


That's an old and always interesting argument, and I honor you for brining it up. However, the fact that English usage evolves is no excuse for going along with every bit of its evolution without asking yourself if the new usage is an improvement or not. It's our responsibility as writers to sift through the entire language and pick and choose the words and idioms that communicate our ideas well.

In this particular case, although plenty of people use "is a ghetto" to mean "sucks" rather than "is isolated," and although almost everyone uses "sucks" to mean "is poor" rather than "performs fellatio," I personally think that "is a ghetto" is a strong metaphor when used to imply a marginalized, isolated technology and is incredibly weak when used to imply something has fallen into disrepair. It really doesn't add anything insightful.

Which brings me to my personal metric for deciding how well a metaphor fits. Does it add some insight? If "is a ghetto" is synonymous with "sucks," I gain nothing form using it other than passing myself off as a hipster.

But when someone uses "is a ghetto" to describe something with an insular culture, I get an "aha!" moment as I think about the various implications, such as people trying to live their entire lives within the ghetto, or people learning to speak a crazy creole of their programming languages.

I think using "is a ghetto" in the social sense conveys extra insight or meaning, so I personally prefer it.

I will go further. Using it to merely suggest that something sucks is--well--gay.


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)?


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?


> 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']}


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.


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.)


There are hints of efforts in this area. See rubyinterfaces.com.

As an example, their proposed HTTP interface can be found here:

http://rubyinterfaces.com/httpi-0.1.0/


The "-ng" prefix has served the programming community quite well for some time.


Same applies to nearly every tool for every language. yacc, for instance, does not give any indication as to what it does (well, until you expand the initialism).

Java is, of course, one place where this is a bit better. log4j and jUnit both tell you what they do quite easily. (But then again, Apache Maven does not.)

We have Google these days, and if that doesn't help you, go on the #ruby IRC channel and ask what they recommend.


Lucene, guice, solr, spring, hibernate, jmx, osi, nailgun, etc.


awk, grep, sed, perl, cat, finger, man, etc


  awk -> I forget what
  grep -> global/regular expression/print
  sed -> stream editor
  perl -> I'll give you this one
  cat -> concatenate
  finger -> I'll give you this one
  man -> manual
A large percentage of them are mnemonics.


I wasn't implying that it's better elsewhere, just that java isn't any better.


http://www.google.com/search?q=ruby+xml+parser&ie=UTF-8&...

Nokogiri is the 5th result for me. How does anyone find libraries and then choose between them? I believe you should always do a little research unless your feeling lucky.


Same goes for just about every library under the sun. The other day I was searching for redis libraries for nodejs, the first one from google by fictorial is maintained by someone who has gone for maternity leave where the current version doesn't even compile against the latest node. The one that you're actually supposed to use doesn't even list on the first 5 pages of the google search. (but is the first one found via npm)


It's much worse than that — ruby's non-standard libs all have at least three potentially-different names:

  $ gem install rack-cache
  $ irb
  irb(main):001:0> require 'rack/cache'
  => true
  irb(main):002:0> Rack::Cache
  => Rack::Cache
Only a japanese person could have come up with this clusterfuck — it's like dealing with Kanji!


I think you are putting too much weight on the name.

Humans brains are by nature powerful association engines. People tend to associate brand names with their purpose and (perceived) quality pretty quickly. If you've heard of that a once and the product turns out to be good then you are likely to remember it in the future. Why do you think Coca Cola is called Coca Cola and not Black Sweet Beverage? Heineken instead of Dutch Beer? Nike instead of Expensive Nice Shoes? Names do not have to be descriptive.

It confuses people for maybe a few minutes. Then they look for information, find it, and they move on. There's absolutely no point giving products generic names because in the long run it hurts the authors by being unable to differentiate themselves from others who do the same thing.

Don't know what "nokogiri" is? Search the internet and the first result will tell you. Looking for an XML parser but don't know its name? Search the internet and the first result likely gives a good recommendation.


Two second google search would suffice http://ruby-toolbox.com/


What was the query?


'gem -r -d search' works pretty well.


not much better in python either, or any language. How does one name an xml parser beautiful soup?


It is an html parser, not an xml parser. It was probably named as a tongue-in-cheek reference to adding some beauty to the tag soup that was state of most (mal-formed) html pages out there at the time of its creation.


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.


> 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.


I think the point here is: Net::HTTP has convenince methods to just "fire off a GET request" as well as the ability to hand-craft a request and send it over a pre-established connection (maybe implemented by myself).


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


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


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


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

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


Personally, I'm a big fan of open-uri for super-simple requests and HTTParty for anything more complex.


If you're doing more than one of those in a single document, having a persistent connection object and sending it request messages wins. (Though open-uri could actually do this, if it cached the connection objects by host:port.)


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.


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?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: