Dear Railsists, Please Don’t be Obtrusive

obtrusive_or_not.png
Update: thanks to Jon Wood aka jellybob, a prototype demonstration has been added, which is even better than my original jQuery btw as it degrades gracefully. Check it out in the ‘prototype-unobtrusive’ directory.

I am guessing 9 out of 10 of you reading the title is prepared for yet-another Rails drama on some obtrusive community members, and because everyone is tired of Rails dramas, I am risking that some of you won’t care to read the article – but I couldn’t resist :-) . Actually I’d like to talk about usage of (un)obtrusive Javascript – why is it a bad idea to be obtrusive, especially given that (as you will learn from the article) writing unobtrusive Javascript is not harder, and you get the warm, fuzzy feeling of writing nice and clean code!

The Drill

To demonstrate the differences, I’ll lead you through the creation of a quick AJAXy shout wall both the default/standard (and obtrusive) way, then do the same with unobtrusive Javascript to show you that contrary to the popular belief, you don’t need to memorize the “Tome of Javascript Black Magick Tricks” by heart, use obscure libraries or special coding techniques to achieve clean, unobtrusive code. The shout wall is simply a form for posting a new message, and a list of messages below it, like so:



shout_wall.png



(You can check out the code used in this post from it’s github repository).

The Standard Way

Note: If you’d like to follow along, please use the provided pastie links – do not try to cut & paste multiple lines from the page (single lines are OK), as it will be b0rk3d.

  1. Creating a new Rails application

    rails obtrusive-shout-wall
      
  2. Get into the Rails dir

    cd obtrusive-shout-wall
      
  3. Generate the resource message

      
    script/generate resource message
      
  4. Add this the following to the generated migration (some_timestamp_create_messages (Get it from pastie):

    t.string :author
    t.text :message	
    
  5. Run the migrations:

    rake db:migrate
    
  6. Because we want to view the messages in reverse order (newest one first), we add a default scope to the Message model (in message.rb):

        default_scope :o rder => 'created_at DESC'
    
  7. Create the application layout – create a new file in app/views/layouts called application.html.erb, and fill it with the following content (Get it from pastie):

    
      
        <%= stylesheet_link_tag "application" %>
    		<%= javascript_include_tag :defaults %>		
      
    	
        <%= yield %>
    	
    
    
  8. Create a file application.css and drop it into public/stylesheets. Add the following content (Get it from pastie):

    body {
    	background-color:#FFFFFF;
    	color:#333333;
    	font-family:"Lucida Grande",verdana,arial,helvetica,sans-serif;
    	margin:0 auto;
    	padding:0;
    	text-align:center;
    	width:960px;
    }
    
    #messages {
    	text-align: left;
    	margin-left: 80px;
    	margin-top: 50px;
    }
    
    #message-form {
    	text-align: left;
    }
    
    #message-form dl {
    	margin:10px 0 0 80px;
    }
    
    #message-form dd {
    color:#666666;
    font-size:11px;
    line-height:24px;
    margin:0 0 5px 80px;
    }
    
    #message-form dt {
    	float:left;
    	font-size:14px;
    	line-height:24px;
    	width:80px;
      text-align: left;	
    }
    
    #author {
      margin-right: 640px;
    }
    
    #message {
      width: 600px;
    	height: 200px;
      margin-right: 194px;
    }
    
    .message {
      margin-bottom: 20px;
    }
    
    .first_row {
      padding-bottom: 10px;
    }
    
    .message-meta {
    	font-size: 12px;
    }
    
    .author {
      color: #FF5050;
    	font-weight: bold;
    }
    
    .new-message-label {
      text-align: left;
      padding-top: 30px;
      margin-left: 80px;
    }
    
    #submit-button {
      float : right;
      margin-right: 195px;
      margin-top: 10px;
    }
    
  9. Create a new action, index in MessagesController (Get it from pastie):

    def index
      @messages = Message.all    
    end
    
  10. This goes into app/views/messages/index.html.erb (Get it from pastie):

    Enter new message!

    <% remote_form_for :message, :html => {:id => "message-form"} do |form| %>
    Author:
    <%= text_field_tag 'author' %>
    Message:
    <%= text_area_tag 'message' %>
    <%= submit_tag "Submit!", :id => "submit-button"%> <% end %>
    <%= render :partial => 'message', :collection => @messages %>

    We are showing the form for the messages and list the already exiting messages below the list.
    Note that we are using the _remote_form_for_ Rails helper to create an AJAXy form. This is already obtrusive, since if you observe the generated HTML, you will see that the form has an onsubmit parameter with some horribly looking code attached to it.:



    Obtrusive helper.png



    Sure, you can go ‘meh’ all the way, but slinging Javascript code all over the place is just as bad idea as writing inline CSS (or even worse, using HTML code for styling) or putting Rails code into views. It will work without any problems – but it’s just not the right way of doing things, especially if your code is going to hit a certain size.
  11. You probably noticed that we are rendering a message as a partial – so create a partial file app/views/messages/_message.html.erb with the following content (Get it from pastie):

    on <%= message.created_at.to_formatted_s(:long_ordinal) %>, <%= message.author %> said:
    <%= message.message %>
  12. We need a ‘create’ action in MessagesController in order to process the form submission (Get it from pastie):

    def create
      @message = Message.create(:author => params[:author], :message => params[:message])
    end
    
  13. And obviously we’ll need to render something to respond to the create action. Using the standard Rails way, RJS, we might come up with something like this (in app/views/messages/create.js.rjs – Get it from pastie):

    page.insert_html :top, "messages", :partial => 'message', :o bject => @message
    page.visual_effect  :highlight, "message-#{@message.id}"
    

    Here we insert the “messages” partial, using the just created @message, and throw a splash of yellow fade into the mix for good measure. Easy peasy.

  14. We are done! Fire up script/server, hit localhost:3000/messages and voila!

The Good Way

Here I am presenting only the steps that are different from the above – i.e. if step 3 is skipped, use the one from above.

  1. Creating a new Rails application

      rails unobtrusive-shout-wall
      
  2. Get into the Rails dir

    cd unobtrusive-shout-wall
      
  3. Same as above
  4. Same as above
  5. Same as above
  6. Same as above
  7. Since we are going to use jQuery (unobtrusiveness is *not* a property of jQuery, you can be just as unobtrusive with Prorotype – but I switched to jQuery just before learning how, and now I am lazy to go back check out how in the ‘prototype unobtrusive’ directory in the github repository), you have to download jQuery with some basic effects, as well as an AJAX form handling library (still from the directory unobtrusive-shout-wall – Get it from pastie):
  8. curl http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js > public/javascripts/jquery.js
    curl http://www.malsup.com/jquery/form/jquery.form.js?2.28 > public/javascripts/jquery-form.js
    curl http://view.jquery.com/tags/ui/latest/ui/effects.core.js > public/javascripts/effects.core.js
    curl http://view.jquery.com/tags/ui/latest/ui/effects.highlight.js > public/javascripts/effects.highlight.js
    

    and replace

    <%= javascript_include_tag :defaults %>
    

    with

    <%= javascript_include_tag 'jquery' %>		
    <%= javascript_include_tag 'jquery-form' %>
    <%= javascript_include_tag 'application' %>
    <%= javascript_include_tag 'effects.core' %>
    <%= javascript_include_tag 'effects.highlight' %>		
    

    in the layout file.

  9. Same as above
  10. Same as above
  11. Same as above – just delete “remote” from the name of the helper, i.e. use a standard Rails view helper, form_for
  12. Same as above
  13. Since we are not relying on Rails to do the rendering for as via a template file, we return the html chunk that we will render from Javascipt. So your create action should look like (Get it from pastie):
    def create
      @message = Message.create(:author => params[:author], :message => params[:message])
      render :partial => 'message', :o bject => @message
    end
    
  14. Now comes the fundamentally different part – instead of using RJS to respond to the create action, we move all our code to application.js (Get if from pastie):
    $(document).ready(function() {      
      $("#message-form").ajaxForm({success: handleNewMessage});
    
      function handleNewMessage(response, statusText) {
        $("#messages").prepend(response).effect("highlight", {}, 1500);
      }    
    });
    

    I don’t think so that this code is particularly more complicated or hard to understand that the RJS one. Everything is inside the ready() function, which means that it’s only run once the document is properly loaded. Then we declare that “#message-form” is an AJAX form, and that upon successful submission, the handleNewMessage() method should be called. And if that happens, we add the response (which is the return value of the “create” action) to the “#messages” div, just as we did in RJS. Then we apply the yellow fade! w00t!

  15. Same as above

(You can check out the code used in this post from it’s github repository).

Conclusion

As you can see, the only real difference between the obtrusive and non-obtrusive version is in the last 2 points (downloading and including the jQuery header files can be easily solved with Rails templates): instead of leaving the rendering part to Rails, we return the response as a string and dynamically insert it from jQuery. With about the same effort, we kept all the Javascript code in application.js, which is much cleaner this way (you can open up 1 file and check out all the JS/AJAX behavior in one place), especially after introducing a lot of Javascript functionality into your code – in other words, for the same amount of work we got something much better. Please try to keep this in mind when you are working with Javascript and Rails the next time – believe me, it can save you from a lot of pain!

RailsBridge is Born

rails_bridge.pngI surely don’t have to introduce last week’s Ruby/Rails earthquake to anyone by now – it has been covered by a boatload of blogs (including this one), analyzed, argued over, rebutted, reddited, dugg and whatnot – suffice to say, it’s time to move on. It was a rather unpleasant drama piece, but fortunately it shed light on some problems the Ruby/Rails communities are facing, and (besides the ensuing trollfest and pointless arguing) it had a pleasant side-effect: a handful of people started to discuss how things could be made better, creating a small (and growing) but determined community: RailsBridge!

Say Hello to RailsBridge!

RailsBridge’s mission is “To create an inclusive and friendly Ruby on Rails community” (check out details on the homepage). Everyone is welcome to participate – with ideas, suggestions, design, code, new project proposals or just about anything that would make Rails a more open and accepted technology and community.

It’s very important to understand that we are not trying to form yet another oh-my-god-we-are-so-awesome Rails group of uber-hackers which looks down on everyone not in it’s ranks – for two reasons, at the very least:

  • RailsBridge is open to anyone! – you don’t have to be a Rails core commiter, coder with 20 years of experience or a renowned Rails blogger – it’s enough if you’d like to make the Ruby/Rails scene more welcoming in any way
  • We are trying to promote the exact opposite philosophy – we acknowledge that Rails’s image is somewhat tarnished because of the “rock star” attitude and we’d like to show by our actions that we are working on this and will eventually turn Ruby and Rails into a very welcoming and enjoyable community

Surely, this is quite a venture – our mission statement sounds great, but everyone can do the talking on just about whichever Gordian Knot out there, be it world hunger, world peace or friendly Rails. We’ll have to demonstrate that we mean serious business, and that’s why we need you – everyone’s ideas, insights and help matters! Check out the RailsBridge homepage to learn more about what are we up to and how to get involved.

Rails *is* (still) a Ghetto

nice_ass.png

While I know the title is both asking for trouble (because of the now anecdotal original article with a similar title) and flamebaity, please read on – my goal is not to get some great stats but rather to know your opinion about the situation and discuss the possible solutions of the problem.

How it all started…

I would not like to re-iterate what has been said on several blogs, just to summarize: Matt Aimonetti, member of the Rails Activists, gave a presentation at GoGaRuCo which contained sexually explicit images (according to some – I am not here to judge whether that’s true, and it doesn’t matter anyway, as you’ll see in the rest of the post).

I am not really discussing whether it’s appropriate to have images of nude chicks in your presentation at a Ruby conference (I think it’s not, it’s unprofessional etc. – but that would be a matter of a different post Update: Someone summed this up in the article’s reddit thread nicely: If you’re a Rails programmer, or a Ruby programmer, and you don’t decry this sort of thing, you have no business calling yourself a professional. It doesn’t matter how large your website is, how easy it was to write, how much better it is over PHP or ASP.NET or J2EE; by definition, you do not belong to a professional community. That’s all there is to it.
It’s incumbent on every Ruby programmer to either reject this sort of misogynistic sewage, or accept that you’re never going to advance the promotion of Rails in the public perception because members of the community still think it’s edgy or cool to put pictures of strippers in their public presentations.
And here’s a hint: if your decided reaction is to talk about how unimportant this is, how much it doesn’t matter, or how much it doesn’t offend you personally, you probably don’t understand professionalism at all.
) because sadly, I think there are far bigger problems here than that – shedding light on them is the real purpose of the article, not talking about pr0n at GoGaRuCo again.

Would You Walk Into a Hindu Temple with Your Shoes on?

hindu_temple.pngI have been living in India for 2 months last summer, working on a Rails startup. Maybe I am odd or something, but I knew that I had to remove my shoes when entering a Hindu temple, and _no one had to convince me (what’s more, I didn’t even think about it for a second) wether this is the right thing to do, why is it so, whether I should do otherwise etc_. This is a similar situation – I just don’t do X when speaking at a conference, if I suspect that X makes feel even one person in the room uncomfortable, whether because of his gender, race, nationality, Ruby/Rails skills, penis size or what have you – _regardless whether I think it’s fine for me, my wife, for other members of the community and/or the majority of the room_.

The trick is, how does a *hindu* feel when I enter a temple in footwear (even if that is perfectly acceptable in my country, culture, family, friends) – it’s perfectly irrelevant how do *I* feel in the given situation. Using the previous paragraph, try to apply this to a Ruby/Rails conference.

Shit happens…

Until this point in the story, I see no problem at all, and could even agree with the guys asking “what’s wrong with you, don’t make a fuss out of nothing” – the pictures Matt used are non-problematic in my book, and he had no idea they are problematic in anyone’s book – theoretically it could have worked, but the point is, *it did not*. Some members of the Ruby community got offended, and here our story begins.

…and hits the fan

One of the real problems is that after this has been pointed out, Matt still keeps answering “As mentioned many times earlier, I don’t think my presentation is inappropriate.”. As I mentioned two paragraph above, it doesn’t matter what do you think, unless of course, you don’t care about offending some members of the community. In that case you should not try to apologize at all. However, if you are trying, reciting “I don’t think my presentation is inappropriate” will not put and end to the discussion. It just doesn’t work. Why can’t you just simply apologize, admitting that this was a bad move (because it offended some, not because porn, sexual images or whatever in presentations are bad, per se) and finish the discussion?

Rails is Still a Ghetto

However, in my opinion that’s still not the worst part of the story, or to put it differently, some members of the Rails community still found a way to make things worse, by applauding to all this:


dhh_pr0n_is_great.png

OK, you say, we are all used to DHH’s style, this is just how the guy is. That’s (kind of) cool, but I heard that most of the Rails core team (and obviously Matt himself) has the same opinion – and that’s a much more serious problem, because it means that a Rails activist, backed by DHH and other Rails core members finds all this OK, despite of the fact that numerous people in the community voiced their opinion otherwise.

This is not about being a closed-minded prude, shouting for police and suing everyone using sexually explicit images in a presentation. This is not even about women, as I have seen both males and females on either side of the fence. This is about mutual respect – I don’t agree with you, but respect your feelings. Or not, as demonstrated in this case.

So Rails continues to be the most socially unacceptable framework – associated with arrogance, elitism and whatnot in the past – now add pr0n images in presentations. Thankfully RailsConf is held in Las Vegas, and that should calm down all the people who associate Rails with all this crap :-) . The real problem is that people associate you with the tools you are using – think Cobol, PHP, Java… or Rails. By being part of the Rails community people associate me with Railsy stereotypes automatically, which aren’t nice at all right now.

I hear you, dear creme-de-la-creme Rails (core) member, I know you don’t give a shit, and you think this is all prude babbling – because your hourly rate is more than some of us earn in a day, and you’ll be sought after even if Rails will have a much worse image than it has now. But 99.9% of us are not in the ‘circle of trust’ and would be happier if Rails would not be constantly associated with a ghetto.

MINASWUBN

In case you are wondering what does the acronym stand for, it’s “Matz is Nice And So We Used to Be Nice”. Unfortunately, the stuff I don’t like about the Rails community is sneaking into Ruby too, it seems, as the above case demonstrates. Besides this, the count of aggressive comments and reactions on various blog posts is really disturbing to me. Please (at least Rubyists) try to avoid being contaminated by all this shit and stop thinking you are cool because you can swear on a forum (always in anonymity). You don’t have to be a douchebag just because you are a Rubyist / Rails coder, as surprising as this might sound to some.

Conclusion

I think “incidents” like this and getting more and more antisocial members are inevitable by-products of growth in a community. The questions is, whether, and if, how, do we stop them. The problem is that it seems to me the Rails “top management” doesn’t want to stop them (what’s more, even encourages them) in the first place (please prove me otherwise – maybe I don’t see the full story – I’ll be the happiest to admit that I am talking bullshit).

I have to admit I have no clue what would be the right move – burying our heads in the sand and pretending everything is fine is not. Please leave a comment if you have an idea or anything to add.

FOWA Dublin videos (including DHH talk)

dhh-ftrw.png As promised, here’s a quick post about the FOWA Dublin videos which have been uploaded recently – including the most anticipated Doing a Start Up in the Real World (a.k.a. ‘Fuck the real world’) talk by David Heinemeier Hansson. If you watch only one video, make sure it’s this one :-) .

I just got back from a wonderful Scotland on Rails 2009 so will post my experience later today (or whenever I’ll be able to catch up with all my chores – spent almost 1.5 week in England + Scotland so my TODO list is huge :-)

Twitter Unveils New Premium Accounts? I hope not!!!

twitter_post.png
Update: I definitely jumped the gun with this one :-) It *is* meant to be a joke. Thanks god.

I hope this is a joke. A bit sounds like it, but it might be still true. I am really hoping it’s not!

The news (“Twitter Unveils New Premium Accounts“) is spreading like wildfire on twitter right now, making it impossible to even guess who retweeted who, but that doesn’t really matter anyway. What matters is that everyone in twitterverse is talking about it right now. I really do hope it’s just a scam, because I don’t like the idea at all… here’s why:

  • Raising the character limit – (this is the part that makes me think/hope it’s a scam) I believe twitter’s success is partly because of the ‘do less’ scheme. If you look at jaiku, plurk, pownce and a ton of other failed (or let’s put it like this: not as successful as twitter by a wide margin) microblogging services, who hoped to differentiate themselves from twitter (also) by adding a ton of other features twitter doesn’t have, didn’t succeed. I (and I believe I am talking for the most of the twitter users out there) love the service exactly because it’s a no-brainer: you have to squeeze some interesting information into 140 chars. That’s it. The story ends here.

    There are plenty of third party apps (several hundreds when I last checked) that add this or that on top of twitter, some of them actually very good. That’s a win for everyone: you can choose which service to use (often multiple sites are competing for the same type of service – competition is always a good thing!). Modularity is a good thing – not to mention that great services (like search, a.k.a. summize) are integrated into twitter later anyway.
  • Messing it up – you get random followers?!?! Why is that? I am already annoyed by the ‘quest for numbers’ “feature” of twitter – totally unrelated people following each other just to bump their follower count. This is kind of understandable, as the follower count is viewed as an universal number of influence/power on twitter, but still, why should you push information to people (or consume the information they are pouring onto you) if you are not in the same niche/field/market? This sounds really crazy.

    Anyway, how will those 20/100/1000 random followers be chosen? Will they accept that they have to follow someone? Bullshit meter +1. This really smells like hoax.
  • Elitism – the same concerns as with Kevin Rose’s latest brainchild, wefollow.com – the rich get richer, the poor get poorer. Invisible (and possibly otherwise great) people will remain undiscovered Good Will Huntings for good, while users already boasting thousands (or much more than that) followers will climb to even more higher places. How is this good for a community as a whole??!
  • Price – this is basically the B variant of “Elititsm”. Open source enthusiasts, students, researchers, a big part of developers (the group I am personally interested in) and a lot of others (you surely have a similar group with other interests) won’t be willing (and able to in some cases) to pay the $15/$50/$100 monthly fee – it’s just too much. $5 is OK for everyone, but that doesn’t buy you nearly anything. The other premium levels are just too much for most of people, again just pushing the elite to higher places.

I have a ton of other points, but the more and more I think about it, I seriously think this is a SCAM. I really love twitter and hope they’ll have a solid business model and will make a ton of money sooner or later, but please not this way. I am not even against premium accounts, or just paying a sensible monthly fee – would surely do that – but please stay with the roots and don’t promote elitism. Khtxbai!

DHH: Fuck the Real World

dhh-ftrw.png
I planned to do a writeup on the talks @ FOWA Dublin, but Dave Concannon did such a great job that I could not add too much without re-iterating what he said, so I’d like to concentrate on just one talk instead, which totally blew me away: Creating Software in the Real World by David Heinmeier Hansson.

Let me start with a bit of background – as a Rails developer for almost 3 years now, this was obviously not the first time I heard about David, 37signals, their Getting Real principles, business practices etc. – however, this was the first time I have seen him live, delivering a great talk. And it made a huge difference.

If you happen to know me, you probably know that I am not a guy who gets ecstatic because someone is an alleged rock star, ninja, pirate or zen master, even if he happens to be author of something as significant as Ruby on Rails which I think is the greatest piece of software since Prince of Persia. I had my own reservations wrt David (a slew of blog posts about him suggest that he is kind of a controversial character to say the least: the potty-mouth Dane, the F-bomb terrorist who always has a curse or two up his sleeve for good measure, brings on the vitriol first and ask questions later etc. etc.) After seeing him perform live, I am quite sure that most of these negative comments are either taken out of context, coming from the sour grape camp or are just plain wrong. Sure, David is not a grail knight when it comes to defending his stance – that’s one of the reasons why he keeps building kick-ass stuff like Rails or Basecamp. He totally pwn3d the stage from the very beginning, and even if I wanted to be very critical, I just could not see that he is the douchebag suggested by his critics.

It also became clear to me that DHH != (only) Rails. While he is often primarily described as the author of the Rails framework, that’s a gross oversimplification of the big picture. I think Rails is “just” the side effect of David’s passion to create web apps in a getting real way. Above everything else, he is a guy with a vision who gets things done, no matter what does it cost – e.g. writing a web framework in Ruby (the language he found the most “getting real” style when he needed to implement Basecamp).

OK enough rambling – here is the summary of the talk (I certainly could not get everything, but I am trying my best)

* “We don’t have 200k RSS subscribers because of my deliciously swirly hair” – a central question (asked also during the Q/A session): how on the earth did Basecamp and other 37signals products become so popular? All of a sudden, they emerged from nowhere! As David points out, it was not that ‘out of the blue’ as it looks like. When they started with Basecamp, they already had 2000 subscribers on their blog, Signal vs Noise, so they built a channel which through they could advertise themselves.
This advice meshes with one of my favorite points from Getting Real which goes something like “Just start doing something”. Really. Start blogging. Creating/contributing to open source software. Get on twitter. Let your voice be heard! You probably won’t have thousands of listeners right away, that’s OK – it takes time. But you can start today!

* “Fuck the real world” – probably the tagline this speech will be remembered for. Taken out of context, DHH critics have yet another flickr snapshot where they can demonstrate arrogant F-bomb usage, good for nothing. Bullshit. It was designed and “dropped” perfectly, kicking off the whole talk! David’s advice is to stop listening to “advice” which goes like “yeah, this is a great idea/concept/whatever, but it will not survive in the real world”. Sure, Rails didn’t look like a great idea when Java and PHP have been the bee’s knees. Today no one (except the hard-core sour-grape Java/PHP/COBOL fanboys) would argue that it made a big impact on how web software is developed (call it web2.0 if you like). David said that none of their current apps passed the “real world” (in the sarcastic sense) test – and look where they arrived.

* “I didn’t start coding when I was 6, but 21, and Jason (Fried) started business school later too” – David de-bunked the myth that you have to be a “natural” to accomplish great things. True, quite a few of the IT related success stories start with “I got my first Sinclair ZX Spectrum/Commodore/Atari/Amiga when I was 4, started coding in xyzBasic at the age of 5, roocked fooBasic at 7 etc. While this is all great, and certainly a big help if one happens to become a professional coder later, it’s certainly not the only path to victory. There is no such thing as “starting out too late”. Just make sure you start today.

* “Forget the _advice_ that you shouldn’t build too simple software” – “Good bye to bloat”, “Simple, focused software that does just what you need and nothing you don’t” are rules 37signals are living by, not just pretending. If you check out their award-winning software, used by over a million people today, you’ll notice that despite of their age (several years) they are still simple pieces of focused apps. That’s one of the secret sauces of 37signals: if it works for them, why shouldn’t it work for you? The point is to create something usable, not bloated.

* “Would I pay for this app?” – a great reality check they are asking themselves all the time. If you wouldn’t pay for such a product, why would anyone else?

* “Running your own business = the power to say no – You should be able to say “no” and stick to your vision rather than trying to add all the bells and whistles required by the customers. Note that this does not mean you should refuse / reject all the requests – some of them are really great, but eventually *you* have to decide which ones to keep and which ones to boot (because they just don’t fit into your vision).

* “startup is a category I hate – you have to build a business” – another great point. It’s so trendy to found start-ups today, it almost sounds like a game for grown-ups. (It’s not, I founded two of them myself and it was the hardest part of my professional life so far. Compared to a startup, regular freelancing / contracting feels like a walk in the park :-) ). You have to plan for long term, have real goals, start making money as soon as possible (vs. wait for google or another Silicon Valley dude with a lot of money), get real. It’s not a game, it’s a business.

* “You don’t need rock stars, but a rock star environment. Your employees are not stupid” – argues that the environment your company is in matters more than the individuals. With a great company culture where you respect and trust your employees (e.g. 37signal employees get a company credit card, with one policy – use it reasonably! wow) your team will live up to their full potential. By creating and nurturing an atmosphere of growth, you won’t have to micromanage everybody and everything – don’t treat your employees as idiots, because they are not.

* “An idea is so small part of a business that it’s almost a rounding error” – So true. I have so many ideas right now, that it would take months to prototype them – but that would eventually become an endless process, because during prototyping I would get new ideas, etc. Ideas are cheap, everyone has them. The question is whether you have the skills and perseverance to make them happen.

* “you have to build massive popularity slowly” – Probably my most favorite point of the talk. As a small business owner, startup founder and entrepreneur I found out on my own skin several times that it’s relatively easy to start something – be it a startup, a blog, an open source project, a client assignment, a relationship/marriage/organization/company/habbit/just about anything. The trick is to keep pushing with the initial vigor (at least) once you reach the plateau – for a long time, until the breakthrough comes (you finish your project, your blog gets picked up, your startup is featured on techcrunch, etc.) That’s one of the main things that sets successful ventures apart from non-succesful ones. Everybody has ideas. Everybody can start. A few of them can finish because it takes time and perseverance. You have to believe in yourself and your idea to make it through, as long as it takes.

Unfortunately this summary can’t capture the atmosphere of the talk – as far as I can tell, the room was on fire, everybody was charged up and motivated by this speech (I can’t imagine who wouldn’t be). For me it was worth the price of the conference alone. Massive thanks to David!

FOWA Dublin – a Mixed Blessing

fowa.png
I am sitting on the plane flying home from Dublin, trying to summarize my thoughts about the Future of Web Apps conference. While I think that overall, FOWA Dublin was worth attending (because of the speakers, especially David Heinemeier Hansson, who surpassed all my (high) expectations – will post about it later), in my opinion it did not live up to its full potential. The most annoying thing is that just with a tiny bit of more effort it could have been an 5-star conference in every sense of the word – however it missed to deliver this additional plus, leaving a bad taste in my mouth.

I have seen blog posts/tweets raving about the conference – in a paradoxical way (given what I just wrote in the above paragraph) I can mostly agree with those posts too. The trick is whether you are judging the conference solely based on the content (in which case I can agree with the above blog posts) – or as a whole, including venue, wifi, organization, socialization, before and after parties, freebies, extras, all the bells and whistles. Using the latter method (and I see no reason why one should not) the conference was mediocre IMHO – a few thoughts why:

* (almost) no wifi – After all, a conference centered around the web full of nerds with iPhones, notebooks and other wifi-hungry devices needs no wifi right? Wrong. (OK, the reality was more complex than that: there _was_ some kind of “home wifi” but in practice that meant constant hunting for the signal which broke randomly after a few minutes)

* crowd – A huge crowd (or too little space, if you put it like that) right from the very beginning; Arrived 30 minutes before the actual start, to experience an episode from the life of herrings in the lobby on my own skin, without the slightest idea of why couldn’t we enter the auditorium or what are we supposed to do (other than brewing in our own sweat and looking around to see more puzzled herrings)

* the way the uni sessions were delivered – no microphone; very noisy from outside; people running around all the time, causing constant distraction;

* no announcements of talks – (like someone running out to the foyer and shouting ‘hey guys we are starting in 5 minutes!’) – half of the people still in the foyer, resulting in slow, continuous trickling into the auditorium, again causing a lot of distraction (probably less distracting the closer you sit to the stage, but at the upper end it was really annoying). The doors were open for some reason, so constant murmuring from the foyer.

* No freebies – for this price, at least a coffee or two (and maybe I am not too demanding to add something like snacks/muffins/mineral water?) would have been nice. Ridiculous prices at the bar (well, quite normal compared to Dublin – 2-3 EUR for a tea, 4-5 EUR for a coffee, 5-6 EURs for a pint of Guiness, you get the idea)

* seats – people standing around; though there were theoretically enough seats, de facto about a dozen or more people have been standing around all the time, which felt weird to me, even though I managed to get a seat somehow during the whole conference.

* no sockets – If you were lucky enough to sit close to one of the few (ok, make it a dozen – for 400 ppl!) sockets in the wall, you could recharge your laptop. Otherwise, you have been out of luck.

* a huge rush – I had the feeling that the organizers wanted to pack as much action into one day as possible, which theoretically sounds great, but IMHO it didn’t work out that well in the practice; I missed the beginning of two talks and one full talk after the lunch break because the breaks were barely enough to accomplish anything, be it buying snacks/coffee, use the toilet (1 working toilet for hundreds of guys – great idea) or to grab a proper lunch at a restaurant.

* it was overpriced for what we got – (or we got too little for an OK price) – c’mon, 400 people at an average price of 150 EUR, is 60,000 EURos, + sponsors like Sun and Microsoft, and not even a fucking cup of cofee? We organized EuRuKo in Prague last year for 20EUR / dude, had Matz, the creator of Ruby as well as a roster of other Ruby celebrities, conference t-shirts and a slew of other conference souvenirs, industrial strength wifi, catering (several tea/coffe/snack breaks, hot food for lunch) for 2 full days, free coffee and beverages, and even some free beers (cheers for Brightbox) all this in the heart of Prague. I repeat it again – for EUR 20!

* Little room for socialization (both in physical and abstract sense) – no before-event party (e.g. compare it with Scotland on Rails – three weeks to go, but I know about almost all the attendees, when and where are we going for a whisky (pre-, during- and post-conference), who is staying where, arriving when, going for a sightseeing tour with an option to join them etc. All the organizers did to make this happen was they set up a google groups mailing list and a twitter account, updated with great info every now and then, enabling the attendees to augment it with their own stuff (e.g. when are we going to have a boatload of whisky))
OK, this is not entirely an organizational problem, but still, all the conferences I went to so far addressed socialization in some way.

* after-party – Some of the guys were raving about the after-party – well, I think it was poorly organized too. I went there on time, and had no idea where the FOWA-party “crowd” is – I have seen random micro-bunches of probably-FOWA attendees scattered around the huge (otherwise excellent) Dandelion bar. Asked a few of them about the party, they were just as clueless as myself. Ok, so I left to grab something to eat to the nearby TGIF, but the situation got even worse when I came back. The dispersion of probably-FOWA-micro-bunches-or-lone-rangers went up significantly, so after a few minutes of strolling around I left. Maybe I was just unlucky and popped up at times when everybody was at toilet / had a quick smoke outside or whatever, but some more info (an A4 sheet of paper with ‘we are here’ perhaps) wouldn’t hurt.

Wow – re reading what I just wrote makes FOWA Dublin look really bad – but unfortunately I don’t know what should I remove from the above. These little (or sometimes not so little) things really added up, and fscked up the whole atmosphere. A little more organization and polishing would have solved 80% of the problems.

I am going to summarize a few of the talks I enjoyed in a follow-up post – now I am too tired for that – spent 6 extremely exhausting days in Dublin so need to get some sleep first!

“I guess Ruby is over: it Was Fun While it Lasted.”

ruby_sad.gifUpdate: As several guys pointed out in the comments, Tim’s remark which basically pulled the trigger was sarcastic – I guess have to re-calibrate my sarcasm meter. So you need to replace “Tim” and whatever he said with a different guy and his random quote. There are plenty of them out there these days, so the choice should be easy :-) .

This rant was in the works for quite some time – I ditched it at least two times already, convincing myself that there is no use to get into language wars and similar nonsense… but people didn’t let the issue go (i.e. that Ruby jumped the shark / it started to suck for some reason etc – most recent example being a tweet by @timbray) so get ready for some grandiose rantbling!

Tim Bray: “I guess Ruby is over…”

Srsly? By what measure? Actually when did it start? Why exactly then? Again, by what measure? What does ‘over’ mean at all? Says who?

I am currently reading “The Black Swan: The Impact of the Highly Improbable” from Nassim Taleb. There is a section describing Tim’s logic perfectly:

“By a mental mechanism I call naive empiricism, we have a natural tendency to look for instances to confirm our story … – these instances are always easy to find. You take past instances that corroborate your theories and treat them as evidence… I can find confirmation for just about anything, the way a skilled London cabbie can find traffic to increase the fare, even on a holiday”

… or the way Tim can find a bogus evidence for Ruby’s alleged decline, whatever that means. I am wondering where have the current “ruby jumped the shark” guys been 3 quarters ago when Ruby books have been on a roller coaster riding up with the speed of light?!?!

Naive empiricism is everywhere

Guess what, I am guilty of naive empiricism too: I wrote an article stating the opposite of Tim’s tweet, based on similar, but opposite O’Reilly data (i.e. Ruby book sales on the rise). Why? Because I have been a Ruby/Rails zealot back then already, that’s why! And I *wanted* to see Ruby on the rise, and did not really care whether my claims were objective (I *wanted* to see that they were objective – meta-naive empiricism FTW!)

Another great example of naive empiricism is the ‘CDBaby: from Rails to PHP‘ vs ‘MuxTape: from PHP to Rails‘ 2-part saga: the funny thing is that both Derek and Luke argue very convincingly and charismatically about the exact different side of the same coin: why the move from framework X to Y has been the best idea since sliced bread, how it saved their ass, pushed productivity to the ends of the earth… arriving at a total opposite conclusion using the same reasoning.

Another bogus reasoning I hear a lot: Python is used in google so it’s > Ruby! Unfortunately enough for the guys treating this fact as a royal flush , Ruby is used in NASA, by some of the smartest folks in Ruby-land. So what?! Does this mean Ruby > Python (or at least is equal to gogle <=> NASA)? Not at all (In my opinion Ruby > Python actually, but 1) this is a personal preference thing 2) it has nothing to do with google vs NASA 3) is a topic of a different rant, which possibly won’t be written as I grew tired of lang wars fought with flame throwers).

Or take github: currently 31% of the code living there is Ruby (and you can’t really argue that by now, github matters – it’s not just a hobby project of 2 guys tired with their original startup any more). So according to this measure, everyone start learning Ruby!

but Tim argues instead:

“…Everyone start learning C#”

This is the second part of @timbray’s rather questionable tweet… and here is why:

Comparing the need for Ruby workforce to the C# one is like comparing the need for planes to that of cars. No correlation.

C# is usually used…

  • for enterprisey stuff
  • to write big, monolithic apps
  • by big teams for long-term projects
  • by BigCO running on a large budget
  • in M$ shops

Ruby/Rails is the total opposite… it’s usually used…

  • for coding quick web apps / internal DSLs / domain specific stuff
  • to craft lean, focused apps, interoperating with each other
  • by small, agile, flexible teams, sometimes lone rangers
  • Usually smaller budget (direct consequence of the first point)
  • in shops with totally different culture compared to that of M$

Both lists could grow unbounded if I cared to come up with more points.

So Tim is essentially saying ‘no need for agile teams cranking out top notch (usually web-based) software fast – everybody jump on the Titanic (the safe 9-5 world of enterprise apps in one of the cubicles of BigCO).
Sorry, but this is utter BS. There will be always a need for lean, agile, quick teams. Following this logic, you should abandon the Python/Django ship too. And btw guess what – the Titanic sunk in the end, no matter how safe it originally was.

So where’s Rails?

It’s not clear to me where is Rails (and a slew of other widely used frameworks/software produced in Ruby) in Tim’s picture. The thing is that Ruby is tied to Rails just like the US economy is tied to just about everyone else’s economy around the world. If Rails prospers, so does Ruby – a kick-ass r41lz h4xx0r is a kick-ass Ruby h4xx0r with knowledge of Rails after all.

However, it looks like there is need for Rails coders: Tom Mornini, one of the founders of Engine Yard, the leading Ruby/Rails hosting states that good Rails developers are very scarce. And while Rails developers will be a scarce commodity, Ruby developers will be too.

Ruby isn’t Fun anymore… wtf?

This is the original part of the rant, from the time when more “ruby/rails sucks” articles popped up in a quick succession, followed by a grandiose trollfest on various social sites, and eventually meta-ranting (my personal favorite).

Apples and Oranges Strike Again

I am a bit confused after reading all this outburst: I seriously think ‘fun’ vs ‘mainstream’, ‘imperfect’ (or even ‘buggy’), ‘slow’ etc. are orthogonal problems. Why should be Ruby less fun than it ever was because now it has more acceptance / users / enterprise penetration and/or it’s slow / 1.9 is not a big deal / it leaks memory (fill in the other pain points from the rants)??! This just doesn’t make any sense. Ruby is fun _and_ it has some problems to address. These two are not contradictory statements at all. It’s immense fun to be with my 2-year old daughter, though she is sometimes hard to handle – so I should say it’s no fun anymore?!?

“Ruby isn’t fun any more *for me*” is a totally different claim from “Ruby isn’t fun any more” (in general). I don’t give a shit if Ruby isn’t fun any more for *you*, but please, don’t describe it as community- or language-wide phenomenon. kthx.

Conclusion

You like python? Great! Putting bread on the table coding in Java? Cool. You’d like to play around with bleeding edge stuff (clojure/scala/erlang etc.)? All the better.

Ruby is slow? The syntax is obscucre? You don’t like Rails/DHH/fanboys/TextMate/Ruby/arrogant douchebags/whatever? Ruby is not fun for you (any more?)
Too bad, so sad – however, this doesn’t alter the fact that Ruby *is* immense fun for me, and a whole community of people, and no ranting will change that, no matter how hard you are trying.

I am not even arguing that Ruby is better than X – I am far beyond that point already (after having my share with some Java vs Ruby flamewars). I am just arguing that people should stop tweeting / blogging about nonsense underpinned with ‘evidence’ just because they want to see the world that way.

Advanced Twitter Queries with the Twitter Gem

twitter_post.pngI wanted a reliable way to find out a few things about my twitter account (for example which of the users I am following are not following me back) – unfortunately the third party apps out there are not always very reliable, do not exactly do what I want/as I want so I decided to check out how easy it is to hack up a more advanced query using a Ruby twitter API wrapper. It turned out that it couldn’t be easier!

There are several gems wrapping the Twitter API out there – I started to use the ‘twitter’ gem from John Nunemaker and I am perfectly happy with it so far. John did a great job supporting all the features offered by the API – it’s a different question that the API, like twitter itself, is quite minimalistic. For example I have not found a way to get all my followers/friends easily (drop me a comment if I am missing something) so I monkey-patched this into the module in a generic way:

module Twitter
  class Base
    def all_entries(method, options = {})
      all_entries = []  
      next_100 = self.send method, {:page => (current_page = 1)}.merge(options)
      while (next_100.size != 0) do
        all_entries << next_100
        next_100 = self.send method, {:page => (current_page += 1)}.merge(options)
      end  
      all_entries.flatten
    end
  end
end

for example you can call connection.all\_entries(:friends) to get all of your friends, given that you set up a connection to your account (I found only a method which returns your first 100 friends – didn’t spend too much time with the documentation though – agin, drop me a message if I overlooked something).

I have added a bit of syntactic sugar to be able to call connection.all\_friends instead of connection.all\_entries(:friends):

module Twitter
  class Base
    alias_method :throw_method_missing, :method_missing
    
    def method_missing(method_name, *args, &bloke)
      if (method_name.to_s =~ /^all_.+/)
        all_entries(method_name.to_s[/all_(.+)/,1], args[0] || {})
      else
        throw_method_missing(method_name, *args, &bloke)
      end
    end
  end
end

Here we ensure that only method calls that start with all\_ are handled by all\_entries, the rest is throwing a method\_missing since we are not interested in handling those messages.

Now it could not be easier to implement the function I originally intended to build: list of users who are not following back.

class Array
  def names
    self.map{|u| u.screen_name}
  end
end

module Twitter
  class Base
    def not_following_back
      all_friends.names - all_followers.names
    end
  end
end	

That’s all there’s to it (I am not a big fan of monkey patching core classes btw ; but in this case, adding the names() method to the Array class just made the method I intended to originally implement much cleaner so I rolled with it).
Note that since subtraction is a non-commutative operation, all\_friends.names – all\_followers.names is not necessarily the same as all_followers.names – all_friends.names.
This is how the final code looks like:

require 'rubygems'
require 'twitter'

connection =  Twitter::Base.new('yourname', 'yourpass')

class Array
  def names
    self.map{|u| u.screen_name}
  end
end

module Twitter
  class Base
    alias_method :throw_method_missing, :method_missing
    
    def method_missing(method_name, *args, &bloke)
      if (method_name.to_s =~ /^all_.+/)
        all_entries(method_name.to_s[/all_(.+)/,1], args[0] || {})
      else
        throw_method_missing(method_name, *args, &bloke)
      end
    end
    
    def all_entries(method, options = {})
      all_entries = []  
      next_100 = self.send method, {:page => (current_page = 1)}.merge(options)
      while (next_100.size != 0) do
        all_entries << next_100
        next_100 = self.send method, {:page => (current_page += 1)}.merge(options)
      end  
      all_entries.flatten
    end
    
    def not_following_back
      all_friends.names - all_followers.names
    end
    
  end  
end  

p connection.not_following_back

You can download/check out the code here – do not try to copy & paste it from the text as it will be b0rk3d.

In part 2 I’d like to set up a small Sinatra app showing the above users in a list – displaying their avatar, screen name and real name, plus a link to remove them if you decide so.

Ruby’s Most Underused Keyword

redo.pngI spent the first 2+ years in Ruby-land without even knowing about the probably most underused (and underrated) keyword of the language: redo. Even after I came across the first example and liked it immensely, I could not come up with another use for it, so I threw it to the bottom of my toolbox. Then I found another example, and another one – so I came to the conclusion that redo might be a valuable keyword in your Ruby arsenal after all – it is one of those things which you rarely need, but if you need it, it’s a perfect solution which would be cumbersome to replace with other constructs.

Break vs Next vs Redo

I am sure everyone is familiar with redo’s cousins: next and break. While next and break allow you to skip an iteration, resp. skip the rest of the remaining iterations altogether, redo does not skip anything – it ‘restarts’ the same iteration. In other words, while next transfers control to the end of the iteration block, redo ‘jumps’ to the beginning of the block. Let’s see an example, where redo is used to recover from an input error (code from “The Ruby Programming Language”):

puts "Please enter the first word you can think of"
words =%w(apple banana cherry)
response = words.collect do |word|
  print word + "> "
  response = gets.chop
  if response.size == 0
    word.upcase!
    redo
  end
  response
end

The trick is that whenever the user enters an empty string, the block is restarted with redo, asking the same ‘question’ until the user enters something that makes sense to the system.

A Real Example – Tail Recursion

As of now, Ruby does not support tail recursion optimization, so you either have to write the function in a non-recursive (i.e. iterative) way yourself, or suffer the consequences of a full stack… or use redo!

I recently came across Magnus Holm’s article on this problem. Magnus provides an elegant solution using redo:

define_method(:acc) do |i, n, result|
  if i == -1
    result
  else
    i, n, result = i - 1, n + result, n
    redo
  end
end

def fib(i)
  acc(i, 1, 0)
end

Magnus even worked around a redo perk: “The redo statement restarts the current iteration of a loop or iterator”. That means he couldn’t define a method with “def”, since that neither involves a loop nor an iterator. Maybe a less esoteric way relying on the same fact would be to use a lambda:

def fib(i)
  acc = lambda do |i, n, result|
    if i == -1
      result
    else
      i, n, result = i - 1, n + result, n
      redo
    end
  end.call(i, 1, 0)
end

Golf Time

Here is a Ruby golf riddle, which I have no idea how could be made this short (42 characters) without redo (via coderrr):

"Generate a random string of length 4 or more consisting of only the following 
set of characters: a-z, A-Z, 0-9"

Here is the winner, Magnus Holm‘s solution (The name sounds familiar? Right, the previous example was from him too – he understands the power of redo for sure :-) ).

(0..9).map{rand(?z).chr[/[^_\W]/]||redo}*""

The above solution might not be instantly crystal clear – so let’s break it down a bit:

  1. rand(?z) is equivalent to rand(122) (but shaves off a character!)
  2. rand(?z).chr turns the random number into a string (equivalent to its ASCII code, i.e. 65.chr == “A” etc)
  3. the regexp /[^_\W]/ means the negation of ‘everything but underscore or non-word character (digits and numbers). To put it another way, accept word characters but not an underscore. (\w includes underscore, so we need to get rid of that)
  4. rand(?z).chr[/[^_\W]/] acts as an identity function for letters and digits, but returns nil for everything else. So “a”[/[^_\W]/] == “a” but “@”[/[^_\W]/] == nil. “_”[/[^_\W]/] also returns nil.
  5. And now comes the redo trick: rand(?z).chr[/[^_\W]/] || redo will restart the block until a random character/letter is not found! w00t!

While one might argue that golfing examples are contrived by definition, I don’t always agree: the [/[^_\W]/] is a neat trick to get numbers/letters from a string only, as well as the use of redo is valid and non-contrived.

Conclusion

As demonstrated above, redo can be used in a variety of situations to produce an elegant solution that would look much more cumbersome without it. Of course all the usual stuff applies: don’t overuse, abuse etc. etc.

If you have any other interesting cases for redo, leave a comment – I’d love to see some more :-)

Ruby Quiz: Gathering Ruby Quiz 2 Data

ruby_quiz.png After running the Ruby Quiz show for almost a year, Mathew Moss, the second Ruby Quiz master had just retired (as a quiz master :-) – great work Matt!), passing the ball to Daniel Moore, who just kicked off the third season with the following problem:

I'm building the new Ruby Quiz website and I need your help...

This week's quiz involves gathering the existing Ruby Quiz 2 data from
the Ruby Quiz website: 

Each quiz entry contains the following information:

 * id
 * title
 * description
 * summary

There are also many quiz solutions that belong to each quiz. The quiz
solutions have the following:

 * quiz_id
 * author
 * ruby_talk_reference
 * text 

For some reason, no one (except me) participated this time – so for the first time in history, I am pretty sure my solution is the best of all! w00t!

Daniel did a really great writeup of my solution (which utilized scRUBYt! and Nokogiri) – check it out here (view the code here), so I am not going to do my own writeup this time.

The Top 30 Most Helpful People on #rubyonrails

Just about 2 weeks ago I have been bitching about the #rubyonrails channel (no need to look it up as this article will negate that anyways). Fortunately (for everyone I guess :-) some prominent rails guys came after me, gently kicked my ass and challenged me to check out #rubyonrails again (after leaving a bit pissed off about 2 years ago), claiming that the atmosphere has changed drastically.

So, I took their advice, joined the channel, and was indeed pleasantly surprised. During my 2+ weeks of stay, I can’t remember any incident (ok, except the constant trolling on TextMate vs Vim, Mac vs Linunx, Shoulda vs rSpec, jQuery ftw, how RJS sucks, how Java sucks (well, initiated by me ;-) ) and found most of the people very friendly and helpful. Also made a few friends and had some great fun.

I also discovered some great #rubyonrails stats by @radarlistener and persuaded him to add a little feature to it: display then number of thanks per all messages. It’s not a huge feature, but we can find out some interesting stuff with it – for example, the signal to noise ratio off different guys: which of them are helping out the most on average (we could probably dig out the reverse info too – a.k.a. help vampires, but that’s outside of the scope of this post).

So, without further ado, here is a top 30 list (the number behind the nick denotes “lines per thanks”, i.e. how much lines the given person had to enter to receive a “thank you”):

  1. pet3r: 69
  2. stympy: 70
  3. octopod: 83
  4. mikeg1a: 90
  5. mf_irc: 97
  6. koppen: 105
  7. noodl: 120
  8. eljo: 120
  9. topfunky: 126
  10. leeo: 128
  11. fcheung: 129
  12. chippy: 137
  13. rainmkr: 138
  14. gerhardlazu: 139
  15. blj: 142
  16. madrobby: 142
  17. darix: 154
  18. toretore: 158
  19. minam: 162
  20. thread: 162
  21. donomo: 166
  22. halorgium: 168
  23. sonofslim: 169
  24. don-o: 170
  25. claudio: 176
  26. melvinram: 180
  27. bitsweat: 180
  28. ddfreyne: 181
  29. archetypo: 183
  30. jacobat: 185

Hey where’s lifo and rsl? Wtf?!!11!1! My script must be buggy… need to spend more time on #rubyonrails to learn this Ruby thingy properly.

Thanks to @radarlistener for his great work on the stats, as well as other great #rubyonrails bots.

Learn at Least One New Language Every Year


I am sure almost all of you heard the now classic advice from the Pragmatic Programmer: Learn at Least One New Language Every Year! Since it is a beginning of a new year, I have seen a lot of bog posts by various people acting upon the advice and choosing to learn a language – this year I decided to follow suit, and learn … Javascript.

I can almost feel the disappointment mounting: What the #&$%^*&#*@ why not Erlang? Or Clojure? Haskell? Scala, Lua… ? Why Javascript? That’s so 1990s…

Why Javascript?

The answer is easy: right now I am a Rails web developer (not a distributed system architect, monad detective, human parenthesis parser etc), and though I know enough Javascript to get by in majority of the cases, I’d like to take it to the next level.

Don’t get me wrong: I understand that the rationale behind learning a new programming language is not (necessarily) the ability to put the newly acquired knowledge to use tomorrow, but rather to discover new patterns / schemes (no pun intended). Thankfully, Javascript means the best of both worlds: you will find a lot of new stuff in there (unless you happen to know some other esoteric languages – Javascript is a dialect of ECMAScript based on Self and Scheme) – for example, unlike most of the mainstream OOP languages (which are class-based), Javascript is prototype-based – while at the same time you get a powerful tool enabling you to create more effective web applications.

Using a Motorized Wheelchair Because you’re too Lazy to Walk

Why do you, as a Rails developer need Javascript? There is Prototype. And script.aculo.us. And RJS. And jQuery. And Dojo. And MooTools. And…

I really have to agree with Adrian Holovaty (of Django fame): “(Relying on server-side frameworks to generate JavaScript) is like using a motorized wheelchair because you’re too lazy to walk”.

So true. I am tired of seeing people doing stuff like:

  • Simulating even the most trivial things like $(‘element’).toggle(); with RJS
  • Using oberve_field for everything. The problem is that observe_field in it’s vanilla form sends a request to the server every time you hit a key. It’s easy to replace it with a bit of Javascript knowledge and stop hogging the bandwidth.
  • Instead using Javascript functions like setInterval / setTimeout they are simulating the desired behavior with Prototype / RJS
  • Trying to create great AJAX sites without much clue about Javascript (and just minimal knowledge about Prototype/RJS – spending a week or so on #rubyonrails was enough to experience this in it’s full glory ‘hey plz help bro cuz Im new to AJAX’)
  • Doing all of the above obtrusively – who cares about the totally littered HTML, just get it done somehow

And I am talking about trivial/mundane tasks above – what if you’d like to create your own custom widgets? Optimize your code? Rely on the browser for various things not supported by rails out of the box (e.g. in-browser caching)? Manipulate the DOM? Prototype/RJS won’t do everything instead of you.

(Don’t get me wrong, I am a big fan of jQuery, and application development would be painful and slow without it – I am talking about the fact that in some cases falling back to Javascript is unavoidable and/or ineffective)

Ok, I’ll Still Stick with RJS and I Like it Obtrusive!

Ok, you have been warned. Suddenly It seems not I am the one stuck in the 1990s… but whatever. Ignore JS in your Rails apps at your own peril.

However, Javascript is usable in many other settings too. It’s a general purpose programming language, roughly comparable to Python or Ruby, so it’s a misconception to believe that JS is just some obscure mini-language only good for some browser hacking (similarly as Ruby is believed to be a scripting language, or a language invented to power Rails). So you can do just about anything with Javascript that you would do with, say Ruby.

If you want some interesting specialized usage: building Firefox extensions. Judging by the current trends, browsers are becoming more and more important, according to some people to the point of taking over the place of an operating system. While currently I find that theory a bit far-fetched, it is sure that as a Web developer, you can’t ignore building Firefox extensions. You need a lot of Javascript to do that.

Then there is DOM scripting. You would be amazed to know how powerful DOM manipulation can be once you learn the ropes.

Obviously, you are using a Javascript framework (Prototype, jQuery, mooTools…). Though you can get by quite well with any of them without knowing too much Javascript per se, your effectiveness will go up with the amount of JS knowledge. It’s like learning Rails and ignoring Ruby. You can do it, but sooner or later you’ll hit a wall.

Let’s Hit the Waves

Douglas Crockford’s site looks like a good starting point.
On the book front, I am planning to get these titles (I am not using any referral crap, those below are plain amazon links):

If you have any suggestions, comments, ideas on how to do this thing better, please leave a comment.

Oh, and be prepared for some Javascripts posts in the future :-)

Getting Real with Balsamiq – Amazing Mockups in a Breeze!




I am sure that if you are a web/IDE/UI developer, want to communicate your ideas visually or even just need to visualize something more complicated than an empty rectangle now and then, you are yearning for a simple tool enabling you to create high-level mockups easily and fast. Photoshop sucks in this regard – it’s neither fast nor simple and not easy to use by any means. Other typical tools (MS Visio for example) are too heavy/bloated/… as well.

Balsamiq mockups to the rescue! Finally a tool with zero learning curve (you don’t even need to have any design skills), is dirt simple to use, and knows exactly the things you need to create beautiful mockups / sketches. Finally you can get real with sketching your thoughts!

Of course this is not to say Balsamiq is just for toying around – quite a few serious designers prefer Balsamiq to MS visio and other, more standard tools out there, so it is definitely a wise choice for more complicated mockups too.

Thanks for the raving, but what’s so good about it?

You have to try it out to get the hang of it, I can’t do that instead of you – but I can try to summarize the things I like the most:

Widget selection: You are creating the mockups by drag and dropping & configuring widgets. The selection of widgets speaks for itself:



It is just great to have widgets like a browser window, different charts, buttons, tabs, tables, stickers, callouts, scratch-outs… you name it.

Widget configuration: setting up the widgets to look ‘real’ is very intuitive and quick. For example setting up a data grid / table: after drag and dropping the table to your mockup, you can set the data up like this (on the left side you can observe the grid data you are entering ; on the right side you can view the result)






Configuring the other widgets is similarly intuitive and easy. You have a box called ‘property inspector’ where you can set up the widget, as well as bring it to the front/send it to the back etc. If the selection still does not meet your needs, request new widgets at balsamiq’s getsatisfaction customer center – indeed the author is extremely focused on customer satisfaction!

great hand-drawn icons – one of my favorite widgets are icons – you get these great ones below out of the box:






laying out the widgets – I really find the auto alignment of widgets with regard to each other super-intuitive and helpful. It totally speeds up the process that you don’t have to care much about the placement of the widgets – it will just look right with minimal moving around, even with a big number of widgets.

simplicity and intuitiveness – you really have to try it yourself, I can’t describe this point. After about 10 minutes of playing around, everything was intuitive and easy, I didn’t even notice and my mockup was ready, because it’s actually fun to work with balsamiq!

outstanding support – I emailed the author, Peldi a few times, and his answer was prompt, kind and 1000% on the ball – solved all my problems instantly! Try to do the same with MS visio :-) (just kidding, please don’t)

So What’s the Catch?

There is no spoon! Err… catch. Whatever. Balsamiq is a tiny little bit rough around the edges, but I didn’t find a show stopper bug or missing feature. I ran into really little things, like

  • no “check for updates” feature which is omnipresent on the Mac
  • couldn’t edit charts at all (so if you have 4 separate charts, they are always 2 red/blue lines looking the same)
  • missing minor options for other widgets as well
  • would really like to have the ability to draw with a tablet/mouse (freehand drawing);
  • create custom widgets, by drawing them with a tablet (ok, this is probably too advanced for now)
  • more widgets and icons (though the existing selection is really, really good – had almost anything I needed so far)
  • minor bugfixes (the property editor vanished once and couldn’t bring it back – had this error just once)

If you want to know more

Definitely check out the not-even-2-minute balsamiq screencast to get a better idea what I am babbling about here – then head over to the balsamiq mockup homepage and check out their offer. If you are an open source contributor / blogger / speaker willing to write / talk about balsamiq, you might get it free for free with a great chance (I got it, so it’s definitely possible without publishing a blog that’s read by 100k people).

Conclusion

If you want to communicate your ideas visually, create a quick sketch of a webpage you are going to prototype, a concept of an IDE, or just want to jot down something non-textual quickly, balsamiq is your thing. Definitely try it out – you’ll be hooked in no time, promise!

Quo Vadis, Rails + Merb?


Update: I have been informed by a few prominent Rails guys (including a core team member) that the atmosphere of the Rails irc changed quite a bit recently (and that they are still working on it), so disregard the ‘rails irc is full of douchebags’ section please!

Happy New Year to everyone! I have been totally off the grid for the past 2 weeks, just getting back to work (several hundreds of e-mails in my inbox, ugh) so just a really quick blurb on Rails + Merb (I guess everyone is sick of the topic by now anyways ;-) . I am still dizzy after all the eating/drinking/pushing wii fit to the edge/doing nothing/… for 2 weeks, so get ready for some nonsensical rambling :-) .

My gut reaction to the very first article on the merger:

Someone thought it is funny to post April’s fools articles under the XMas tree.

After seeing about 3 more articles of the same kind:

Oh wow, there is a post-some-BS-which-is-a-bad-joke-even-for-april’s-fools meme going on! How amusing!

After actually reading the articles and digging around some more:

FUCK this is for real!!!

After calming down a bit and thinking it through:

This totally sucks. RIP Merb (2006-2008)

Sorry guys, I just can’t join the grandiose Rails+merb merger celebration just yet (I’ll pop a few bottles after Rails 3 will hit the streets AND it will (mostly) work as promised though – but I am skeptical). I was happy that there is a new community which is different from the Rails one (of which I consider myself part of, by the way) – I joined the merb irc and voilà – everyone was 100% helpful (no exceptions) even with the smallest things, and even beyond merb (I remember a great discussion on some fake data generators/factory girl style fixture replacement plugins which was started just because I asked a quick question on something totally different). How about the Rails irc? I don’t really know as I joined just once about 1.5 years ago but was turned down quickly by abrasive comments and overall behavior (e.g. a comment along the lines of “dude if you are still using habtm anywhere (and not has-many-through), get a life and/or go back to your java thingy” – I don’t even agree with this statement by the way, but that’s a different story). Of course I am not saying the rails irc is always like this, and/or that all the rails guys are douchebags (I am not, for example ;-) but I heard similar stories from more people, unfortunately.

Just for the record – I am still a Ruby and Rails fanatic (please no comments like ‘it is maybe time to check out django’ – no, it’s definitely not, the rails climate has never been better), I am doing all my professional work with Rails since 2 years, own tons of Rails books, sleeping in DHH pajamas etc. so I am not attacking Rails in any way. From that perspective I couldn’t be happier – Rails will become faster, more modular, less bloated etc. (I am sure you know all the bullet points from the other articles) and I have no doubt this is more or less going to happen. I am mourning over merb. The community. The influx of new ideas which maybe look bullshit when uttered/prototyped but have a chance to get into the framework because there is almost no bureaucracy. The competition. The monoculture (will Rails eventually eat Sinatra too?). The very fact that something like this just happened – a true black swan, in my opinion.

Of course, I am aware of the huge benefits too – first of all, the reverse ‘divide et impere’ effect, turning enemies into allies – who wouldn’t like to have Yehuda Katz (which indirectly means Engine Yard, to some extent), Matt Aimonetti and a ton of other kick-ass coders/evangelists in their ranks? Not to talk about the other great things – you obviously read about it all over the web already, so I am not going to duplicate that information again. However, in spite of all this awesomeness, something just does not feel right… this is not how it should have happened.

Just in case anyone cares what I am doing in this situation: I am packing my bags. Porting over Bob the Biller(tm), my first serious merb code to Rails. Advising my clients not to start merb projects from now on. Sorry merb, not long ago it felt like a beginning of a beautiful friendship – too bad you passed away prematurely. Rails, here I come again!