git cheat shee
For those who don't know Git is a version control system developed by Linus Torvalds. It's main difference from other tools like SVN and CVS is the fact that it's distributed.
Recently I gave a workshop about Git here at the company where I walked through the most common cases I usually see when working in a team and thought about posting a summary of the commands used in the workshop.
It turns out that just this morning I found this - a.k.a the rest of my post. It's a really nice and concise Git Cheat Sheet that covers most of what I talked about in the workshop. So I highly recommend you bookmark it. It will certainly be useful.
jruby on rails and google app engine
As many of you know the new language supported at GAE now is Java, as officially announced on their blog. As a Ruby/Rails developer you might not be interested on it but here is a reason you should be: JRuby.
It was only a matter of time until we saw some people deploying JRuby on Rails apps on GAE, like Ola Bini's mini blog app. Guess that was the first one really, as he was beta testing the service in secret. Google App Engine imposes a few catches to any java application deployed there and any JRuby app wouldn't be different. For instance, your Java API access is limited to these classes - called JRE Class whitelist.
As you can see on his blog, you don't need active record and in fact shouldn't even be loading that on your app.
I felt compelled to try it and the timing was perfect. I am currently developing a JRuby on Rails app at the company I work for and it was a perfect fit, since we are not using ActiveRecord. The reason is that we get the data we need from other sources, such as web services and even text files.
Ola Bini's tips were crucial here. He provides a small script you can use to prepare the jars you're sending to your app. Another important piece was the Google App Engine SDK for Java. It ships with a server that emulates GAE's behaviour locally so you're less likely to have problems once you deploy it.
I did have a problem though with the number of files uploaded to my appspot. It's currently limited to 1000 - a thousand - and a Rails app can easily exceed this limit. So before deploying, remove anything that is not crucial: activerecord - you should've done it already - , all tests directories - including the ones inside gems your app needs in order to work, fixtures and etc.
After that it was rewarding seeing a custom JRuby On Rails application working perfectly on GAE. And as much as I'd like to, I can't really share the URL since it's a private app but I encourage people to try it. I believe GAE will ultimately help the community improve JRuby even more.
And as a last tip, this time thanks to Fabio Akita, is this snippet. You should redirect your log so you can debug your app form GAE's dashboard.
Have fun!
long stand up meetings
It's been more than a year since I started my new endeavor here in Spain, moving from Brazil and starting a whole new life - both personal and professional. Time for a little retrospective.
More precisely, a retrospective about the agile practices here at the company.
When I first started out back in January '08 the company thought they were agile. NOT! They did adopt some XP practices but just to give you an idea, I'm gonna focus on just one: stand-up meetings.
My first stand-up meeting was a shock! We were a team of 6 developers and 2 sys admins and the meeting lasted for 40 -yes, forty - minutes!
The reason? Several, but the most obvious one was that in their stand up meeting they were actually, well, sit. That was my first suggestion which some people were actually reluctant about. But we survived.
Since then we improved a lot our stand-up meetings being able to usually cut it down to 10 minutes. But we can get better.
Another problem we usually have is the "i-want-my-finger-in-everything" syndrome. I guess you're all familiar with that. It's the developer who wants to know everything in its minimum detail and interrupts everyone in the stand-up meeting to ask questions or make clarifications that could, both, be done afterwards. And that's a problem we still have every now and then.
But we are much better now and to get here we basically successfully tried:
- Standing up ( duh?! - believe me, this was harder than you might think)
- Trying to bind people's thoughts on what they've done the day before and what they are going to do that day. Anything else should be left for after the meeting - it's probably not everyone else's concern. Focus.
- Limiting the amount of time allowed for each developer - currently we have a generous 2 minute limit.
- Using a token -any object light enough to be hold while you're talking. People are only allowed to talk when they get hold of it. This was a nice idea brought by my colleague Philip MacIver.
But we still have issues. People still jump in somebody else's turn and get the token basically as if just by getting it they can talk. And because of that we still suffer from the "i-want-my-finger-in-everything" syndrome.
So after telling this little story about how stand-up meetings evolved here, I'd like to hear from you guys what do you do to keep your meetings short and to the point. I'm really willing to hear suggestions and success stories.
final classes are evil
Update: Go ahead and read this post in its entirety - including the comments. Then, read my other post where I expand the subject a little more.
--
Every now and then I still do some Java coding. And I actually like it. I spent several years of my career developing primarily in Java and am very keen about the language.
I've been a fierce defender of it these days, specially with the wave of popularity of other languages such as Ruby and Groovy. But I must say that for the 1st time - actually the 2nd - I got pissed off at Java.
The reason? Final classes!
How arrogant of someone to say: "And from now on you shall not subclass my classes!"
Er.... Why?!?! I'm yet to find a good reason in favor of it. But I can share 2 that made me be completely against it. - I never actually liked it but it just didn't bother me that much in the past.
The first one happened while I was adding PostgreSQL XML support to Hibernate. The basic idea is that the XML data type should behave mostly as a string, with the exception of the saving and loading operations.
The thing is, the String data type in Hibernate is declared final. So you cannot share behavior unless you copy and paste it. How smart.
And the second is in the testing area. We all love testing. And we all love mocking external dependencies so we can test our code in isolation and fast. Well, I hope your code doesn't depend on the URL class then.
It is declared final so you just can't mock it. Mocking frameworks like easyMock use subclassing to create your dependencies mock objects and obviously it doesn't work here.
Yeah yeah, of course you can refactor your code so it depends on an interface/class that wraps your URL class and then you can switch implementations. But just how stupid is that? Programming to interfaces makes sense, but not everywhere. Specially not when you're using a low level class like this one.
So please, software developers, architects and the like, design your systems for extensibility and stop being presumptuous.
P.S.: There is a testing framework called jMockit which uses instrumentation (Java 5+) to redefine methods in runtime so you can mock final classes. It works, but should we really be playing that much with the java class loader just so we can "easily" test our code?
qcon london 09
Tomorrow I'll be once more heading London for this year's QCon.
As usual, the schedule looks amazing and I'll try to keep you all posted about what's going on there.
Oh and if any of you guys is going and wanna meet up for a geek talk and a couple of beers, just send me a message.
Cheers! :)
eclipse tip debugging non wtp projects
This is a very useful tip I shared a while ago at the office and turned out to be extremely useful.
If you work with java and use eclipse as an IDE you know that eclipse has something called WTP, which stands for Web Tools Platform. It's a set of tools and API's to aid in the development of web and JEE projects.
That means that if you have a WTP project in your workspace, you can deploy, run and debug it straight from the IDE. But what happens if your project is not of a WTP nature?
Back at the office we have a coupe of really old Java project. WTP didn't exist back then but we do use Eclipse as our IDE of choice.
So, how do we debug a deployed project that we don't actually deploy from the IDE? As long as you have the source, it is quite simple:
somewhere in between
So here I am! Alive and kicking!!!
Just got back from vacation. Brazil was awesome and so was xmas in Norway! Lots of food in both places! Need a diet! :p Warming up for new year's now.
But the reason for this post is the last comment on my Rails 2.0 scaffold post, quoted here:
Hi Leonardo,
I am extremely grateful for your info altruism. I thought maybe I could show my gratitude with a small donation but I don’t see anywhere on your site to do so.
You’ve saved me hours and possibly what little sanity that I claim to have left. Is there a place to do so on your site that I’m missing? If not just tell me where and I’ll send my gesture to any cause that you wish. Thanks very much again, some day I hope to be able to be of service to a needy newbie as you have been to me. Happy New Years!!
I was surprised that someone wanted to make a donation and, since I never thought about it, I wasn't prepared.
I was talking with the author of the comment, Eric Goodman, and I suggested he could donate to a noble cause. He ageed and just sent me the confirmation that a donation was made to The American Cancer Society.
So here I leave my thank you to Eric and encourage other people that read my blog to do the same in case they feel compelled to contribute in some way. Other societies around the world are gonna be very grateful.
Happy new years!
apologizing in advance p
UPDATE: By next friday I meant this friday, december 5th. Tks Pillip! :P
This will be a really quiet month on my blog.
The reason? Next friday I'm going to Brazil for vacation and right after, in the end of december, I'm going to extend my trip a bit and spend xmas in Norway.
Just hope to come back alive from Brazil! My friends are promising a real blast!!!!! :D
C u all soon!
rails performance scripts profiler benchmarker
There are several ways you can measure your rails application's performance. The techniques range from filling your code with "puts" statements - :p - to fancy ones like NewRelic - which is quite nice, I must say.
But what many people don't know is that rails ships with a handful of scripts to help you out. One of which is called profiler, located under your application's scripts/performance directory.
By default it uses the standard ruby profiler but if you want more speed - and additional reporting options - , consider installing the ruby-prof gem.
So if you execute it without params, you'll get a clue of how it works:
$ script/performance/profiler
Usage: ./script/performance/profiler 'Person.expensive_method(10)' [times] [flat|graph|graph_html]
Pretty self explanatory, right?
As a sample code, I have in my rails app a dumb model with a really dumb method I wanna profile:
class Article
def self.find_all_with_delay
sleep 10
self.find(:all)
end
end
Clearly this method doesn't perform well and is a bottle neck in our super application! But let's see what rails' profiler tells us:
$ script/performance/profiler 'Article.find_all_with_delay' 1 graph > text_graph.perf
Loading Rails...
Using the ruby-prof extension.
Thread ID: 109440
Total Time: 10.147995
%total %self total self wait child calls Name
--------------------------------------------------------------------------------
100.00% 0.00% 10.15 0.00 0.00 10.15 1 Global#[No method] (/Users/leo/projects/test/vendor/rails/railties/lib/commands/performance/profiler.rb:24} /Users/leo/projects/test/vendor/rails/railties/lib/commands/performance/profiler.rb:24
10.15 0.00 0.00 10.15 1/1 Object#profile_me
--------------------------------------------------------------------------------
10.15 0.00 0.00 10.15 1/1 Global#[No method]
100.00% 0.00% 10.15 0.00 0.00 10.15 1 Object#profile_me ((eval):1} (eval):1
0.00 0.00 0.00 0.00 1/1 Class#const_missing
10.15 0.00 0.00 10.15 1/1
merb turns 10 and started driving me crazy
As you may already know, Merb turned 1.0 a while ago and I decided to resume my studies to learn the framework.
So I just built a new app with a few resources and fired the migration scripts:
$ rake db:automigrate
And this is what I got:
Loading init file from /Users/leo/projects/merb/my-first-app/config/init.rb
Loading /Users/leo/projects/merb/my-first-app/config/environments/development.rb
~ Connecting to database...
/opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/data_objects_adapter.rb:137:in `initialize': wrong number of arguments (8 for 1) (ArgumentError)
from /opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/data_objects_adapter.rb:137:in `new'
from /opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/data_objects_adapter.rb:137:in `normalize_uri'
from /opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/abstract_adapter.rb:44:in `initialize'
from /opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/data_objects_adapter.rb:159:in `initialize'
from /opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core.rb:157:in `new'
from /opt/local/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core.rb:157:in `setup'
from /opt/local/lib/ruby/gems/1.8/gems/merb_datamapper-1.0/lib/merb/orms/data_mapper/connection.rb:44:in `setup_connections'
from /opt/local/lib/ruby/gems/1.8/gems/merb_datamapper-1.0/lib/merb/orms/data_mapper/connection.rb:27:in `connect'
from /opt/local/lib/ruby/gems/1.8/gems/merb_datamapper-1.0/lib/merb_datamapper.rb:17:in `run'
from /opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0/lib/merb-core/bootloader.rb:99:in `run'
from /opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0/lib/merb-core/server.rb:172:in `bootup'
from /opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0/lib/merb-core/server.rb:42:in `start'
from /opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0/lib/merb-core.rb:169:in `start'
from /opt/local/lib/ruby/gems/1.8/gems/merb-core-1.0/bin/merb:11
from /opt/local/bin/merb:19:in `load'
from /opt/local/bin/merb:19
Lovely, isn't it?
After a fair amount of googling around it turns out that there seems to be a problem with the URI parser Merb uses underneath, called Addressable.
As of the installation of Merb 1.0, the installed version of this library was 2.0.0.
The solution? Install a older Addressable version:
$ sudo gem uninstall addressable
You have requested to uninstall the gem:
addressable-2.0.0
dm-core-0.9.6 depends on [addressable (>= 1.0.4)]
data_objects-0.9.6 depends on [addressable (>= 1.0.3)]
If you remove this gems, one or more dependencies will not be met.
Continue with Uninstall? [Yn] Y
Successfully uninstalled addressable-2.0.0
$ sudo gem install addressable -v 1.0.4
Successfully installed addressable-1.0.4
1 gem installed
Installing ri documentation for addressable-1.0.4...
Installing RDoc documentation for addressable-1.0.4...
I haven't figured out the reason for this issue, so please do share if you know. I'll be glad to update the post. :)