Recently, I found reading an article by Paul Venezia titled, Fatal abstraction: A bottom-up view of high-level languages, where—if you read between the lines—you can see that Paul just found himself waking up from a coma and it’s no longer 2004.
“I may have questioned Perl’s future now and then, and Perl certainly doesn’t have the presence it once enjoyed, but the strength of Perl has always been its flexibility. You can do pretty much anything with Perl, and you can do it in a wide variety of ways. Perl’s core revolves around the idea that there’s always more than one way to do it. In fact, there may be dozens of ways to do it. PHP shares a similar trait in that it gives you a large set of tools and leaves the construction up to you.
Ruby, and especially Rails, is the opposite, and Python definitely leans more in that direction. Essentially, it’s the difference between building a chair from raw lumber and assembling one from IKEA. This isn’t to say there’s anything wrong with assembling from parts, and clearly Ruby and Python are very capable and strong languages. However, they’re not my cup of tea.”
Admittedly, perhaps I’ve been in drinking the “kool-aid” for far too long, but I thought this tired argument has run it’s course.
I take huge offense to comparing Ruby on Rails to IKEA furniture. It’s far easier to build a web application with Ruby on Rails than it is to build an IKEA bookshelf
“When it comes right down to it, I need to know exactly what my code is doing. I’m going to keep an open mind and spend more time on the other side of the fence in the short term. Perhaps I’ll be won over, but it won’t be easy. Trust issues are complicated.”
Paul, I completely understand where you’re coming from. It sounds like you’re dealing with similar trust issues that I had nearly a decade ago. Trust me, it will be okay.
Ruby on Rails isn’t magic. Behind the curtain you’ll find a collection of object-oriented code written in one of the most readable languages in existence.
We’ve had a number of clients in New York over the years. After a recent trip this last fall to visit clients and attend Cultivate we decided that we should spend more of our time in the city.
In 2014, we’re looking to expand our client base there. If you’re in the NYC area and are looking for an agency that has great Ruby on Rails developers… get in touch.
Earlier today, I noticed that we now have over 500 developers from around the globe who I have accepted pull-requests from1. That is so fantastic.
Thanks to each and every one of you who has helped make this project so wonderful for others. :-)
1 This number could be a lot higher if I spent more than a hour or two a week on this, but I’m a big fan of slow and steady… a good number of the open pull-requests are themes at the moment.
Recently, I found myself re-installing everything from Homebrew and began to notice that MySQL was consuming nearly half a gig of memory. Given that I don’t do too much with MySQL on a regular basis, I opted to override a handful of default configuration options to reduce the memory footprint.
As you can see, a fresh MySQL install via homebrew was consuming over 400mb of memory.
Here is how I reduced my memory footprint:
$ mkdir -p /usr/local/etc
Unless you already have a custom MySQL config file, you will want to add one into this directory.
$ vim /usr/local/etc/my.cnf
We’ll then paste in the following options into our file… and save it.
# Robby's MySQL overrides [mysqld] max_connections = 10 key_buffer_size = 16K max_allowed_packet = 1M table_open_cache = 4 sort_buffer_size = 64K read_buffer_size = 256K read_rnd_buffer_size = 256K net_buffer_length = 2K thread_stack = 128K
Finally, we’ll restart MySQL.
$ mysql.server stop
If you have MySQL setup in
launchctl, it should restart automatically. After I did this, my MySQL instance was now closer to 80mb.
So far, this has worked out quite well for my local Ruby on Rails development. Mileage may vary…
Having said that, how much memory are you now saving?
For more information on how we use it, read my older post, Tracking Google Analytics events in development environment with GoogleAnalyticsProxy.
While reviewing some code recently, I came across controller code that resembled the following.
if @customer.save CustomerMailer.deliver_welcome_message(@customer) flash[:message] = "Your account has been successfully created. We've sent you a welcome letter with..." redirect_to dashboard_path else ... end
Fairly typical Rails code. Nothing alarming here, but I wanted to evaluate the call to the mailer in this scenario. When it comes to sending emails from your application, you can choose to do it from the controller as in the example above or in your models. Our team prefers to do this from our model via a callback as we are considering this to be part of our business logic.
Each time a customer is created, we want to send them an email. This can be moved into the model and resembled something like the following..
after_create :send_welcome_message #, other callbacks.. def send_welcome_message CustomerMailer.deliver_welcome_message(self) end
There are a few benefits to doing it this way.
- We can test that this is being triggered within our model specs instead of our controller specs. (we prefer to spend more of our time working within models than controllers)
- We remove the dependency that all requests must be processed through our controllers.
- Example: We may one day create rake tasks that data and want these emails to still be sent out. (We’ve had to do this a few times)
I definitely don’t think doing this via controllers is a bad idea, I just lean towards keeping controllers as dumbed down as possible. This allows us to have less controller code that is focused on passing data to/from models and letting our models do the heavy lifting.
UPDATE: DHH was kind enough to post a more detailed response on his blog.