Fork me on GitHub

Keep Learning Conhecimento nunca é o bastante

Pair programming comigo!

Que tal aprender mais sobre técnicas e práticas para tornar seu trabalho desenvolvendo software mais prazeroso e satisfatório? Menos bugs, código limpo, bonito e flexível, testes rápidos e relevantes, entre outros benefícios, são facilmente obtidos através do estudo e prática de alguns fundamentos.

A partir desta semana estou disponível para workshops/sessões de pareamento presenciais focados nessas técnicas.

O que é?

Não é um curso. Não darei uma aula ou palestra. A ideia é que eu sente com os integrantes da equipe e, trabalhando em projetos reais do time, ensine e pratique as técnicas que aplico em meu código e sobre as quais falo em diversos eventos no Brasil.

O foco é em aplicações desenvolvidas com Ruby sob o paradigma de orientação a objetos. Aplicação de BDD e princípios como SOLID e “Tell, don’t ask” serão os principais objetivos.

Apenas para deixar claro, não tenho nada contra cursos. Apenas quero tentar uma nova abordagem que, enquanto mais “perigosa” para mim (o risco de dar de cara com situações que não conheço é alto), proporciona mais aprendizado para ambos os lados. Acredito que o time que me contratar se beneficiará muito da possibilidade de aprender enquanto desenvolve dentro de um contexto real, que enfrenta diariamente.

Horários

Não estou deixando meu trabalho atual. Por isso, meus horários disponíveis são de Segunda à Sexta das 19h às 22h e durante os Sábados. Isso limita os lugares aos quais posso ir, mas é o factível no momento.

Preços

Os preços serão de acordo com duração, tamanho das equipes e porte da empresa. Entre em contato comigo através do e-mail lucashungaro@gmail.com e vamos conversar. Tenho certeza que o custo ficará bem inferior ao de contratar uma consultoria de desenvolvimento e o benefício será bem maior.

Contato: lucashungaro@gmail.com


Capistrano and whenever: updating the crontab of the runner user

When deploying Rails applications with Capistrano it’s a common practice to use two separated users: a deployer (the user who actually does the deploy process, copying files and all that) and a runner (the user that runs the application on the server).

If you need cronjobs you probably use the whenever gem. It’s an awesome tool to configure your scheduled jobs with a nice and easy DSL. It also has built-in integration with Capistrano, but there’s a caveat: it will update the crontab of the deployer, not the runner‘s one.

To solve that issue, I’ve dropped the “automatic” integration (just a simple require “whenever/capistrano”) and used a hook to invoke whenever passing a user option to specify which user’s crontab to update. Here’s the relevant code:

after "deploy:update_code" do
  run "cd #{release_path} && #{try_sudo} GEM_HOME=/opt/local/ruby/gems RAILS_ENV=production bundle exec whenever --clear-crontab #{application} --user #{runner}"
  run "cd #{release_path} && #{try_sudo} GEM_HOME=/opt/local/ruby/gems RAILS_ENV=production bundle exec whenever --update-crontab #{application} --user #{runner}"
end

The code above sets some env vars for sanity sake and runs whenever specifying the runner user as the crontab owner.

There’s another small tweak you’ll need. On your schedule.rb file, add the following code on the very first line:

env "PATH", ENV["PATH"]
every 10.minutes do
  # ...
end

This will avoid nasty path-related errors (the cronjobs won’t find the gem’s bins and all that). And… that’s it! Have fun! :)


Compilando uma versão local do Rails Guides

Para compilar uma versão local do Rails Guides, você pode fazer o seguinte processo:

1) Descubra qual o seu “gem path”, o local onde suas gems estão instaladas. No meu caso, o Rails está instalado diretamente no sistema e não utilizo rvm ou rbenv. Para encontrar essa informação, utilizei o comando “gem env” diretamente no terminal. Meu path é “/usr/local/lib/ruby/gems/1.9.1/gems/”.

2) Acesse o diretório da gem railties. Essa gem é como um “rails-core”, sendo o núcleo e o “hub” em que todas as outras gems que compõe o framework (e também extensões de terceiros) se registram para serem carregadas:

lucashungaro@IronMan:/usr/local/lib/ruby/gems/1.9.1/gems
$ cd railties-3.2.2/guides
 
lucashungaro@IronMan:/usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.2/guides (master)
$ gem install RedCloth
 
lucashungaro@IronMan:/usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.2/guides (master)
$ ruby rails_guides.rb
 
lucashungaro@IronMan:/usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.2/guides (master)
$ mv output ~/projects/documentation/rails_guides_3.2.2

Isso irá compilar os guias no diretório local “output”, o qual movemos para uma localização mais familiar. Não encontrei uma forma de mudar o diretório com argumentos na linha de comando. Você pode fazer isso se chamar o gerador via código, no entanto. O script aceita outras opções via linha de comando, como a opção de gerar guias para o Edge Rails ou versão Kindle, entre outras.

3) Ao término do processo, teremos os guias compilados em HTML no diretório indicado. Para acessá-los você pode criar um bookmark em seu browser ou utilizar um SSB. Prefiro a segunda maneira e, para isso, utilizo o Fluid (para encontrar alguns ótimos ícones visite esse grupo no Flickr. Basta criar uma nova aplicação e apontar para o diretório em que geramos os guias, iniciando pelo arquivo index.html.

Rails Guides com Fluid


Modularity on Rails

Following my last article I’d like to elaborate on my opinions.

First, let’s review some things:

  • Yes, I know you can deactivate a lot of the bundled stuff in Rails; that doesn’t solve any of the issues.
  • Yes, I’m aware of Railties; It’s nice, well built, a good step forward; still doesn’t solve any of the isses.
  • Most of the people who reacted badly to my article (and @merbist‘s one) pointed out that, to use and understand Rails’ “modularity” you’re supposed to buy a book; I don’t think it should be necessary (nothing against the book, it’s very good)
  • The issues I pointed out converge to one thing: modularity isn’t configurability. Yeah, I can edit my default generated Rails app and remove all sorts of things, including using some hackish code to remove middlewares from its stack. This isn’t modularity on the application-level.

    I know that Rails’s internals are more modular on Rails 3 than they’ve ever been. I’ve saw Jose Valim’s talk about how they’ve applied SOLID principles to achieve that, it’s really nice (read the slides if you can, it pays off). I’m not talking about that. I’d like to emphasize that I’m talking about modularity at the application level, not at internal code level.

    Here’s an example (hypothetical context, of course):

    $ rails new my_app # generates a lean app (not a Sinatra-style app, a Rails app without the unneeded stuff)
     
    ... # days after
     
    # Hmmm, I need to send e-mails!
    $ cd my_app
    $ rails add actionmailer # adds and installs actionmailer, generates the boilerplate needed
     
    # Hmmm, I need to speed up my assets load time!
    $ rails add rails-assets-pipeline

    Modular. Apps. Things I can incrementally build upon. Now, mailer should probably be there by default, but you get the idea.

    These gems would be separated from Rails core. I really don’t care if a “full” Rails app ends up installing 100 gems as long as I’m in control of that and can start with way less.

    What’s the advantages?

    • Easier to learn: beginners will have a better experience since they can learn the framework gradually;
    • Still powerful: that doesn’t force you to dumb it down, as many suggest. Modular apps suit the needs of novices and experienced developers as well;
    • Goodbye clutter and unneeded code: the framework will only load the code I need. Boot time will be decreased as well as memory consumption. Yes, I know that if you deactivate something today, most of the code won’t be loaded, which gets us to…
    • Less code to understand: it will be easier to contribute to the framework as it will have way less code and I can gradually dig in. I can contribute with the core without stumbling into the assets pipeline, for example.

    Well, I could elaborate more on that, but it’s the main idea. Rails’ internals are way better, yes, and that’s awesome. But the framework still lags behind on many things I think should receive priority instead of adding built-in support for SASS, CoffeeScript and things like that. I’m currently taking a look at Rails’ codebase to see how I can fit these ideas in. I hope to have some pull requests ready soon. If you’re interested in helping, please contact me.


Rails has entered the framework death spiral

I usually write here in Brazilian Portuguese but this post is written in English in the hope of getting some useful attention and discussion going on (yes, wishful thinking).

Before we start this, let’s make some things clear. When I criticize Rails there’s two common reactions:

The Lovers:

  • “OMG, DHH and the Core Team are awesome, they know what’s better for you, stop crying!”
  • “Well, stop using Rails and create something better!”
  • “You should not criticize the tool that pays your bills!”

The Haters:

  • “Yes! Yes! Let’s burn these motherfuckers!”

Let me be totally clear here: Rails is very useful and I like it a lot (although I used to like it way more). Otherwise I would just dismiss it and don’t even bother trying to get some attention to the issues I’ll describe. I respect the work and effort of so many people that keep the framework going fixing bugs and adding features. You should too, it’s not a walk in the park and very few people actually get some time to do this kind of work. A special mention goes to Aaron Patterson (@tenderlove), a guy who relentlessly keeps cleaning up the mess that Rails’ codebase has become while still keeping his humility (sadly, a rare trait in our community).

Some days ago, when talking with a friend, he said “Rails has entered the framework death spiral – it’s now adding features for feature-sake”. I agree. The “Rails is opinionated software” idea is clearly lost as it’s trying to embrace everything and has turned into a playground for some people (not the entire team, to be clear) instead of a framework that shapes the way web applications are created (that paradigm is shifting and meanwhile Rails is messing around with CoffeeScript and SASS).

One example of this “playground theory”? Releasing a piece of crap like the assets pipeline, clearly rushed and so fucked up that it makes me think if it’s the worse thing I ever had to use to build software, occupying a honorable spot besides the Struts framework, ASP and JavaServer Faces.

The main problem, in my humble opinion, is: Rails has turned into bloatware. I see the problem from two angles: as a potential contributor and as a user of the framework.

As a contributor

Rails has so many things included by default now that the code is really big. I tried to understand it some time ago and got quickly frustrated by the massive amount of coupled code and features that distract you from the main workflow of the framework. Yes, I could probably just get some ticket and solve a bug, but I like to understand the whole before going around throwing code like crazy to get some commits in. OSS activists will probably bash me for this, calling me lazy, but it’s the way I work, sorry.

The solution? Well, my suggestion is this: the rails gem should contain only the core, the request processing cycle and hooks for the other parts to hang in (ORMs, template engines, other gems in general). It already has this in some form, a framework called Railties, but all the things that hook into it are still in the same codebase, divided in a few other gems.

The asset pipeline is a main offender here and the easiest example to bring to the surface. This thing should *really* be into its own gem and out of Rails. It could be included in Rails’ default Gemfile, I don’t care, but please do not throw more code into the mess. I won’t even start the discussion about the quality of the pipeline per se, but I digress. If you want the default approach, the one the Core Team chose, just generate a full app and install de default gems. Otherwise we could have a lean application generator that remove all the uneeded dependencies without hacks. Better yet if that one could be the default.

If my memory isn’t failing me, I believe Merb did things this way. Besides lessening the burden on contributors it should force people to write decoupled code, something the Rails Core Team has been improving on for some time now, by the way.

Yes, I know Rails included extra things like ActionMailer and ActiveRecord from the beginning and they’re independent gems. As I said before, I’m fine with default choices, but I also think that Rails’ starting point should be a lean and simple mini-stack that could be easily incremented as the user needs it to be.

As a user

People who are experienced with Rails tend to forget that beginners do exist. Most of the so called “Railers” I know see themselves as a kind of superior being surfing the waves of awesomeness, forgetting that legacy must be supported and new people will try Rails. Funny thing is that the developers that use Rails as a mere tool (what it is) see this issue clearly, while people that see it as a religious cult dismiss it.

The first issue is legacy. Rails completely ignore this (as is common with frameworks in so called “non-enterprise” ecosystems) and makes no effort to support people that work with legacy code. The community itself fails hard at this, as we don’t even talk about that as we should. Think about how rare it is to see a talk about legacy applications on conferences in contrast to the plethora of talks about new features/libraries or how you should be writing your code. We fail hard here.

The second issue is that, as of today, Rails is incredibly hard for beginners to learn and use effectively. It’s slow, has a freaking unbelievable amount of dependencies right of the bat (this can be normal down the road, not by default), it’s cumbersome to set up (don’t you love some gem version hell?), it’s not quick to get up and running anymore. I usually joke that the “15 minutes blog” today should be called “the 1 hour and 30 minutes blog”. That’s not to mention the big disparity between the official literature and documentation (“the DHH way”) and the way real Rails apps are developed.

EDIT: to be fair, I installed the latest Rails and generated a new app. No version hell this time, hurray! The last three times I did it, it was a nightmare. Things are still slow though. You can generage your application with “rails new my_app –skip-sprockets –skip-test-unit” to drop the generation time from ~2 minutes to about ~30 seconds. Other flags like –skip-active-record and –skip-javascript are available to bypass some default dependencies.

It’s hard for people who already knows Rails to imagine how it is to begin with the framework today. I’ve seen beginners trying it and it was ugly. Think about how many unrelated things someone has to go through to understand a simple “Hello World” in a default Rails application today.

What got me interested in Rails was the “batteries included” approach, yes. But there was a thin line and, to me, that line has been crossed. Rails went past the line of “including everything you need for a quick start” to “including everything the Core Team thinks you need to build a gigantic web application following every techniques they find appropriate”. Yes, I know it’s best practice to minify my JavaScript but I’m a grow up, let me do it the way I want without clogging up the framework with a lot of useless code (yes, I can deactivate it, but it’s still useless since I won’t use it and it will slow my boot time and bloat the framework code, hence the idea of splitting Rails into more gems and do not install them by default nor include them in the same codebase).

Conclusion

The Rails framework should really get trimmed down. Non-fundamental trinket should be separated and, maybe, we could have two application generators: a “lean” (maybe just ActionPack and Railties, something like that) one and a “full” one. That way it would be a lot easier to grasp the framework code and contribute while allowing newcomers to taste the goodies gradually, learning instead of being drowned into a lot of concerns that really doesn’t relate to the core of developing a well built application.

EDIT: Yes, the title of the article is harsh and I recognize it does not reflect what I wanted to suggest here. It was wrong and tabloid style. It was chosen out of frustration, which shouldn’t be a reason to do it. The intention of the article is to spark a good discussion, not to be alarmist and accusatory, which the title makes it sound like.


← Anterior