Tag: Creativity
Be Bored
Recently I wrote an internal blog post at work titled On the traps of working from home.
While the content isn’t new it was triggered by the recent events around COVID-19 and the fact that all of a sudden the whole company was working from home, distributed across multiple timezones.
I was worried that we may default to having more meetings instead of better communication and writing this post was my attempt to share how I tend to deal with distractions.
Tag: Deepwork
Be Bored
Recently I wrote an internal blog post at work titled On the traps of working from home.
While the content isn’t new it was triggered by the recent events around COVID-19 and the fact that all of a sudden the whole company was working from home, distributed across multiple timezones.
I was worried that we may default to having more meetings instead of better communication and writing this post was my attempt to share how I tend to deal with distractions.
Tag: Productivity
Be Bored
Recently I wrote an internal blog post at work titled On the traps of working from home.
While the content isn’t new it was triggered by the recent events around COVID-19 and the fact that all of a sudden the whole company was working from home, distributed across multiple timezones.
I was worried that we may default to having more meetings instead of better communication and writing this post was my attempt to share how I tend to deal with distractions.
how do you keep yourself focused
This is basically a compilation of a few tools/habits that I use to keep focused and at a high level of productivity when working alone. Works great for me and I hope there are useful tips for you as well.
- Music
- This is one of my favorites. When working alone I hate having noisy people around, which happens quite often if you work in an open office space like me. - It is great for pair programming but I find it inefficient otherwise. Thus, I came up with the term the Heavy Metal effect. Ok, just fit your favorite music genre there but the important thing is that it must act as a barrier to the outside world. It won't work if you put something new and start babbling the lyrics!
- Password Manager
- In my day to day I have a number of web sites open like API documents, programming related groups, email... There are also the ones you open a few times a day like the company bug tracker, review board and etc. I find that having a password manager, in my case LastPass, saves a lot of time. The big advantage of it over similar tools like 1Password is that it works on mac, linux or windows. It's just a firefox plugin.
- Multiple Workspaces
- Probably the most obvious item on this list to developers but I's never too much to reinforce it. Multiple workspaces are great. And they are available in whatever platform you happen to be locked in. In my case, I split my environment in at least 3 workspaces:
-Development - where I keep things like my IDE, Browser and Terminal
-Documentation - where I keep API documents, tutorials and related stuff
-Communication - where I have my email, both personal and business, twitter and etc. This allows me to easily set a time per day to do each of my stuff without having noise from things that aren't important to what I'm focusing in that very moment. - App Launcher
- A must! On Mac I use QuickSilver and on Linux, Gnome Do. I won't say much here. If you don't use some sort of application launcher, do yourself a favor, stop reading and install one. You have no idea of how comfortable and time saver they are.
- Batch tasks
- Maybe this wasn't the best title but I couldn't think of anything better.
As a result of having a communication workspace that I use a few times a day, I find stuff that I'm interested in but don't have the time to dig at the moment. So I need a way to queue that and read later when I'm home. The tools of the trade in this case are Twitter + Evernote.
Evernote is roughly a to-do manager. And since they released their Twitter integration it's been dead easy to queue those things I talked about earlier. Just send a direct message to evernote and the item gets added instantly.
Tag: Ai
Classifier Evaluation
I recently wrote an article on our company blog where I explained how we evaluate Machine Learning models at RecordPoint – if you haven’t read it yet, I’d recommend you do so before proceeding.
Since its publishing, I received a number of comments asking me to clarify the concepts presented with concrete examples.
The original article is light on code by design as the audience for the company blog isn’t always that technical. Therefore, in this post I’ll provide a simple example that will hopefully clear things up – in particular why accuracy isn’t enough.
Tag: Machine-Learning
Classifier Evaluation
I recently wrote an article on our company blog where I explained how we evaluate Machine Learning models at RecordPoint – if you haven’t read it yet, I’d recommend you do so before proceeding.
Since its publishing, I received a number of comments asking me to clarify the concepts presented with concrete examples.
The original article is light on code by design as the audience for the company blog isn’t always that technical. Therefore, in this post I’ll provide a simple example that will hopefully clear things up – in particular why accuracy isn’t enough.
Tag: Ml
Classifier Evaluation
I recently wrote an article on our company blog where I explained how we evaluate Machine Learning models at RecordPoint – if you haven’t read it yet, I’d recommend you do so before proceeding.
Since its publishing, I received a number of comments asking me to clarify the concepts presented with concrete examples.
The original article is light on code by design as the audience for the company blog isn’t always that technical. Therefore, in this post I’ll provide a simple example that will hopefully clear things up – in particular why accuracy isn’t enough.
Tag: Blockchain
Highlights of the Symposium on Blockchain and Distributed Ledger Technology - Day 1
Early last week I had the chance to attend the Symposium on Blockchain and Distributed Ledger Technology organised by UNSW. I wasn’t aware that UNSW was so heavily involved in the community until this event and have since learned about their interest group which has been going on for a while.
The talks had a healthy mix of research and industry case studies with subjects ranging from the technical challenges of current blockchain implementations to the legal implications of distributed ledger technology.
Highlights of the Symposium on Blockchain and Distributed Ledger Technology - Day 2
If you haven’t yet, make sure you read my summary of Day 1 first.
Morning Panel
Day 2 started with a morning panel with:
- Paul Fox from Blockchain.capital
- Leon Gerard Vandenberg from RightsFusion Pty Ltd & Solara
- Oliver Harvey from ASIC
- Ross Buckley from UNSW Law
The panelists took turns in giving their views around blockchain, investments and regulation, leading into a Q&A at the end. I was running late to this session and believe I may have missed Ross’ individual slot.
Tag: Conferences
Highlights of the Symposium on Blockchain and Distributed Ledger Technology - Day 1
Early last week I had the chance to attend the Symposium on Blockchain and Distributed Ledger Technology organised by UNSW. I wasn’t aware that UNSW was so heavily involved in the community until this event and have since learned about their interest group which has been going on for a while.
The talks had a healthy mix of research and industry case studies with subjects ranging from the technical challenges of current blockchain implementations to the legal implications of distributed ledger technology.
Highlights of the Symposium on Blockchain and Distributed Ledger Technology - Day 2
If you haven’t yet, make sure you read my summary of Day 1 first.
Morning Panel
Day 2 started with a morning panel with:
- Paul Fox from Blockchain.capital
- Leon Gerard Vandenberg from RightsFusion Pty Ltd & Solara
- Oliver Harvey from ASIC
- Ross Buckley from UNSW Law
The panelists took turns in giving their views around blockchain, investments and regulation, leading into a Q&A at the end. I was running late to this session and believe I may have missed Ross’ individual slot.
EuroClojure 2014 and announcing my book
A bit late for a EuroClojure 2014 post but I suppose “better late than never” applies here.
The best part of every conference is the networking. Meeting new and interesting people is priceless and I did plenty of that - mostly over Polish beer and food. Polish beer isn’t the greatest but if you must have it, better stick to Żywiec. It’s widely available and was the one which didn’t give me a headache :) - I’ve been told there are amazing microbreweries though I didn’t get a chance to try any while in Krákow.
Functional Programmers Unite! LambdaJam down under
I hinted at LambdaJam Australia back in my 2012 Highlights post and the dates are fast approaching so I thought appropriate to blog about it once more.
YOW! LambdaJam is a conference targeted at intermediate and advanced functional programmers and is organised in talks, jams and workshops.
- Talks are the traditional format and are 30 minutes long;
- Workshops aim to introduce a specific subjects to attendees in great detail and are up to two hours long;
- Jams are hands-on sessions. Participants will be guided through pre-defined problems around a given subject/technology and encouraged to work through the solutions either by themselves or ideally as small groups. Jams are also 2 hours long;
Sounds pretty amazing, doesn’t it?
RubyConf Brazil 2011

I was in São Paulo last week - the 3rd and 4th of November - for RubyConf Brazil. For those who don’t know, RubyConf Brazil is the evolution of Rails Summit Latin America, where I had the privilege to speak in 2009.
This year though, all bets were off. Fabio Akita and Locaweb put together a great event, with over 700 attendees and about 30 speakers split in two streams and two awesome days.
my slides from rails summit 09
{% img /assets/images/rs2009.jpg %}
Rails Summit finished a few days ago and I have only one word to describe it: Awesome!
I met some really cool people, discussed a whole bunch of technical subjects and managed not to get so nervous in my first presentation ever - I'm not counting internal presentations I've done for my team...
My slides and source files can be found here. Feel free to contact me with questions if you got any.
rails summit 2009 im speaking
I'll be speaking at this year's Rails Summit Latin America in Sao Paulo, Brazil. It will be a good opportunity to meet some amazing people and visit friends back home! :)
Overall I'll be spending 12 days in Brazil, with 2 of them dedicated to the conference. The other 10 I'll be in Rio de Janeiro visiting my family and friends. I strongly advise you to spend some time in Rio too, if at all possible. It's an amazing city and you can contact me if you have any questions.
Back to the conference, my session is called JRuby in the enterprise world: Using Rails with legacy code, and will be given in the form of a tutorial. I will walk you through some problems we had while making this kind of integration at my company, focusing mostly on dependency management.
At the end I hope you'll have a good understanding of what JRuby is capable of in a legacy environment.
If you're planning to attend and would like to hear anything specific about JRuby, please let me know, I can try and squeeze in.
C u there!
railswaycon jruby internals by ola bini
As always I expected a good talk from Ola and once more he delivered it. But this one was different. It might have been even boring to some ruby developers since we saw a fair amount of java code in this presentation. Ola gave us a tour through the main classes that make JRuby possible with a single purpose: so we can check out the code and hack ourselves. You can download his slides here.
If you've been following both JRuby and Ola Bini for the past year or so, you've noticed the trend and evolution of this alternative - and so far the most complete one - implementation of the ruby language. Specially at conferences.
Last year at QCon London, Ola was also talking about JRuby. At Euruko '08, in Prague, Charles Nutter also talked about it. RailsConf in Berlin also had its share. What all these talks had in common is that they talked about JRuby from a user/developer point of view. They were selling the solution. Convincing people to use it and presenting successful use cases.
And as the trend goes on, JRuby is now faced as a true alternative - one that we, btw, believe here at the company as we're actively using it - and it seems that now the call is for help. Help to make JRuby an even more complete and overall better ruby implementation. Charles' call for help was a great step. As he states, it's a good way to get your feet wet. I answered the call and am hacking JRuby myself, having already submitted a couple of patches. Perhaps this was the reason for which I enjoyed the talk the most. I was already familiar with some of the structure and classes in JRuby.
There were 2 more talks about JRuby: The Pleasure and Pain of Migrating to jRuby, by Steven Bristol and Integrating Enterprise Java with JRuby and Rails, Michael Johann. Unfortunately only the first one was a real case experience, where Steven walked through the problems he faced integrating JRuby with an existing java project. Interesting insights.
Michael Johann basically presented a short tutorial on how to integrate rails with EJB3 which, albeit interesting, failed to address issues faced on real life projects, like dependency management. Issues which we have already addressed in a very cool way here and I plan to share it soon. Still deciding how though...
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! :)
railsconf europe 2008 impressions and highlights
I'm back in Madrid again after the RailsConf and I think it's time to say something about it. :)
First off, the infrastructure provided by the conference was really great. The rooms, WiFi connection, food... Really well organized.
Now to the sessions, highlights:
Tutorials (Tuesday)
- Meta-programming Ruby for fun and profit (Neal Ford, Patrick Farley)
The old and good techniques that made Ruby so powerful. Here Neal and Patrick walked us through the main tricks to meta programming like open classes - and conditionally open them - , dynamically define methods, sending messages to objects and how Ruby can help test your Java code in a much easier way.
I've put the link to the slides but honestly I don't think they're too much useful without the talking.
Sessions (Wednessday)
- EC2, MapReduce and Distributed processing (Jonathan Dahl)
Jonathan explained the theory behind MapReduce using very simple ruby examples, providing the basics on how to distribute and paralelize tasks accross multiple machines.
He also introduced Hadoop, a platform built in Java that "lets one easily write and run applications that process vast amounts of data". What I liked the most was the simplicity he explained this subject. As of today, his presentation is not available online. Stay tuned as I'm gonna update this post with the links, as soon as they're available.
Sessions (Thursday)
- Debugging & Testing the Web Tier (Neal Ford)
If you've been concerned about testing your app's web tier lately, this presentation would probably not show you anything new. Neal talks about the need to debug and test javascript behaviour accross multiple browsers, using tools like Firebug, JSUnit and Selenium. If you have no idea about what these tools are, please stop now and go evaluate them!
We are pretty concerned about testing on my actual job, but selenium tests can be a pain sometimes - a.k.a extremely slow. And what ends up happening is that they are forgotten. Developers only run the test suite if it's not painful and it's lightning fast. Here's is where the highlight for this session comes: CrossCheck.
The idea is to be able to test your javascript code accross multiple browsers without the need to launch them. In fact, you don't even need a browser installed. The negative point is that it's kinda fallen behind because now you can only test older versions of browsers. But since the project is getting a lot of traction, I'm pretty sure this will be solved soon.
Conclusion
My overall impression of the other sessions I attended is that some speakers just didn't have time to properly prepare themselves, what made me think this years's RailsConf wasn't all that I expected.
But I also met interesting people and after all one of the key points in a conference is networking. :)
Definitely worth it though. And that's why I took the time to provide this highlights.
c u soon
railsconf europe 2008 heading to berlin
The title says it already.
On monday I'll be going to Berlin to attend this year´s RailsConf.
This will be my first one and of course my expectations are pretty high!
As usual, after the conference I'll try and give a summary of what happened there, providing as much content as I can.
Anyone else's going??? :)
C u there!
the biggest rails event in latin america
Behold latin american railers!
This year we will have the Rails Summit Latin America on October, 15th and 16th, in São Paulo, Brazil.
It's by far the biggest Rails event we've ever had, including many of the speakers that were present at RailsConf.
Fábio Akita is also one of the speakers and provides more details on his blog.
If you're a assumed rails geek don't miss the opportunity to hear from the big names and to know a beautiful country like Brazil.
Oh, btw, if you're brazilian, like me, you have no excuse to miss this party!
Enjoy!!!
euruko 2008 materials available
As some of you know I went to the European Ruby Conf in Prague, this year.
The event was awesome and it's good to know they finally made available the majority of the slides, here.
They also published Matz's keynote, and more videos from the conference are being edited right now, so stay tuned to their home page!
Enjoy!
qcon 2008 slides available
Most of last QCon's presentations are available for download here.
Highlights to Ola Bini's on JRuby(pdf) and Randy Shoup's on eBay's architectural principles(pdf).
And while we're talking about JRuby, it's impressive how it's becoming a recurrent and big subject. Fast. It had its own small space at big event like QCon and in the last Euruko in Prague, we had a presentation by the JRuby Core Developers Charles Nutter and Thomas Enebo.
Big companies are sponsoring JRuby's development indirectly or directly, like Sun. And other big companies are endorsing its production ready state, like Oracle, which has a publicly available website developed with JRuby On Rails.
It's past the time to give it a serious try...
euruko 2008 european rubyconf prague
On friday I'll be heading Prague for the European RubyConf.
Anyone is going? :)
Almost 300 attendees already registered for the event. And a few very interesting people will be speaking there like Matz and DHH (this one, through skype).
Besides that, the organization staff is scheduling 2 parties, friday and saturday, for the attendees.
Networking comes to mind, doesn't it? I think it will be a great opportunity to meet interesting and bright people.
So, see u in Prague!
qcon 2008 domain specific languages
Today was the first day of the conference and it started with a tutorial about DSL's with Martin Fowler, Neal Ford and Rebecca Parsons. We also had as attendants Ola Bini, core developer of JRuby, and others. My expectations were pretty high and the presentation didn't let me down. I'll try to put here toghether my impressions and some notes I took while I was there.
Marting Fowler started discussing what DSL's are and giving some examples that many of us use in our day to day Job. Like the XML configuration files in the Java world. It is a kind of DSL, it has it's own keywords and syntax in order to express some information that will be used , for instance, to configure an underlying framework.
The problem with XML is that it becomes hard to see the overall behavior behind it. It's not very fluent to understand the purpose of an XML file just by looking at it for the first time. There is too much "noise". Things that get into the way of the readability. - YAML files are an much more readable alternatives to XML.
The same happens with a standard framework api code. Let's take for instance a sample API configuration code written in Java to tackle the domain of hotel reservations. A framework like this could have the following implementation:
HotelService hotelService = new HotelService();
PersonService personService = new HotelService();
Hotel hotel = hotelService.findById(1);
Person guest = personService.findById(10) ;
Reservation reservation = new Reservation() ;
reservation.setFrom("2008-03-10") ;
reservation.setTo("2008-03-14");
reservation.setGuests(new Person[]{guest});
hotelService.book(hotel, reservation);
Of course implementations of this simple example may vary but we can see here some of the readability problems. One approach we could use for that is to develop a Fluent Interface to wrap this API. This was one of the techniques explored during the tutorial and the actual fluent interface could now look somewhat similar with this:
new Hotel(1)
.book()
.forGuests({
person.find(10)
})
.rooms(1)
.from("2008-03-10")
.to("2008-03-10");
Much more readable, huh? One of the main benefits of using DSL's they highlighted in the tutorial is the simplicity of code you can achieve. You can actually show this code to a business person and he can understand it. This is a kind of internal DSL.
But there is still a bit of noise in this code. The the parenthesis which are not always desirable, and the use of double quotes for dates. But, this is Java code, and Java doesn't give too much room for you on the DSL subject. Here was when the speakers changed their focus a bit to Ruby. It's dynamic nature and metaprogramming techniques provides a powerful flexibility that allows for a looser syntax.
So in ruby the previous interface could look like this now:
Hotel.find(1) .book(1.room).forGuests {
Person.find(10)
}.from(march.10.2008).to(march.10.2008)
We got rid of the double quotes and the code looks more fluent, like a normal english sentence. I doubt a business guy woudn't understand what this code is doing. With this, we can get closer to the business guys, with a common vocabulary, and fill the gap between us.
This is just one of the ways we could have written this code and is not the actual example used in the tutorial. The syntax also really depends on how readable you wanna make your code. I'll provide those later when they release the digital format of the presentation.
So one of the flows that the development of an internal DSL can get is to build a framework and define the DSL on top of it. But we should also keep in mind that DSL's shouldn't be general purpose programming languages. They should be created to tackle a specific kind of domain problem, so we would have a whole system made of small DSL's.
Another interesting subject that was touched is testing. How do you test DSL's?
The suggested approach, and that I think is quite reasonable, is to have separate tests for the underlying framework and another to test the DSL and its parser you can assure you have the expected behaviour of both parts.
This is really just a summary of my thoughts and of what happened there. I'm not going into too much details right now but if you found something too abstract - and it is! ;) - feel free to ask details. I'll be more than happy to help.
This is definetly an interesting subject and now I'll head to play more with all that. :)
PS; This is not the whole presentation, just the best of it from my stand point. Other subjects include External DSL's which can actually involve you coding Lexers, Parsers and Compilers. It's usually not worth the hassle. And it's too complicated anyway, that's why I left it out from this post.
qcon 2008 london
Next week I'll be at QCon, in London, so if any of you are going to the conference and would like meet up for a couple of beers and a tech talk, please don't hesitate to drop a message.
For those of you who have never heard of QCon before, it is a really nice event to play along with some of the most popular names in the software engineering community. This year's conference features people like Martin Fowler, Neal Ford, Erich Gamma and much more.
So stay tuned, the conference takes place during the whole week and I'll try and keep you posted about what's happening over there.
C u in London!
Tag: Atlassian
Mission accomplished
A year and four months ago I joined Atlassian to pursue a very exciting opportunity: to deliver realtime collaborative editing to Confluence. I have talked about it last year at EuroClojure and this year at QCon Brazil. Even Cognitect wrote a few words about it.
In a nutshell this involved writing Clojure code all day to build an awesome service we call Synchrony. Synchrony is capable of realtime data synchronisation - not just collaborative editing - and as such its applications are many! This has been proven again and again internally during the Atlassian ShipIt hackatons, and externally via Enso.me, which is powered by Synchrony.
Tag: Clojure
Mission accomplished
A year and four months ago I joined Atlassian to pursue a very exciting opportunity: to deliver realtime collaborative editing to Confluence. I have talked about it last year at EuroClojure and this year at QCon Brazil. Even Cognitect wrote a few words about it.
In a nutshell this involved writing Clojure code all day to build an awesome service we call Synchrony. Synchrony is capable of realtime data synchronisation - not just collaborative editing - and as such its applications are many! This has been proven again and again internally during the Atlassian ShipIt hackatons, and externally via Enso.me, which is powered by Synchrony.
The Clojure Sydney Meetup, four years in
In the beginning
Nearly 4 years ago I founded the Sydney Clojure User Group. I had been playing with Clojure for a little while and started a small study group to learn more. Initially this group was private and held at the ThoughtWorks office.
After a couple of meetups and conversations I decided to open up the group to the public and then realised we weren’t the only ones interested in Clojure and, even more important, interested in meeting like-minded people, share experiences and help each other.
Clojure Reactive Programming has been published
I’m extremely happy to let everyone know my book, Clojure Reactive Programming, has finally been published!
You can get it at the publisher’s website or on Amazon. I had a great time writing it and I truly hope you find it useful!
I’ve met a few authors here and there and I heard more than once that a book is never really finished. I now know what they mean.
The book doesn’t cover everything I wanted to write about due to time and space limitations. Having said that, now that the book is out I do plan to expand on a few things using this blog.
ClojureBridge Sydney, vol. I
This past weekend - 19-20th of December - a group of highly motivated individuals gave up their Friday night and their entire Saturday simply to learn how to code in Clojure!
It was the first ever ClojureBridge edition in Sydney and if you haven’t heard of it before, its goal is to increase diversity in the Clojure community. It does so by offering free workshops targeted at beginners.
You should totally read Julian Gamble’s post about the event for details. He’s was one of the volunteers on the day and has done a great job of describing his experiences.
EuroClojure 2014 and announcing my book
A bit late for a EuroClojure 2014 post but I suppose “better late than never” applies here.
The best part of every conference is the networking. Meeting new and interesting people is priceless and I did plenty of that - mostly over Polish beer and food. Polish beer isn’t the greatest but if you must have it, better stick to Żywiec. It’s widely available and was the one which didn’t give me a headache :) - I’ve been told there are amazing microbreweries though I didn’t get a chance to try any while in Krákow.
Validation and Internationalization in Clojure with bouncer & tower
I released bouncer in April last year and since then it has had a small but steady growth in usage.
So much so that I received some community feedback in the form of emails and pull requests which is simply great!
The latest and most substantial pull request, submitted by Vadim Platonov, added the ability to customise validation messages in anyway you like, as you can see in the section Internationalization and customised error messages of the README.
CUFP/ICFP 2013
I’m sitting in the Lobby of the Hilton in Boston and since my flight back to Australia isn’t for a few hours I thought I’d write my experience report while everything is still fresh in my mind.

CUFP - Commercial Users of Functional Programming - is a Workshop-like conference targeting the practically-minded functional programming community.
As it’s stated on their website, “The CUFP workshop is a place where people can see how others are using functional programming to solve real world problems […]”.
Purely functional data structures in Clojure: Red-Black Trees
This post is part of a series about Chris Okasaki’s Purely Functional Data Structures. You can see all posts in the series by visiting the functional-data-structures category in this blog.
Recently I had some free time to come back to Purely Functional Data Structures and implement a new data structure: Red-black trees.
Red-black trees
Red-black trees are a type of self-balancing binary search tree. Back when I first learned the balancing algorithm used in operations such as insert and delete, I remember it being a particularly tricky one.
Clojure, core.async and the Lisp advantage
Long gone are the days when systems needed to do only one thing at a time.
Concurrency is the word but it often leads to complex code, dealing with locks, mutexes etc…
There are several different abstractions which allows us to both model and think about asynchronous code in a more sane fashion: futures, promises and events/callbacks are but a few of them.
I won’t get into the merits - or lack thereof - of these alternatives in this post but rather focus on a different alternative: Communicating Sequential Processes - CSP.
Functional Programmers Unite! LambdaJam down under
I hinted at LambdaJam Australia back in my 2012 Highlights post and the dates are fast approaching so I thought appropriate to blog about it once more.
YOW! LambdaJam is a conference targeted at intermediate and advanced functional programmers and is organised in talks, jams and workshops.
- Talks are the traditional format and are 30 minutes long;
- Workshops aim to introduce a specific subjects to attendees in great detail and are up to two hours long;
- Jams are hands-on sessions. Participants will be guided through pre-defined problems around a given subject/technology and encouraged to work through the solutions either by themselves or ideally as small groups. Jams are also 2 hours long;
Sounds pretty amazing, doesn’t it?
clojure and why calculating is better than scheming
Last week while attending Clojure/West in Portland I came across a paper called Why calculating is better than scheming. In a nutshell, this paper is a critique to Abelson and Sussman’s classic textbook SICP - Structure and Interpretation of Computer Programs, used by MIT for many years to teach their introductory programming course.
If you haven’t read SICP, you should. It’s an amazing book. It uses Scheme, a dialect of Lisp, as the vehicle to present fundamental programming concepts.
Purely functional data structures in Clojure: Leftist Heaps
This post is part of a series about Chris Okasaki’s Purely Functional Data Structures. You can see all posts in the series by visiting the functional-data-structures category in this blog.
Last year I started reading a book called Purely Functional Data Structures. It’s a fascinating book and if you’ve ever wondered how Clojure’s persistent data structures work, it’s mandatory reading.
However, all code samples in the book are written in ML - with Haskell versions in the end of the book. This means I got stuck in Chapter 3, where the ML snippets start.
bouncer validation lib for clojure
Today I’m releasing bouncer, which was extracted from a project I’ve been working on.
It’s a validation library for Clojure apps and it lets you write code like this:
(def person {:name "Leo"})
(validate person
:name required
:age [required number])
If you’d like to see more examples and a detailed guide check out the github repository. The README should get you started.
This post however isn’t only about announcing bouncer. It’s also about the motivation and implementation details behind it.
Monads in small bites - Part IV - Monads
This is Part IV of my Monads tutorial. Make sure you read the previous parts:
-
Part IV - Monads (this post)
A quick recap
In Part I we learned about Functors, which are things that can be mapped over using a normal function - fmap
is used for that.
Part II tought us that when our Functors themselves contain functions and we want them applied to the values contained in other Functors, Applicatives come to the rescue - and bring theirs friends pure
and <*>
.
Monads in small bites - Part III - Monoids
This is Part III of my Monads tutorial. Make sure you read the previous parts:
-
Part III - Monoids (this post)
Monoids
Simply put, Monoids describe types containing a binary function and an identity value.
When applied to the identity value and a random value x
, said function leaves its argument x
untouched, returning it as a result.
Monads in small bites - Part II - Applicative Functors
This is Part II of my Monads tutorial. Make sure you read the previous parts:
-
Part II - Applicative Functors (this post)
Applicative Functors
In Part I I talked a little about Haskell type signatures and introduced Functors, which provide a way to map standard functions over values which are wrapped inside a Functor - we used fmap
for that. You might want to skim through it again as a refresher.
Monads in small bites - Part I - Functors
Today I join the already bloated group of people who wrote monad tutorials. It’s a bit of a ritual, really.
Different than most tutorials though I aim to take a different approach. The good news is that I won’t be comparing monads to burritos :)
People say one needs to have his/her own epiphany in order to understand Monads and reading explanations from others is of little help. My goal is to disprove that.
Clojure, leiningen 2 and Heroku: AOT compilation gotchas
Recently I upgraded the clojure project I’m working on to Leiningen 2 in order to start using nrepl - since swank-clojure is now deprecated. Little did I know this would lead me to a small debugging adventure.
Heroku
I use Heroku as my deployment platform and my project had been running on it for a few weeks without any issues. I also use Heroku’s PostgreSQL solution.
However, by upgrading to Leiningen 2, my project started throwing some weird exceptions during deployment - it couldn’t connect to my database any longer. Everything was fine on my local environment though.
Sean Corfield: Clojure and CFML sitting in a tree
Last night I attended the Adobe User Group here in Sydney. That might strike some of you as a big surprise given my relationship with Adobe is pretty much limited to fiddling with Photoshop/Lightroom to get my photos looking nice.
However the reason for which I attended the meetup is that Sean Corfield - a prolific member of the Clojure community - gave a presentation on how he introduced and migrated most of his backend code at World Singles from CFML to Clojure - hence my interest.
clj syd report number 0
Last night we held the first ever meetup for the Sydney Clojure User Group!
When I decided to start running the meetups I had no idea we’d end up with 37 people on the first night! What a great turn out!
As for the content, here’s what you missed:
- Running Clojure apps on Heroku - Lincoln Stoll (@lstoll)
Linc works for Heroku but ended up not spending a whole lot of time talking about that - instead he showed us how to build a simple web application using Compojure, a small Clojure web framework.
project euler problem 4 in clojure
I solved a few of the problems on Project Euler in the past, both in Java and Ruby, and thought it would be useful to redo them in Clojure, thus improving my skills on the language’s core functions and libraries. Today I’ll share problem 4.
Go ahead and read it but here’s the meat of it:
“Find the largest palindrome made from the product of two 3-digit numbers.”
From this statement we can tell two things: (1) we’ll need a function that can tell whether a number is a palindrome or not and (2) that the largest palindrome is given by the product of two numbers between 100 and 999, inclusive.
backlog ola bini on clojure conj
As I promised in my previous post, here are the highlights of what Ola Bini had to say about Clojure/conj.
Clojure/conj is the largest gathering of clojure programmers, hackers and enthusiasts, with a single track of talks spanning three days. Ola selected his favorite talks and summarised each one of them.
The actual slides for each one of the talks can be found on github.
You can find Ola’s slides here.
Fun Data Structures
This is certainly a very interesting topic. The highlight here is the approach Clojure takes to handling immutable data structures efficiently: persistent data structures through structural sharing - maybe a good short talk for the next meetup?
announcing the sydney clojure user group
Update: We now have a [Meetup.com page][9]. Head over there to learn about our next meetups as well as to RSVP to them. We’ll discontinue usage of the wiki for registering attendees, in favor of the new site. Everything else on this post however still holds.
If you’ve been following my blog, you’ll have noticed I started running internal Clojure meetups/hack nights at ThoughtWorks here in Sydney a while ago. While being closed, we’ve already had one international speaker - [Ola Bini][7] - come and share his experience as an attendee at [Clojure/conj][8]. I promise I’ll blog about it soon.
Report: Clojure Meetup - 1
Last Tuesday we held ThoughtWorks' Australia first Clojure meetup here in Sydney. It was a lot of fun so I thought I'd share a few words about it.
The format was rather simple. First, we had a brief introduction to the language syntax by breaking down a couple of snippets and understanding how each bit worked. For instance, this is one of those snippets:
;;word count
(reduce #(if (%1 %2)
(assoc %1 %2 (inc (%1 %2)))
(assoc %1 %2 1))
{}
(clojure.string/split "Clojure 101 - this is is gonna be be great great great" #"\s"))
The cool thing here is that a simple example like this can show quite a few things about Clojure's syntax:
Tag: Misc
Mission accomplished
A year and four months ago I joined Atlassian to pursue a very exciting opportunity: to deliver realtime collaborative editing to Confluence. I have talked about it last year at EuroClojure and this year at QCon Brazil. Even Cognitect wrote a few words about it.
In a nutshell this involved writing Clojure code all day to build an awesome service we call Synchrony. Synchrony is capable of realtime data synchronisation - not just collaborative editing - and as such its applications are many! This has been proven again and again internally during the Atlassian ShipIt hackatons, and externally via Enso.me, which is powered by Synchrony.
The Clojure Sydney Meetup, four years in
In the beginning
Nearly 4 years ago I founded the Sydney Clojure User Group. I had been playing with Clojure for a little while and started a small study group to learn more. Initially this group was private and held at the ThoughtWorks office.
After a couple of meetups and conversations I decided to open up the group to the public and then realised we weren’t the only ones interested in Clojure and, even more important, interested in meeting like-minded people, share experiences and help each other.
So long 2015: Year highlights
I should have published this post still in 2015 but as I was on holidays traveling around Australia I didn’t really have the time to do it. Better late than never, right? (also Linode - the provider hosting this site - has been under a severe DDoS attack so the site just came back up today)
2015 has been a unusually quiet year in this blog. Thankfully that is because I have been extremely busy in many other areas. I’d like to take the opportunity and look back at 2015’s highlights.
So long 2014: Year highlights
Another year is about to end and as it is tradition in this blog it’s time to look at the year’s highlights!
Functional Programming
I have been advocating Functional Programming and Clojure for a while now and 2014 has been good to me. It was the first year where I was paid to work almost entirely in functional languages. Most of it was in Scala and a little less in Clojure.
A new chapter begins
Thanks, ThoughtWorks
After 4 years and 8 months I have made the hard decision to change jobs: Friday, 19th of December, was my last day at ThoughtWorks.
In this time I have made many friends and have grown a lot as a professional. Consulting presents so many new challenges that often times the technical problems you are trying to solve are the easiest part of the whole project. I am thankful for that.
ClojureBridge Sydney, vol. I
This past weekend - 19-20th of December - a group of highly motivated individuals gave up their Friday night and their entire Saturday simply to learn how to code in Clojure!
It was the first ever ClojureBridge edition in Sydney and if you haven’t heard of it before, its goal is to increase diversity in the Clojure community. It does so by offering free workshops targeted at beginners.
You should totally read Julian Gamble’s post about the event for details. He’s was one of the volunteers on the day and has done a great job of describing his experiences.
So long 2013: Year highlights
I finally got some free time so sit down and write this post. I was travelling with my girlfriend around the state of Victoria, Australia - mostly around the Great Ocean Road. I had an amazing time and it’s a trip I highly recommend anyone do.
As for this year’s highlights, let’s get started:
Clojure
clj-syd - the Sydney Clojure User Group - continues going strong and this is in great part thanks to the amazing community behind it. You can have a look at our wiki page for 2013 to see what we’ve been up to.
So long 2012: Year highlights
Keeping the tradition of end-of-year blog posts, here are my year highlights for 2012:
Clojure
I started clj-syd - the Sydney Clojure User Group - back in January and it has seen a major uptake. We consistently get an average of 25 people each month and there’s no shortage of talks and topics to discuss. It’s a great crowd and I’m proud to have started it and of being part of it.
So long 2011: Year highlights
It’s that time of the year to look back at what you’ve done and either be happy about it or… well not. :)
To me anyway 2011 was a great year but I won’t bore you with the details so I’ll just jump straight into a couple of highlights!
The biggest one of course was the project we developed to help the Queensland flood victims back in January - which brings me to the next topic:
Tag: Books
Clojure Reactive Programming has been published
I’m extremely happy to let everyone know my book, Clojure Reactive Programming, has finally been published!
You can get it at the publisher’s website or on Amazon. I had a great time writing it and I truly hope you find it useful!
I’ve met a few authors here and there and I heard more than once that a book is never really finished. I now know what they mean.
The book doesn’t cover everything I wanted to write about due to time and space limitations. Having said that, now that the book is out I do plan to expand on a few things using this blog.
EuroClojure 2014 and announcing my book
A bit late for a EuroClojure 2014 post but I suppose “better late than never” applies here.
The best part of every conference is the networking. Meeting new and interesting people is priceless and I did plenty of that - mostly over Polish beer and food. Polish beer isn’t the greatest but if you must have it, better stick to Żywiec. It’s widely available and was the one which didn’t give me a headache :) - I’ve been told there are amazing microbreweries though I didn’t get a chance to try any while in Krákow.
Tag: Functional-Programming
Clojure Reactive Programming has been published
I’m extremely happy to let everyone know my book, Clojure Reactive Programming, has finally been published!
You can get it at the publisher’s website or on Amazon. I had a great time writing it and I truly hope you find it useful!
I’ve met a few authors here and there and I heard more than once that a book is never really finished. I now know what they mean.
The book doesn’t cover everything I wanted to write about due to time and space limitations. Having said that, now that the book is out I do plan to expand on a few things using this blog.
EuroClojure 2014 and announcing my book
A bit late for a EuroClojure 2014 post but I suppose “better late than never” applies here.
The best part of every conference is the networking. Meeting new and interesting people is priceless and I did plenty of that - mostly over Polish beer and food. Polish beer isn’t the greatest but if you must have it, better stick to Żywiec. It’s widely available and was the one which didn’t give me a headache :) - I’ve been told there are amazing microbreweries though I didn’t get a chance to try any while in Krákow.
Functional composition with Monads, Kleislis and Functors
I’ve been learning Scala for my current client project and I find writing to be a great tool to test my understanding of any given topic. This means there might be a few Scala posts coming up soon as I keep learning interesting things.
Today I’ll be exploring a few different ways in which you can compose programs. I’ll be using Scalaz in this post.
The examples that follow all deal with Vehicles - more specifically makes and parts:
CUFP/ICFP 2013
I’m sitting in the Lobby of the Hilton in Boston and since my flight back to Australia isn’t for a few hours I thought I’d write my experience report while everything is still fresh in my mind.

CUFP - Commercial Users of Functional Programming - is a Workshop-like conference targeting the practically-minded functional programming community.
As it’s stated on their website, “The CUFP workshop is a place where people can see how others are using functional programming to solve real world problems […]”.
Purely functional data structures in Clojure: Red-Black Trees
This post is part of a series about Chris Okasaki’s Purely Functional Data Structures. You can see all posts in the series by visiting the functional-data-structures category in this blog.
Recently I had some free time to come back to Purely Functional Data Structures and implement a new data structure: Red-black trees.
Red-black trees
Red-black trees are a type of self-balancing binary search tree. Back when I first learned the balancing algorithm used in operations such as insert and delete, I remember it being a particularly tricky one.
Functional Programmers Unite! LambdaJam down under
I hinted at LambdaJam Australia back in my 2012 Highlights post and the dates are fast approaching so I thought appropriate to blog about it once more.
YOW! LambdaJam is a conference targeted at intermediate and advanced functional programmers and is organised in talks, jams and workshops.
- Talks are the traditional format and are 30 minutes long;
- Workshops aim to introduce a specific subjects to attendees in great detail and are up to two hours long;
- Jams are hands-on sessions. Participants will be guided through pre-defined problems around a given subject/technology and encouraged to work through the solutions either by themselves or ideally as small groups. Jams are also 2 hours long;
Sounds pretty amazing, doesn’t it?
clojure and why calculating is better than scheming
Last week while attending Clojure/West in Portland I came across a paper called Why calculating is better than scheming. In a nutshell, this paper is a critique to Abelson and Sussman’s classic textbook SICP - Structure and Interpretation of Computer Programs, used by MIT for many years to teach their introductory programming course.
If you haven’t read SICP, you should. It’s an amazing book. It uses Scheme, a dialect of Lisp, as the vehicle to present fundamental programming concepts.
Purely functional data structures in Clojure: Leftist Heaps
This post is part of a series about Chris Okasaki’s Purely Functional Data Structures. You can see all posts in the series by visiting the functional-data-structures category in this blog.
Last year I started reading a book called Purely Functional Data Structures. It’s a fascinating book and if you’ve ever wondered how Clojure’s persistent data structures work, it’s mandatory reading.
However, all code samples in the book are written in ML - with Haskell versions in the end of the book. This means I got stuck in Chapter 3, where the ML snippets start.
bouncer validation lib for clojure
Today I’m releasing bouncer, which was extracted from a project I’ve been working on.
It’s a validation library for Clojure apps and it lets you write code like this:
(def person {:name "Leo"})
(validate person
:name required
:age [required number])
If you’d like to see more examples and a detailed guide check out the github repository. The README should get you started.
This post however isn’t only about announcing bouncer. It’s also about the motivation and implementation details behind it.
Monads in small bites - Part IV - Monads
This is Part IV of my Monads tutorial. Make sure you read the previous parts:
-
Part IV - Monads (this post)
A quick recap
In Part I we learned about Functors, which are things that can be mapped over using a normal function - fmap
is used for that.
Part II tought us that when our Functors themselves contain functions and we want them applied to the values contained in other Functors, Applicatives come to the rescue - and bring theirs friends pure
and <*>
.
Monads in small bites - Part III - Monoids
This is Part III of my Monads tutorial. Make sure you read the previous parts:
-
Part III - Monoids (this post)
Monoids
Simply put, Monoids describe types containing a binary function and an identity value.
When applied to the identity value and a random value x
, said function leaves its argument x
untouched, returning it as a result.
Monads in small bites - Part II - Applicative Functors
This is Part II of my Monads tutorial. Make sure you read the previous parts:
-
Part II - Applicative Functors (this post)
Applicative Functors
In Part I I talked a little about Haskell type signatures and introduced Functors, which provide a way to map standard functions over values which are wrapped inside a Functor - we used fmap
for that. You might want to skim through it again as a refresher.
Monads in small bites - Part I - Functors
Today I join the already bloated group of people who wrote monad tutorials. It’s a bit of a ritual, really.
Different than most tutorials though I aim to take a different approach. The good news is that I won’t be comparing monads to burritos :)
People say one needs to have his/her own epiphany in order to understand Monads and reading explanations from others is of little help. My goal is to disprove that.
Clojure, leiningen 2 and Heroku: AOT compilation gotchas
Recently I upgraded the clojure project I’m working on to Leiningen 2 in order to start using nrepl - since swank-clojure is now deprecated. Little did I know this would lead me to a small debugging adventure.
Heroku
I use Heroku as my deployment platform and my project had been running on it for a few weeks without any issues. I also use Heroku’s PostgreSQL solution.
However, by upgrading to Leiningen 2, my project started throwing some weird exceptions during deployment - it couldn’t connect to my database any longer. Everything was fine on my local environment though.
Sean Corfield: Clojure and CFML sitting in a tree
Last night I attended the Adobe User Group here in Sydney. That might strike some of you as a big surprise given my relationship with Adobe is pretty much limited to fiddling with Photoshop/Lightroom to get my photos looking nice.
However the reason for which I attended the meetup is that Sean Corfield - a prolific member of the Clojure community - gave a presentation on how he introduced and migrated most of his backend code at World Singles from CFML to Clojure - hence my interest.
Tag: Euroclojure
EuroClojure 2014 and announcing my book
A bit late for a EuroClojure 2014 post but I suppose “better late than never” applies here.
The best part of every conference is the networking. Meeting new and interesting people is priceless and I did plenty of that - mostly over Polish beer and food. Polish beer isn’t the greatest but if you must have it, better stick to Żywiec. It’s widely available and was the one which didn’t give me a headache :) - I’ve been told there are amazing microbreweries though I didn’t get a chance to try any while in Krákow.
Tag: Scala
Functional composition with Monads, Kleislis and Functors
I’ve been learning Scala for my current client project and I find writing to be a great tool to test my understanding of any given topic. This means there might be a few Scala posts coming up soon as I keep learning interesting things.
Today I’ll be exploring a few different ways in which you can compose programs. I’ll be using Scalaz in this post.
The examples that follow all deal with Vehicles - more specifically makes and parts:
Functional Programmers Unite! LambdaJam down under
I hinted at LambdaJam Australia back in my 2012 Highlights post and the dates are fast approaching so I thought appropriate to blog about it once more.
YOW! LambdaJam is a conference targeted at intermediate and advanced functional programmers and is organised in talks, jams and workshops.
- Talks are the traditional format and are 30 minutes long;
- Workshops aim to introduce a specific subjects to attendees in great detail and are up to two hours long;
- Jams are hands-on sessions. Participants will be guided through pre-defined problems around a given subject/technology and encouraged to work through the solutions either by themselves or ideally as small groups. Jams are also 2 hours long;
Sounds pretty amazing, doesn’t it?
jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
Tag: Haskell
CUFP/ICFP 2013
I’m sitting in the Lobby of the Hilton in Boston and since my flight back to Australia isn’t for a few hours I thought I’d write my experience report while everything is still fresh in my mind.

CUFP - Commercial Users of Functional Programming - is a Workshop-like conference targeting the practically-minded functional programming community.
As it’s stated on their website, “The CUFP workshop is a place where people can see how others are using functional programming to solve real world problems […]”.
clojure and why calculating is better than scheming
Last week while attending Clojure/West in Portland I came across a paper called Why calculating is better than scheming. In a nutshell, this paper is a critique to Abelson and Sussman’s classic textbook SICP - Structure and Interpretation of Computer Programs, used by MIT for many years to teach their introductory programming course.
If you haven’t read SICP, you should. It’s an amazing book. It uses Scheme, a dialect of Lisp, as the vehicle to present fundamental programming concepts.
Monads in small bites - Part IV - Monads
This is Part IV of my Monads tutorial. Make sure you read the previous parts:
-
Part IV - Monads (this post)
A quick recap
In Part I we learned about Functors, which are things that can be mapped over using a normal function - fmap
is used for that.
Part II tought us that when our Functors themselves contain functions and we want them applied to the values contained in other Functors, Applicatives come to the rescue - and bring theirs friends pure
and <*>
.
Monads in small bites - Part III - Monoids
This is Part III of my Monads tutorial. Make sure you read the previous parts:
-
Part III - Monoids (this post)
Monoids
Simply put, Monoids describe types containing a binary function and an identity value.
When applied to the identity value and a random value x
, said function leaves its argument x
untouched, returning it as a result.
Monads in small bites - Part II - Applicative Functors
This is Part II of my Monads tutorial. Make sure you read the previous parts:
-
Part II - Applicative Functors (this post)
Applicative Functors
In Part I I talked a little about Haskell type signatures and introduced Functors, which provide a way to map standard functions over values which are wrapped inside a Functor - we used fmap
for that. You might want to skim through it again as a refresher.
Monads in small bites - Part I - Functors
Today I join the already bloated group of people who wrote monad tutorials. It’s a bit of a ritual, really.
Different than most tutorials though I aim to take a different approach. The good news is that I won’t be comparing monads to burritos :)
People say one needs to have his/her own epiphany in order to understand Monads and reading explanations from others is of little help. My goal is to disprove that.
Tag: Functional-Data-Structures
Purely functional data structures in Clojure: Red-Black Trees
This post is part of a series about Chris Okasaki’s Purely Functional Data Structures. You can see all posts in the series by visiting the functional-data-structures category in this blog.
Recently I had some free time to come back to Purely Functional Data Structures and implement a new data structure: Red-black trees.
Red-black trees
Red-black trees are a type of self-balancing binary search tree. Back when I first learned the balancing algorithm used in operations such as insert and delete, I remember it being a particularly tricky one.
Purely functional data structures in Clojure: Leftist Heaps
This post is part of a series about Chris Okasaki’s Purely Functional Data Structures. You can see all posts in the series by visiting the functional-data-structures category in this blog.
Last year I started reading a book called Purely Functional Data Structures. It’s a fascinating book and if you’ve ever wondered how Clojure’s persistent data structures work, it’s mandatory reading.
However, all code samples in the book are written in ML - with Haskell versions in the end of the book. This means I got stuck in Chapter 3, where the ML snippets start.
Tag: Concurrency
Clojure, core.async and the Lisp advantage
Long gone are the days when systems needed to do only one thing at a time.
Concurrency is the word but it often leads to complex code, dealing with locks, mutexes etc…
There are several different abstractions which allows us to both model and think about asynchronous code in a more sane fashion: futures, promises and events/callbacks are but a few of them.
I won’t get into the merits - or lack thereof - of these alternatives in this post but rather focus on a different alternative: Communicating Sequential Processes - CSP.
A Tale Of Concurrency: Partitioning Data Between Processes
So I had just finished writing this feature. I was confident it’d work - after all I had a good level of tests around it. It sounded like yet another successful deployment.
One week in and something starts breaking. It was hard to track down but at the end I realised it was caused by having concurrent processes running in parallel.
That’s what happened in a recent production release at our current client. It was a very interesting problem to track down and solve and I’ll do my best to explain and walk you through it here.
Tag: Lambdajam
Functional Programmers Unite! LambdaJam down under
I hinted at LambdaJam Australia back in my 2012 Highlights post and the dates are fast approaching so I thought appropriate to blog about it once more.
YOW! LambdaJam is a conference targeted at intermediate and advanced functional programmers and is organised in talks, jams and workshops.
- Talks are the traditional format and are 30 minutes long;
- Workshops aim to introduce a specific subjects to attendees in great detail and are up to two hours long;
- Jams are hands-on sessions. Participants will be guided through pre-defined problems around a given subject/technology and encouraged to work through the solutions either by themselves or ideally as small groups. Jams are also 2 hours long;
Sounds pretty amazing, doesn’t it?
Tag: Android
This is what we built in 24 hours
Last week our current client - ninemsn - ran the 3rd edition of their HackDay.
It’s akin to Atlassian’s ShipIt days so if you’re not familiar with the concept, you should check their page but here’s the gist:
-
We’re given 24 hours to work on whatever we like as long as it’s related somehow to the business
-
We’re also free to use any technology we want
The team consisted of @romainprieto, Pranav Raja, @thepaddedcell, @stewgleadow and myself (@leonardo_borges).
Tag: Ios
This is what we built in 24 hours
Last week our current client - ninemsn - ran the 3rd edition of their HackDay.
It’s akin to Atlassian’s ShipIt days so if you’re not familiar with the concept, you should check their page but here’s the gist:
-
We’re given 24 hours to work on whatever we like as long as it’s related somehow to the business
-
We’re also free to use any technology we want
The team consisted of @romainprieto, Pranav Raja, @thepaddedcell, @stewgleadow and myself (@leonardo_borges).
build automation with xcode 4 dot 3 kif and jenkins
UPDATE: As pointed to me in this commment, sym links aren’t necessary for Waxsim anymore. Check Jonathan Penn’s fork on github.
After coming back from my holidays in China - which were awesome - I had no downtime at ThoughtWorks and started at a brand new client/project - a much needed change from what I had been working on lately.
It’s an iOS project, more specifically an iPad app and that’s pretty much all I can tell you about it. I will however tell you how my first few days in the project have been so far.
Tag: Mobile
This is what we built in 24 hours
Last week our current client - ninemsn - ran the 3rd edition of their HackDay.
It’s akin to Atlassian’s ShipIt days so if you’re not familiar with the concept, you should check their page but here’s the gist:
-
We’re given 24 hours to work on whatever we like as long as it’s related somehow to the business
-
We’re also free to use any technology we want
The team consisted of @romainprieto, Pranav Raja, @thepaddedcell, @stewgleadow and myself (@leonardo_borges).
Tag: Clj-Syd
Sean Corfield: Clojure and CFML sitting in a tree
Last night I attended the Adobe User Group here in Sydney. That might strike some of you as a big surprise given my relationship with Adobe is pretty much limited to fiddling with Photoshop/Lightroom to get my photos looking nice.
However the reason for which I attended the meetup is that Sean Corfield - a prolific member of the Clojure community - gave a presentation on how he introduced and migrated most of his backend code at World Singles from CFML to Clojure - hence my interest.
clj syd report number 0
Last night we held the first ever meetup for the Sydney Clojure User Group!
When I decided to start running the meetups I had no idea we’d end up with 37 people on the first night! What a great turn out!
As for the content, here’s what you missed:
- Running Clojure apps on Heroku - Lincoln Stoll (@lstoll)
Linc works for Heroku but ended up not spending a whole lot of time talking about that - instead he showed us how to build a simple web application using Compojure, a small Clojure web framework.
backlog ola bini on clojure conj
As I promised in my previous post, here are the highlights of what Ola Bini had to say about Clojure/conj.
Clojure/conj is the largest gathering of clojure programmers, hackers and enthusiasts, with a single track of talks spanning three days. Ola selected his favorite talks and summarised each one of them.
The actual slides for each one of the talks can be found on github.
You can find Ola’s slides here.
Fun Data Structures
This is certainly a very interesting topic. The highlight here is the approach Clojure takes to handling immutable data structures efficiently: persistent data structures through structural sharing - maybe a good short talk for the next meetup?
announcing the sydney clojure user group
Update: We now have a [Meetup.com page][9]. Head over there to learn about our next meetups as well as to RSVP to them. We’ll discontinue usage of the wiki for registering attendees, in favor of the new site. Everything else on this post however still holds.
If you’ve been following my blog, you’ll have noticed I started running internal Clojure meetups/hack nights at ThoughtWorks here in Sydney a while ago. While being closed, we’ve already had one international speaker - [Ola Bini][7] - come and share his experience as an attendee at [Clojure/conj][8]. I promise I’ll blog about it soon.
Tag: Ipad
build automation with xcode 4 dot 3 kif and jenkins
UPDATE: As pointed to me in this commment, sym links aren’t necessary for Waxsim anymore. Check Jonathan Penn’s fork on github.
After coming back from my holidays in China - which were awesome - I had no downtime at ThoughtWorks and started at a brand new client/project - a much needed change from what I had been working on lately.
It’s an iOS project, more specifically an iPad app and that’s pretty much all I can tell you about it. I will however tell you how my first few days in the project have been so far.
Tag: Iphone
build automation with xcode 4 dot 3 kif and jenkins
UPDATE: As pointed to me in this commment, sym links aren’t necessary for Waxsim anymore. Check Jonathan Penn’s fork on github.
After coming back from my holidays in China - which were awesome - I had no downtime at ThoughtWorks and started at a brand new client/project - a much needed change from what I had been working on lately.
It’s an iOS project, more specifically an iPad app and that’s pretty much all I can tell you about it. I will however tell you how my first few days in the project have been so far.
Tag: Algorithms
project euler problem 4 in clojure
I solved a few of the problems on Project Euler in the past, both in Java and Ruby, and thought it would be useful to redo them in Clojure, thus improving my skills on the language’s core functions and libraries. Today I’ll share problem 4.
Go ahead and read it but here’s the meat of it:
“Find the largest palindrome made from the product of two 3-digit numbers.”
From this statement we can tell two things: (1) we’ll need a function that can tell whether a number is a palindrome or not and (2) that the largest palindrome is given by the product of two numbers between 100 and 999, inclusive.
Tag: Project-Euler
project euler problem 4 in clojure
I solved a few of the problems on Project Euler in the past, both in Java and Ruby, and thought it would be useful to redo them in Clojure, thus improving my skills on the language’s core functions and libraries. Today I’ll share problem 4.
Go ahead and read it but here’s the meat of it:
“Find the largest palindrome made from the product of two 3-digit numbers.”
From this statement we can tell two things: (1) we’ll need a function that can tell whether a number is a palindrome or not and (2) that the largest palindrome is given by the product of two numbers between 100 and 999, inclusive.
Tag: Rubyconf2011
RubyConf Brazil 2011

I was in São Paulo last week - the 3rd and 4th of November - for RubyConf Brazil. For those who don’t know, RubyConf Brazil is the evolution of Rails Summit Latin America, where I had the privilege to speak in 2009.
This year though, all bets were off. Fabio Akita and Locaweb put together a great event, with over 700 attendees and about 30 speakers split in two streams and two awesome days.
Tag: ThoughtWorks
Report: Clojure Meetup - 1
Last Tuesday we held ThoughtWorks' Australia first Clojure meetup here in Sydney. It was a lot of fun so I thought I'd share a few words about it.
The format was rather simple. First, we had a brief introduction to the language syntax by breaking down a couple of snippets and understanding how each bit worked. For instance, this is one of those snippets:
;;word count
(reduce #(if (%1 %2)
(assoc %1 %2 (inc (%1 %2)))
(assoc %1 %2 1))
{}
(clojure.string/split "Clojure 101 - this is is gonna be be great great great" #"\s"))
The cool thing here is that a simple example like this can show quite a few things about Clojure's syntax:
one year of thoughtworks a retrospective
It seems like it was yesterday that I wrote about my next big challenge: Moving to Australia to join ThoughtWorks. Since then a year has passed and I thought I'd share a little bit about what it's been like so far.
The first thing you notice when joining ThoughtWorks is that you're surrounded by smart, opinionated people. It was once common for me to be the one fighting for automated testing, TDD, Ruby and overall finding new and better ways of doing what we do - but imagine how different it is to join a team that takes that for granted. This gives you a very high standard within the team that frees your mind to try and achieve bigger things. It's a great feeling.
ThoughtWorks' culture is inspiring. We're a small and very active community - there's always something going on in our offices after hours: Tech nights, local groups' meetups, training, people randomly hacking on stuff and even band rehearsals! The point is that you can get involved in several ways and the best part is that ThoughtWorks supports all that: be it providing pizzas and beers, flying us to international conferences, buying books and whatnot in order to help us do our best! I could go on but you get the point.
In return, we get to work on hard stuff. Not only technically challenging but personally challenging as well. As consultants we can be thought of as agents of change: When we go to a client, we're not only concerned with building the coolest projects with the best tools out there - of course that's a big part of what we do - but we're expected to change the way they think, work and do business.
Since I joined I worked with 2 clients - and 2 different projects - that varied wildly between them. That is in part what makes working at ThoughtWorks so interesting to me. You get to change domains, technologies and teams more often than not, which nurtures a stimulating environment.
The first project for instance was a standard Java web app where we had the usual players such as Spring, Hibernate, Freemarker, etc...
My current project, on the other hand, is very much like a start-up: We have a EC2 box that plays our CI role, all code is hosted on Github, we're using Ruby on Rails and deploying the whole thing to Heroku + RDS.
To top it off I also had the chance to make a real difference in the Queensland Flood Relief Appeal in 2010, when we built a donation app to help the flood victims - that was definitely the highlight of the year, and something I'm particularly proud of.
What next? I'm eager to find out what my second year here has to offer. Bring it on!
clouds against the floods
I think by now everyone's heard of the hard time the guys up in Queensland, Australia are having because of the recent floods. People have lost their lives and many others have lost their homes and businesses, product of years of hard work.
As a result of this massive disaster the Queensland Government decided to run a telethon to encourage donations to help the flood victims. The Telethon aired last Sunday, 09/01/11, on Channel 9 and lasted for 2 hours.
The problem was the existing donations system that the Government had been using so far: it was just not thought out to handle the load we were expecting to have on Sunday.
That's when my employer, ThoughtWorks, kindly offered a hand to Smart Services Queensland in the attempt to make sure they could receive all donations that were likely to come through the web.
After that, on the Thursday afternoon before the event, Phillip Calçado, Ben Barnard and I set off on a mission against the clock: we had a little over 48 hours to develop, test and deploy an application that was expected to handle thousands of users. Not only that but an application that, should it fail, would prevent millions of dollars from reaching the people in need in Queensland. This was a great responsibility but we knew we could do it.
Given the time constraints it was a bit obvious that we would use Ruby on Rails for this app. Both because of the productivity it's known for and because we had the knowledge right there. With that out of the way, we had to decide how and where we would deploy this thing. We thought a little about it and came down to to 2 options: Amazon EC2 or Heroku (which is powered by Amazon EC2 under the hood). I pushed hard for Heroku and that's what we ended up going with.
Now it was time to get down and dirty and start coding the app. In principle it should be fairly simple. It needed a form where a potential donor would fill out his/her information, giving the option to receive the tax receipt by email or regular mail - more on that later. Upon clicking submit users would be taken to the secure payment gateway website where they could input their credit card number and finish the payment, after which they would be taken back to our app with a success - or an error - message and a transaction number.
Now this work flow has a couple of implications: First, all emails would have to be sent in the background so as to not interfere with the website performance. We were expecting to be sending thousands of them - workers anyone?
Second, the payment gateway integration would have to be developed and tested from scratch. Up until now the Queensland Government integrated with it in a different manner that could not be reused in this case.
And most important of all, although simple in concept, we had no idea of the load we should be preparing for. There was just no data from previous telethons. Thus we decided to prepare for the maximum we possibly could.
As we developed the application we deployed continuously to Heroku in order to test the payment gateway integration, benchmark the app using Apache AB, setup cache headers - Heroku uses Varnish - and find bottlenecks.
Email was one of these bottlenecks and that's why we decided to handle that in the background using Delayed::Jobs.
Since the first deployment, we also tweaked a couple of things at Heroku, such as migrating from their free PostgreSQL offering to a dedicated instance that we believed would both take the load and have plenty of room for all the data - as I write this post, we are already well over the 5MB limit they offer for free.
Long story short, by Saturday evening the website was up and running on 5 app instances, a 6th instance running background jobs - sending emails - and a dedicated PostgreSQL database server.
As Heroku is outside the Government network, their SMTP server was a no go on the short term so we also integrated the app with SendGrid, an email delivery service that fitted perfectly our needs - although the site got so much traction that we went over our monthly quota with them. But the nice guys from SendGrid increased our limit after I opened a ticket explaining the situation!
As for performance we used NewRelic to monitor the application, which Heroku also makes a breeze to integrate with.
We all went home to rest and get ready for Sunday, the day of the Telethon, when we would be monitoring the app throughout the day. We were all excited and when the show went live, we started seeing all those beautiful access charts moving like crazy, spiking over 720 requests per minute and being solid like a rock with flat and fast response times throughout the night.
In about two hours we had over AUD$2,000,000.00 (two million) donated through our website.
Since then the number of transactions dropped but has stayed constant and as of today we've received AUD$25,438,518.32 (over 25 millions of dollars) that will be donated to the flood victims in Queensland.
Oh, and the site is still up and going strong so move your fingers and go help: telethon.smartservice.qld.gov.au - there will be heaps of people grateful for your donation.
soon off to conquer lands afar
Once more my life is taking a huge turn.
I've been pretty quiet for the past month and honestly don't know how I managed to hold in my excitement. I've just accepted an offer from ThoughtWorks to be based at their australian offices, either in Sydney or Melbourne, depending on where my 1st project will be.
For those of you who don't know, ThoughtWorks is a global IT consultancy that is really well known in the software development community. It's been advocating agile methodologies and test-driven development for several years now and seems to work really hard to attract and keep many bright people working there.
As a result, ThoughtWorks inspires companies and professionals around the world by delivering high quality projects and massively supporting/contributing to open source projects.
Needless to say, I am really excited to be joining a company with such an amazing culture and so many smart people.
The hiring process was long, tough and tiring - but yet enjoyable. It took 5 interviews, 1 code review and 1 pairing session, a process through which I talked to 8 thoughtworkers. They take pride on their hiring process and now I understand why.
Now I'm just going through the bureaucratic side of things: gathering documents, certificates, translations - all in order to apply for my VISA, which can take up to 3 months to get ready. In the meantime, you can still find me here in Madrid, where I'll be celebrating with a few 'cañas'. Feel free to join me! ;)
Tag: Git
A Few Useful Git Commands
I’ve been working fulltime with Git for a while now and I’ve noticed a pattern of commands that emerge every so often, but not often enough that would make me remember them.
That’s why I decided to post them here so I know where to look in the future. And of course they can turn out to be useful to someone else too.
So without further ado, here they are:
#undo last commit
git reset HEAD^
#show files in a given commit
git show --pretty="format:" --name-only rev_number
#remove untracked files and directories
git clean -f -d
#track remote branch
git branch --track branch_name origin/master
# given you created a new local branch 'branch_name'
# pushes 'branch_name' to 'origin/branch_name', creating the remote branch for you
git push origin branch_name
#delete remote branch
git push origin :remote_branch_name
I’ll keep this list up to date and add more useful stuff as need arises. Enjoy.
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.
Tag: HTML5
look ma no hands tweeting with your voice
This is just another one of those boring weekends where I felt the need to hack on something.
If you follow Google Chrome's blog you're probably aware of this little nifty feature they started to implement in their latest builds: HTML5 voice recognition.
And that's when it struck me: "Hey, what if I use that and tweet with my voice instead of typing?"
The result of this hacking session is LoudParrot, a sample Rails app that shows how to do just that. You will need a fairly recent build of Google Chrome -beta - which you can download here.
You can get the source on GitHub.
Tag: Rails
look ma no hands tweeting with your voice
This is just another one of those boring weekends where I felt the need to hack on something.
If you follow Google Chrome's blog you're probably aware of this little nifty feature they started to implement in their latest builds: HTML5 voice recognition.
And that's when it struck me: "Hey, what if I use that and tweet with my voice instead of typing?"
The result of this hacking session is LoudParrot, a sample Rails app that shows how to do just that. You will need a fairly recent build of Google Chrome -beta - which you can download here.
You can get the source on GitHub.
ide review rubymine
Since I started working with Ruby about 4 years ago, I've used quite a few text editors and ide's: RadRails, gedit + plugins, TextMate and Vim.
TextMate is the one I've used the most and it's been ok for a long time. Until you realize you need half a dozen bundles to make it really useful for ruby development. Obviously the same goes for Vim and gedit.
Oh, and forget about refactoring. In these tools refactoring equals regex global replace. So if you need it, well, forget it.
That's when I decided to give RubyMine a fair go. I've been using it heavily for a while now and I must say I love it!
What pissed me off about RadRails when I first tried it was the speed. It was too slow, something people take for granted when running java based IDE's.
However this is not true for RubyMine. You DO take a hit on startup, nothing major, but once it's done, it's a breeze.
I've compiled a list of my favorite productivity shortcuts and features. Hope it'll be useful to someone else.
Productivity Shortcuts
Navigation
Ctrl + Tab - File Switcher
Cmd + Shift + T - Switching between implementation and test works perfectly. Even in a pure ruby project
Cmd + Shift + F12 - Expand/restore editor
Alt + Shift + N - Go to model/view/controller
Alt + F1 - Show current file in other views such as the project tree (scroll to file)
Cmd + Shift + N - Open file
Cmd + Alt + Shift + N - Open symbol - across files
Alt + F7 - Find usages - when on a method, variable, etc…
Running/Debugging
Ctrl + Shift + F10 - Run current [test] file. When inside a test method, run that single method.
Ctrl + Shift + F9 - Same as above, but in debug mode.
Shift + F10/Shift + F9 - Run/Debug last action executed
Alt + R - Run rake task
Refactoring
Cmd + Alt + N - Inline variable/ method
Cmd + Alt + M - Extract method
Shift + F6 - Rename
F5 - Copy current file as...
Editing
Cmd + Y - Delete line
Cmd + D - Duplicate Line/Selection
Alt + Mouse - Column selection
Cmd + Shift + (Up Arrow|Down Arrow) - Moves de line or selected block of code up or down
Features
Code completion - It's fairly accurate and pretty fast. They've done some good yak shaving around this area.
Debugger - The debugging interface is an absolute beauty. Saved me a lot of time where I'd have used puts statements or googled to re-learn how to use ruby-debug instead. Definitely worth checking out.
The bad stuff
It is not free - unless you are a committer to an open-source project. But it's not expensive either.
It is a bit slower - but not that much. The performance hit is insignificant compared to the added value.
Regex file open, TextMate style - What can I say? I do miss this.
Wrap highlighted text - In TextMate, if you highlight a word and press ", [, {, ( or # it surrounds the word with the respective combination of quotes, brackets, etc... Another missed feature
Wrapping up
It's probably soon to say it but so far RubyMine has been my missing Ruby IDE. And I'm very happy with it. :)
clouds against the floods presentation available
Last Tuesday I gave a short presentation on the whole Clouds Against the Floods thing at the Ruby on Rails Oceania User Group here in Sydney.
Those guys are awesome and they recorded the talk - thanks guys!
If you'd like to download the slides, they're available on Slideshare.
Enjoy! ;)
update to appconstants it can now be used as a gem
This is just a quick post to let you know that AppConstants can now be used as gem!
Just add it to your Gemfile and 'bundle install' it:
#in your Gemfile
gem "app_constants"
#in the console
$ bundle install
$ rails generate app_constants
#then follow the instructions on-screen instructions
It can also be used without Rails. Check out full instructions on the GitHub repository.
Feedback welcome :)
clouds against the floods
I think by now everyone's heard of the hard time the guys up in Queensland, Australia are having because of the recent floods. People have lost their lives and many others have lost their homes and businesses, product of years of hard work.
As a result of this massive disaster the Queensland Government decided to run a telethon to encourage donations to help the flood victims. The Telethon aired last Sunday, 09/01/11, on Channel 9 and lasted for 2 hours.
The problem was the existing donations system that the Government had been using so far: it was just not thought out to handle the load we were expecting to have on Sunday.
That's when my employer, ThoughtWorks, kindly offered a hand to Smart Services Queensland in the attempt to make sure they could receive all donations that were likely to come through the web.
After that, on the Thursday afternoon before the event, Phillip Calçado, Ben Barnard and I set off on a mission against the clock: we had a little over 48 hours to develop, test and deploy an application that was expected to handle thousands of users. Not only that but an application that, should it fail, would prevent millions of dollars from reaching the people in need in Queensland. This was a great responsibility but we knew we could do it.
Given the time constraints it was a bit obvious that we would use Ruby on Rails for this app. Both because of the productivity it's known for and because we had the knowledge right there. With that out of the way, we had to decide how and where we would deploy this thing. We thought a little about it and came down to to 2 options: Amazon EC2 or Heroku (which is powered by Amazon EC2 under the hood). I pushed hard for Heroku and that's what we ended up going with.
Now it was time to get down and dirty and start coding the app. In principle it should be fairly simple. It needed a form where a potential donor would fill out his/her information, giving the option to receive the tax receipt by email or regular mail - more on that later. Upon clicking submit users would be taken to the secure payment gateway website where they could input their credit card number and finish the payment, after which they would be taken back to our app with a success - or an error - message and a transaction number.
Now this work flow has a couple of implications: First, all emails would have to be sent in the background so as to not interfere with the website performance. We were expecting to be sending thousands of them - workers anyone?
Second, the payment gateway integration would have to be developed and tested from scratch. Up until now the Queensland Government integrated with it in a different manner that could not be reused in this case.
And most important of all, although simple in concept, we had no idea of the load we should be preparing for. There was just no data from previous telethons. Thus we decided to prepare for the maximum we possibly could.
As we developed the application we deployed continuously to Heroku in order to test the payment gateway integration, benchmark the app using Apache AB, setup cache headers - Heroku uses Varnish - and find bottlenecks.
Email was one of these bottlenecks and that's why we decided to handle that in the background using Delayed::Jobs.
Since the first deployment, we also tweaked a couple of things at Heroku, such as migrating from their free PostgreSQL offering to a dedicated instance that we believed would both take the load and have plenty of room for all the data - as I write this post, we are already well over the 5MB limit they offer for free.
Long story short, by Saturday evening the website was up and running on 5 app instances, a 6th instance running background jobs - sending emails - and a dedicated PostgreSQL database server.
As Heroku is outside the Government network, their SMTP server was a no go on the short term so we also integrated the app with SendGrid, an email delivery service that fitted perfectly our needs - although the site got so much traction that we went over our monthly quota with them. But the nice guys from SendGrid increased our limit after I opened a ticket explaining the situation!
As for performance we used NewRelic to monitor the application, which Heroku also makes a breeze to integrate with.
We all went home to rest and get ready for Sunday, the day of the Telethon, when we would be monitoring the app throughout the day. We were all excited and when the show went live, we started seeing all those beautiful access charts moving like crazy, spiking over 720 requests per minute and being solid like a rock with flat and fast response times throughout the night.
In about two hours we had over AUD$2,000,000.00 (two million) donated through our website.
Since then the number of transactions dropped but has stayed constant and as of today we've received AUD$25,438,518.32 (over 25 millions of dollars) that will be donated to the flood victims in Queensland.
Oh, and the site is still up and going strong so move your fingers and go help: telethon.smartservice.qld.gov.au - there will be heaps of people grateful for your donation.
small update to appconstants
It's been now over a week since we moved to Sydney and everything is just great. We're still house hunting but I got a feeling we'll have a home soon. :)
In the meantime, this morning I got a feature request on github to allow AppConstants to interpret YAML files with embedded code like this:
I haven't needed it myself but thought it would be a nice addition so my latest commit does exactly that. Let me know if you find any issues.
upgrading appconstants to rails 3
Back in January I announced a small but useful plugin called AppConstants, that basically provides a central place where you can store environment specific constants. And since I started using Rails 3 in the past week, I thought I'd make it Rails 3 compatible.
The code is really simple and - as I expected - the upgrade process was quite straight forward.
I'm not gonna write a guide here on how to upgrade your plugins to Rails 3 - there is plenty about that around the web - but instead, just show the steps I went through to upgrade mine. Similar plugins might have a similar upgrade path.
- Generators
My plugin makes use of a simple generator that copies its default constants file and initializer to Rails.root/config and Rails.root/config/initializers, respectively. In Rails 2.x it was located under Rails.root/vendor/plugins/app_constants/generators/app_constants and it was defined like so:
In Rails 3, the generators had to be moved to Rails.root/vendor/plugins/app_constants/lib/generators. Notice the root directory app_constants under generators has been removed as well. And the code was changed to this:
We had three simple changes here:
- The generator now extends from Rails::Generators::Base: This class uses the Thor infrastructure to handle generators. - more info here.
- I had to implement the source_root class method, which basically tells your generator where to find your template files.
- The manifest method is now called copy_config_files - or anything you want.
The way this works is that, once you invoke the generator, Thor will sequentially call all instance methods in your generator class - or the only instance method in the example above. If your generator does a lot, it will allow for a better organization of your tasks.
And that's it! I did change a couple of other things but that had to be changed anyway and are not related to the migration.
For Rails 2.3.x users, you'll find a 2.3.x branch on github that should work for you.
Cheers
my take on rails environment specific constants
It’s funny how every Rails application I - and possibly you - work on ends up needing some sort of per-environment global constants.
Examples may include the application url - It might be used in account activation emails and thus should be different between the development and production environments.
Or perhaps your application depends on external services that, depending on the environment, are available in different URIs.
There are a couple solutions out there but my needs were simple and straightforward, thus I developed a small rails plugin that is the simplest thing that could possibly work: AppConstants.
It's been useful for my current project and I hope it can be useful to someone else too ;)
monit thinking sphinx and rvm
In one of my Rails projects I'm using Sphinx to provide full-text search capabilities. To integrate both worlds I chose Thinking Sphinx, which is just great and so far has met all of my expectations.
Also, as I previously mentioned, I'm using RVM to manage my ruby installations on both my development and production machines and this setup is what motivated this post.
I use Monit to monitor the services running on my production server - nginx, mysql, php - and as of the first deploy of this application, it only made sense to also monitor Sphinx.
In order to create an initialization script, I would need at least a way to start and stop sphinx from the command line, which, using Thinking Sphinx, can be done using these rake tasks:
$ rake thinking_sphinx:stop
$ rake thinking_sphinx:start
It's worth mentioning now that I don't run sphinx as root. I run it with the same user my rails application uses. For the purpose of this post, let's call it deploy.
When I tried using my script I got errors such as these:
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.
After some digging around I found that the GEM_HOME environment variable for my deploy user wasn't being set correctly - something to do with rvm, but not quite sure - and to fix this, well, I just had to set it, leaving the final working version of my script somewhat like this - simplified :
#! /bin/sh
### BEGIN INIT INFO
### END INIT INFO
set_path="cd /your/rails/app/root; export GEM_HOME=/path/to/your/gems; RAILS_ENV=production;"
case "$1" in
start)
echo -n "Starting sphinx: "
su - deploy -c "$set_path rake ts:start" >> /var/log/sphinx.log 2>&1
echo "done."
;;
stop)
echo -n "Stopping sphinx: "
su - deploy -c "$set_path rake ts:stop" >> /var/log/sphinx.log 2>&1
echo "done."
;;
*)
N=/etc/init.d/sphinx
echo "Usage: $N {start|stop}" >&2
exit 1
;;
esac
exit 0
There are 2 things happening here. First, regardless of the user I’m running this init script as, I drop privileges in order to execute the rake task with my deploy user. Second, I set the GEM_HOME environment variable to stop getting the ‘gem not found’ errors.
After that, monit was able not only to monitor my sphinx instance, but also (re)start/stop it with the correct user.
I’m no Linux wizard so if you wanna suggest improvements to this script, feel free to do so!
rails summit 2009 im speaking
I'll be speaking at this year's Rails Summit Latin America in Sao Paulo, Brazil. It will be a good opportunity to meet some amazing people and visit friends back home! :)
Overall I'll be spending 12 days in Brazil, with 2 of them dedicated to the conference. The other 10 I'll be in Rio de Janeiro visiting my family and friends. I strongly advise you to spend some time in Rio too, if at all possible. It's an amazing city and you can contact me if you have any questions.
Back to the conference, my session is called JRuby in the enterprise world: Using Rails with legacy code, and will be given in the form of a tutorial. I will walk you through some problems we had while making this kind of integration at my company, focusing mostly on dependency management.
At the end I hope you'll have a good understanding of what JRuby is capable of in a legacy environment.
If you're planning to attend and would like to hear anything specific about JRuby, please let me know, I can try and squeeze in.
C u there!
rails rumble 09
Update: The service is now down while we move it from the VPS provided by Rails Rumble to our own. I'll let you know once it's up.
Last weekend Philip, Pedro and myself got together for this year's Rails Rumble.
We haven't had really decided what to do until a few days before the competition, but I had this really simple idea and decided to go with it. Seems people liked it, given a few positive comments we received.
So, after 48 hours - which were not used to work full-time in the application - The Bird Watcher was born.
The Bird Watcher is a simple way to show the world what's going on on Twitter for any topic you define. Go ahead and take a look at the website to see a live example.
We're planning to keep the service up after the competition is over and we have some nice features lined up to go live on the next release.
In short, it was an interesting weekend and showed me that this team works really well together.
Cheers
jruby on rails and legacy java apps managing dependencies
The motivation for this post came from a couple of messages I've seen on the jruby's google group and because I think it's pretty cool to share how we tackled this problem.
- A little bit of context
We, as a vast amount of people out there, have legacy Java code. A lot. In our case this legacy is pretty much crucial to our business. We can't just trash it and start from scratch. Bad idea.
On the other hand we do have new features to be built on top of it. But we wanted an easier way to develop this new stuff and decided for a JRuby on Rails solution, using it as a front-end to our existing services.
- What we decided to do
Our final rails project would make use of a specially created jar file containing our Java application. This Jar would also contain a public interface of the services we'd have to interact with from rails.
As any Java application, ours depend on a number of external jar files that correspond to the various framewoks we usually have in place. e.g.: Hibernate, Spring, apache-commons ...
Which means we need to make our app's jar and all it's dependencies available in the JRuby classpath in order to use it.
Given we're using warbler to package our application as a war file, we just need to place all jars needed into our rails app's lib folder. Warbler then takes care of copying any jar files located in there into the war.
- The problem
So we needed a smart way to include all these dependencies into the project, and copy/paste isn't an option.
In the Java world we use Maven to manage our projects dependencies - and you should too. Because of that our approach involved turning our rails application into a Maven aware project.
Basically we needed a pom file that would declaratively list our java project as a dependency. From there on, Maven knows what the dependencies are and downloads them to your local repository.
Which leaves us with one more task. We need to put all these dependencies into our lib folder after maven has downloaded them.
Below you'll find the pom.xml file that we use to achieve this with inline comments explaining each bit:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<!-- notice how we specify the packaging to be a war,
that way, maven knows where to copy the jar files -->
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<artifactId>railsApp</artifactId>
<name>railsApp</name>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>java-legacy-app</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>railsApp</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<!-- This tasks only creates a basic structure expected by maven,
so it can do its work -->
<id>create-mock-web-descriptor</id>
<phase>compile</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
mkdir -p src/main/webapp/WEB-INF
touch src/main/webapp/WEB-INF/web.xml
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Now in the package phase we copy the jar files
that maven put into the fake web app to our rails' lib folder -->
<id>copy-needed-jars-into-lib</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -f lib/*.jar
cp target/railsApp/WEB-INF/lib/*.jar lib
rm -rf target/railsApp*
rm -rf src
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Here we optionally create the final war file containing our rails app using warbler,
doing a small cleanup of the files and folders maven created -->
<id>create-final-war</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -rf *.war tmp/war
jruby -S warble && \
mv *.war target/railsApp.war
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Now from the command line we can just run mvn package and we’re good to go.
Maven will start to package the application as a war file. Since it’s not a Java application we create the empty web.xml file in the compile phase, to fool maven.
After it has copied all the dependencies into WEB-INF/lib the next packaging goals will make sure we copy them to our rails’ lib folder, also creating the final war file, ready for deployment.
Note that once done, you can use a simple code snippet similar to this one as an initializer and load all dependencies:
Dir.entries("#{RAILS_ROOT}/lib").sort.each do |entry|
if entry =~ /.jar$/
require entry
end
end
Then we can just use script/console, script/server and so on, as we normally would.
Sorry for the long post, I tried to pack in as much as I could and I certainly hope it’s useful to someone. Any doubts, comments and etc… just drop me a line. :)
rails readable test names run individual tests from the console
As you probably know, since rails 2.1 you can write test methods in the following format:
test "hotel should return its permalink" do
#your test code here
end
Which is great, as the test name becomes much more clear. But you can't simply run this test easily from the command line. You'd have to run something like:
$ ruby your_test_file.rb -n test_hotel_should_return_its_permalink
It annoys me. And it's not practical either to make the test fail just so you can get the test's real name.
I wanted to be able to just copy and paste the readable name in the console and have Test::Unit do the conversion and run it for me, like this:
$ ruby your_test_file.rb -n "hotel should return its permalink"
So I created readable_test_names_runner. It's a tiny rails plugin that adds this feature for you.
Enjoy.
rcov jruby and rcov_plugin
The rcov_plugin project is a rails plugin for rcov that adds some useful rake tasks to your application. And since I'm currently working in a JRuby project it made sense to use this plugin.
The thing is, among other stuff, an rcov report from a JRuby project includes some files that shouldn't be there at all, plus you also need to change the way you call rcov as such. Thus, I thought I'd contribute these changes to the plugin and my pull request was approved this morning - just install the latest version and you should be good to go.
It was useful for us here, hope it might be useful for you too.
Enjoy :)
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!
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
dont use rexml i mean it
REXML is the standard XML processing library for Ruby. It's on Ruby's core and is terribly slow.
Yeah, I know it's pretty simple to use, got a nice interface and, again, it's just there. And it is a good library, for most things. But if you, as me, came to a point that processing XML is taking 50% of the time to render a rails action, it's time to change.
My tip? Use libxml instead. The numbers on their home page speak for themselves. Try it yourself, you won't be disappointed. And I'm really happy with the performance increase on our app.
railsconf europe 2008 impressions and highlights
I'm back in Madrid again after the RailsConf and I think it's time to say something about it. :)
First off, the infrastructure provided by the conference was really great. The rooms, WiFi connection, food... Really well organized.
Now to the sessions, highlights:
Tutorials (Tuesday)
- Meta-programming Ruby for fun and profit (Neal Ford, Patrick Farley)
The old and good techniques that made Ruby so powerful. Here Neal and Patrick walked us through the main tricks to meta programming like open classes - and conditionally open them - , dynamically define methods, sending messages to objects and how Ruby can help test your Java code in a much easier way.
I've put the link to the slides but honestly I don't think they're too much useful without the talking.
Sessions (Wednessday)
- EC2, MapReduce and Distributed processing (Jonathan Dahl)
Jonathan explained the theory behind MapReduce using very simple ruby examples, providing the basics on how to distribute and paralelize tasks accross multiple machines.
He also introduced Hadoop, a platform built in Java that "lets one easily write and run applications that process vast amounts of data". What I liked the most was the simplicity he explained this subject. As of today, his presentation is not available online. Stay tuned as I'm gonna update this post with the links, as soon as they're available.
Sessions (Thursday)
- Debugging & Testing the Web Tier (Neal Ford)
If you've been concerned about testing your app's web tier lately, this presentation would probably not show you anything new. Neal talks about the need to debug and test javascript behaviour accross multiple browsers, using tools like Firebug, JSUnit and Selenium. If you have no idea about what these tools are, please stop now and go evaluate them!
We are pretty concerned about testing on my actual job, but selenium tests can be a pain sometimes - a.k.a extremely slow. And what ends up happening is that they are forgotten. Developers only run the test suite if it's not painful and it's lightning fast. Here's is where the highlight for this session comes: CrossCheck.
The idea is to be able to test your javascript code accross multiple browsers without the need to launch them. In fact, you don't even need a browser installed. The negative point is that it's kinda fallen behind because now you can only test older versions of browsers. But since the project is getting a lot of traction, I'm pretty sure this will be solved soon.
Conclusion
My overall impression of the other sessions I attended is that some speakers just didn't have time to properly prepare themselves, what made me think this years's RailsConf wasn't all that I expected.
But I also met interesting people and after all one of the key points in a conference is networking. :)
Definitely worth it though. And that's why I took the time to provide this highlights.
c u soon
railsconf europe 2008 heading to berlin
The title says it already.
On monday I'll be going to Berlin to attend this year´s RailsConf.
This will be my first one and of course my expectations are pretty high!
As usual, after the conference I'll try and give a summary of what happened there, providing as much content as I can.
Anyone else's going??? :)
C u there!
mac os x getting mysql and rails to work
So I couldn't resist and bought myself a MacBook Pro! It's my first week with my new toy and I'm really enjoying it.
But I need to do something useful with it so I started to prepare it to be my new development platform, starting with Ruby/Rails + MySQL: Here is where the fun begins!
After I installed both Rails and MySQL, I fired up a terminal an typed:
sudo gem install mysql
...and here is what u get
ERROR: Failed to build gem native extension.
If you google this error you will find a couple solutions and this is the one that worked for me:
ARCHFLAGS="-Os -arch x86_64 -fno-common"
sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
--with-mysql-config=/usr/local/mysql/bin/mysql_config
Now, confident enough, I created a sample rails app and tried to create the development database:
leo$ rake db:create (in /Users/leo/projects/test)
dyld: lazy symbol binding failed: Symbol not found: _mysql_init
Doesn't look happy yet huh? This took me a while to figure out but it turned out to be fairly simple.
I have no idea why but after I installed the gem I had the file mysql.bundle in two different places:
/Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
/Library/Ruby/Gems/1.8/gems/mysql-2.7/mysql.bundle
The solution was to remove the first copy of the file. Now everything is working fine at this end!
I really hope this is useful to someone!
rails vulnerability on rexml
REXML, the XML library uses by many ruby apps, including rails, has a vulnerability that requires an immediate patch on whatever rails version you're using.
Details and instructions on the official rails weblog, here.
But basically, this is what you need to do:
gem install rexml-expansion-fix
Then, require rexml-expansion-fix in your rails's app environment.rb file.
the biggest rails event in latin america
Behold latin american railers!
This year we will have the Rails Summit Latin America on October, 15th and 16th, in São Paulo, Brazil.
It's by far the biggest Rails event we've ever had, including many of the speakers that were present at RailsConf.
Fábio Akita is also one of the speakers and provides more details on his blog.
If you're a assumed rails geek don't miss the opportunity to hear from the big names and to know a beautiful country like Brazil.
Oh, btw, if you're brazilian, like me, you have no excuse to miss this party!
Enjoy!!!
passenger mod_rails and problems with custom apache installation
This week we started to test mod_rails in a couple of projects where I work on. One in production.
Of course it's too early for any conclusions, but I just wanted to share a couple of problems you might find when the installer tries to compile the Apache module.
In our case, and I believe it is the case of many servers out there, we have a custom Apache installation, what makes the installer not find it and/or not find the Apache Portable Runtime (APR) sometimes.
The first one is easy and is documented here. You just seed to export the following environment variable, pointing to your apache installation:
export APXS2=/opt/apache2/bin/apxs
The second one is a bit tricky but it happened only when I tried to install passenger in another server that had CentOS. In this case, you will also need the following environment variable, pointing to your Apache APR config:
export APR_CONFIG=/usr/local/apache2/bin/apr-1-config
It took me a fair amount of time googling around to find this answer, so I hope it'll be useful for someone. :)
euruko 2008 materials available
As some of you know I went to the European Ruby Conf in Prague, this year.
The event was awesome and it's good to know they finally made available the majority of the slides, here.
They also published Matz's keynote, and more videos from the conference are being edited right now, so stay tuned to their home page!
Enjoy!
a couple of things from here
It's been some time since my last post but here I am! Where? In Spain, of course! Having a great time, I must say.
I arrived last week in Madrid and the past 2 weeks before that I spent basically packing my stuff. There is still some paperwork going on but everything is flowing well.
Besides this little feedback, I was reading this week's issue of the excellent series This Week In Ruby, from my friend Antonio Cangiano. I found something quite interesting, a plugin called HoboFields.
One of the things that bothers me in rails is the fact that by looking at your model classes, you can't tell the fields you have there. Sure, you can look at the migration script. Yeah, you can also load the development environment and inspect the object. It's a pain in the @zz! But this is the way ActiveRecord works...
Other ORM solutions like DataMapper, allows you to define the fields directly in the class. It's a much cleaner and clear way to maintain your models. And you get to know what properties you have just by looking at your classes.
That's exactly what HoboFields adds to ActiveRecord.
You define your properties and its types straight into your model class, and the plugin creates the migration scripts for you. Coming from a java world my self, I find it rather interesting, useful and it also reminds me of the way Hibernate works. You define your mappings with anotations in your class and hibernate just generate the schemas from there.
It's worth a try.
passengermod_rails released
Passenger(mod_rails) has been released.
The idea is to ease the pain on rails applications deployment. I tested myself and in less than five minutes I had my application working behind Apache!
I'm not going to say much here besides the fact that it seems like a really good option for rails deployment and people have been talking about it already, including DHH.
But I do recommend a read on the architecture overview document. Be sure to read it all, specially the part on handling concurrent requests.
To install, "it doesn't get easier than" that.
Good job guys.
jruby db2 xquery bug
Update: Follow up link to this issue on JRuby's Jira, here
As I told in my last post, it was time to give JRuby a serious try. So I took one of our rails projects at work and decided to migrate it to JRuby and see what happens.
We heavily use the XML capabilities of DB2 and this was a huge problem. Every query would work just fine through the activerecord-jdbc-adapter - part of the JRuby Extras . But every Xquery would gracefully fail!
After some debugging I got stuck and decided to get JRuby and activerecord-jdbc-adapter's source to see what was happening.
As I could see, it has a bug -in my opinion - at the java part of the code. The jdbc-adapter is a bridge to allow Active Record to talk with databases through native JDBC drivers, so it's normal that we do have a java part here. At this point, what the code does is to inspect the sql statement sent from ruby and decide if it's a select, update or insert.
I fixed the problem and submitted a patch to rubyforge. I'm not sure if it's the best solution or not, but now I got the xQueries working just fine.
I'd love to hear from people with similar environments whether this patch works for you or not. I'm sure I didn't try every possibility.
If you wanna try it, just drop me a message (e-mail in the About page) and I can send the pre-compiled jar file - for activerecord-jdbc-0.8
You can also just check out the code and compile yourself. ;)
qcon 2008 slides available
Most of last QCon's presentations are available for download here.
Highlights to Ola Bini's on JRuby(pdf) and Randy Shoup's on eBay's architectural principles(pdf).
And while we're talking about JRuby, it's impressive how it's becoming a recurrent and big subject. Fast. It had its own small space at big event like QCon and in the last Euruko in Prague, we had a presentation by the JRuby Core Developers Charles Nutter and Thomas Enebo.
Big companies are sponsoring JRuby's development indirectly or directly, like Sun. And other big companies are endorsing its production ready state, like Oracle, which has a publicly available website developed with JRuby On Rails.
It's past the time to give it a serious try...
euruko 2008 european rubyconf prague
On friday I'll be heading Prague for the European RubyConf.
Anyone is going? :)
Almost 300 attendees already registered for the event. And a few very interesting people will be speaking there like Matz and DHH (this one, through skype).
Besides that, the organization staff is scheduling 2 parties, friday and saturday, for the attendees.
Networking comes to mind, doesn't it? I think it will be a great opportunity to meet interesting and bright people.
So, see u in Prague!
openid
I think I've been really lucky lately. In my new job I'm getting to work with many interesting things and OpenID is just one of them.
We are investing high in Ruby on Rails and we have now a few internal applications in development stages. Our manager wanted the ability to let people log in to our rails applications(for now) using their OpenID accounts.
It was a funny task, as I knew very little about OpenID. The idea actually is really good. Instead of creating a new user account on each new service/site you'd like to subscribe to, you create a single user account in a OpenID provider - like MyOpenID - and use this identity to authenticate yourself in the services/sites that support this protocol.
What do we earn from that? Well, in my opinion, we can get a couple of benefits:
- You don't need to memorize 723 logins and 723 passwords (if you really care about creating different passwords for all of your user accounts)
- You don't authenticate yourself to the service you're attempting to use. This service actually asks to your provider if your identity is valid, and you authenticate yourself there. Nowhere else.
I strongly recommend you visit the OpenID to understand more about it.
But, back to the problem, we needed to put it working in a rails app. And that's when I found the ruby-openid library, provided by OpenID Enabled.
It is a complete library, really well documented that provides an abstraction layer both for consumer and server applications.
My first step was to develop the consumer. That's what you need if you are going to provide your users with OpenID authentication in your web site. The ruby-openid library comes with several samples that really helped me out here. They were developed using Ruby On Rails and are a really good start point.
After this step, I was asked to evaluate the possibility of being a OpenID provider. At first I thought it would be a really complicated task, but again this ruby library had a great example of a simple provider. The drawback is that the samples were developed in an older version of Rails ( < 2.x ) . So I had to freeze the Rails version to 1.2.5 so I could run the provider sample code.
I am now working on porting this code to Rails 2.x, into one of our applications and it's been flowing well so far. Just wanted to share this library for those of you trying something similar. It is really worth a look.
rails 20 xml data type and db2
[2008/04/30] Update: The ibm_db gem has been updated to support the new Rails 2.0 style migration. Now you can just use t.xml and it will work. Look here for more info. Thanks to Mario Briggs for pointing me to the update.
---
In my new job we work with XML data natively stored on DB2. I have done some test with Rails and DB2 a few weeks ago and it's pretty interesting, specially the easiness that Rails deals with XML.
We decided to test some new features of DB2 9.5 and I decided to test them with Rails 2.0.
So I created a new Rails app, configured the database.yml to use the idm_db gem and fired:$ rake db:create
The output is nice but, the database isn't there! I suppose it's something with the gem that needs to be updated. But really don't know about it. It just doesn't work. But this will not hold us down. I will just create the database by hand and keep going with my tests.
After that, I created a new model XmlDocument, which has a column named data, of type XML. According to the new migrations syntax, my model's migration would look something similar with this:class CreateXmlDocuments < ActiveRecord::Migration
def self.up
create_table :xml_documents do |t|
t.xml :data
t.timestamps
end
end
def self.down
drop_table :xml_documents
end
end
Right? Ok, I fired up a terminal and lauched:$ rake db:migrate
The output? Here it is:== 3 CreateXmlDocuments: migrating ============================================
-- create_table(:xml_documents)
rake aborted!
undefined method `xml' for #
Yes, a big nice exception! The new migration syntax doesn't allow you to do t.xml! But please don't ask me why! :p
The solution? Well, although it's weird - imo - , it's also easy. You can mix the new and the old syntax in the same file. So our model's migration will now look like this:class CreateXmlDocuments < ActiveRecord::Migration
def self.up
create_table :xml_documents do |t|
t.column :data, :xml
t.timestamps
end
end
def self.down
drop_table :xml_documents
end
end
And that's it! We're ready to go! I didn't find anything else different so far, besides what I described here. Hope this helps!
rails 20 scaffold
Following the Rails 2.0 hype, I've been playing around with it and decided to share a first impression: Scaffolding is gone!
But wait, before you knock your head against the wall, let me tell you something: I lied :)
Scaffolding is not really gone. It's just changed a bit.
How can I tell? Well, as a good developer I thought: "I'll just create a scaffold with the new version and see what's different"
I fired up a terminal, created a news rails application and generated a new model:$ script/generate model Contact name:string email:string
- yes you can do this in rails 2.0, and these fields get into your model's migration!
Now the I have a new model, it's time for a controller to manage it:$ script/generate controller Contacts
So your controller would look something like this huh?class ContactsController < ApplicationController
scaffold :contact
end
Well, too bad! The method scaffold is gone from ActionController::Base! And I'm not lying this time!
Now that the dynamic scaffold is gone, we're left with the static one.
Ok, let's try it then:$ script/generate scaffold contact
And it won't work again! ;) At the end of the output, you will get something like this:Another migration is already named create_contacts: db/migrate/001_create_contacts.rb
It really means that if your model is meant to be used by a scaffold, you better generate it in the same line. It will fail, afaik, if the model previously existed. Destroy yout model and controller, and execute the following:$ script/generate scaffold Contact name:string email:string
Done! Just run your migrations, startup your server and your new scaffold in rails 2.0 will be working gracefully!
It took me a while to discover this changes because I didn't find it well documented. But maybe I was not looking in the right places. :)
rubyworks production stack for rails
Well, we all know how hard, or at least cumbersome, it can be to set up a production environment to deploy your applications. Besides all the hardware stuff like storages, links, routers you are still left with a huge amount of software configuration to handle. This often includes configuring things like clusters, load balancing and services monitoring - Including notification of interested parts in case of any failure. Pieces of software you have to tie up and make them work together.
But hey, ruby lovers, you may have a better way to get this going! Released by ThoughtWorks, RubyWorks is, as quoted from their website, a production application stack for Ruby On Rails applications. I decided to give it a try and I really enjoyed it.
First of all I didn't want to mess with my actual configuration so I installed a new vm with Virtual Box. It has Ubuntu 7.10 on it, with 256MB of memory.
After installing RubyWorks - instructions on their website -, you get a new skeleton rails app up and running, being served by 4 mongrels that defaults to production environment! Impressed? There is more. A HAProxy is also set up in front of your mongrel servers acting as a load balancer.
Well, you probably want to monitor all that stuff huh? A monit web interface is waiting for your call on port 2812! It monitors all your mongrel servers - four by default - and your HAProxy, allowing you to measure CPU and Memory usage, among other things.
The coolest thing here is that all these softwares you would have to setup by hand are already working together, ready for production! Well, is it?
Going a little deeper, I deployed a database backed application to test this stack's performance.
I used Siege to stress the app and I am very happy with the results! I compared it with a single mongrel running on production env and no proxy at all.
It is worth mentioning that having 4 mongrels running took my vm to 77% of memory usage, while a single mongrel took it to 38%.
Tag: Ruby
look ma no hands tweeting with your voice
This is just another one of those boring weekends where I felt the need to hack on something.
If you follow Google Chrome's blog you're probably aware of this little nifty feature they started to implement in their latest builds: HTML5 voice recognition.
And that's when it struck me: "Hey, what if I use that and tweet with my voice instead of typing?"
The result of this hacking session is LoudParrot, a sample Rails app that shows how to do just that. You will need a fairly recent build of Google Chrome -beta - which you can download here.
You can get the source on GitHub.
ide review rubymine
Since I started working with Ruby about 4 years ago, I've used quite a few text editors and ide's: RadRails, gedit + plugins, TextMate and Vim.
TextMate is the one I've used the most and it's been ok for a long time. Until you realize you need half a dozen bundles to make it really useful for ruby development. Obviously the same goes for Vim and gedit.
Oh, and forget about refactoring. In these tools refactoring equals regex global replace. So if you need it, well, forget it.
That's when I decided to give RubyMine a fair go. I've been using it heavily for a while now and I must say I love it!
What pissed me off about RadRails when I first tried it was the speed. It was too slow, something people take for granted when running java based IDE's.
However this is not true for RubyMine. You DO take a hit on startup, nothing major, but once it's done, it's a breeze.
I've compiled a list of my favorite productivity shortcuts and features. Hope it'll be useful to someone else.
Productivity Shortcuts
Navigation
Ctrl + Tab - File Switcher
Cmd + Shift + T - Switching between implementation and test works perfectly. Even in a pure ruby project
Cmd + Shift + F12 - Expand/restore editor
Alt + Shift + N - Go to model/view/controller
Alt + F1 - Show current file in other views such as the project tree (scroll to file)
Cmd + Shift + N - Open file
Cmd + Alt + Shift + N - Open symbol - across files
Alt + F7 - Find usages - when on a method, variable, etc…
Running/Debugging
Ctrl + Shift + F10 - Run current [test] file. When inside a test method, run that single method.
Ctrl + Shift + F9 - Same as above, but in debug mode.
Shift + F10/Shift + F9 - Run/Debug last action executed
Alt + R - Run rake task
Refactoring
Cmd + Alt + N - Inline variable/ method
Cmd + Alt + M - Extract method
Shift + F6 - Rename
F5 - Copy current file as...
Editing
Cmd + Y - Delete line
Cmd + D - Duplicate Line/Selection
Alt + Mouse - Column selection
Cmd + Shift + (Up Arrow|Down Arrow) - Moves de line or selected block of code up or down
Features
Code completion - It's fairly accurate and pretty fast. They've done some good yak shaving around this area.
Debugger - The debugging interface is an absolute beauty. Saved me a lot of time where I'd have used puts statements or googled to re-learn how to use ruby-debug instead. Definitely worth checking out.
The bad stuff
It is not free - unless you are a committer to an open-source project. But it's not expensive either.
It is a bit slower - but not that much. The performance hit is insignificant compared to the added value.
Regex file open, TextMate style - What can I say? I do miss this.
Wrap highlighted text - In TextMate, if you highlight a word and press ", [, {, ( or # it surrounds the word with the respective combination of quotes, brackets, etc... Another missed feature
Wrapping up
It's probably soon to say it but so far RubyMine has been my missing Ruby IDE. And I'm very happy with it. :)
clouds against the floods presentation available
Last Tuesday I gave a short presentation on the whole Clouds Against the Floods thing at the Ruby on Rails Oceania User Group here in Sydney.
Those guys are awesome and they recorded the talk - thanks guys!
If you'd like to download the slides, they're available on Slideshare.
Enjoy! ;)
update to appconstants it can now be used as a gem
This is just a quick post to let you know that AppConstants can now be used as gem!
Just add it to your Gemfile and 'bundle install' it:
#in your Gemfile
gem "app_constants"
#in the console
$ bundle install
$ rails generate app_constants
#then follow the instructions on-screen instructions
It can also be used without Rails. Check out full instructions on the GitHub repository.
Feedback welcome :)
clouds against the floods
I think by now everyone's heard of the hard time the guys up in Queensland, Australia are having because of the recent floods. People have lost their lives and many others have lost their homes and businesses, product of years of hard work.
As a result of this massive disaster the Queensland Government decided to run a telethon to encourage donations to help the flood victims. The Telethon aired last Sunday, 09/01/11, on Channel 9 and lasted for 2 hours.
The problem was the existing donations system that the Government had been using so far: it was just not thought out to handle the load we were expecting to have on Sunday.
That's when my employer, ThoughtWorks, kindly offered a hand to Smart Services Queensland in the attempt to make sure they could receive all donations that were likely to come through the web.
After that, on the Thursday afternoon before the event, Phillip Calçado, Ben Barnard and I set off on a mission against the clock: we had a little over 48 hours to develop, test and deploy an application that was expected to handle thousands of users. Not only that but an application that, should it fail, would prevent millions of dollars from reaching the people in need in Queensland. This was a great responsibility but we knew we could do it.
Given the time constraints it was a bit obvious that we would use Ruby on Rails for this app. Both because of the productivity it's known for and because we had the knowledge right there. With that out of the way, we had to decide how and where we would deploy this thing. We thought a little about it and came down to to 2 options: Amazon EC2 or Heroku (which is powered by Amazon EC2 under the hood). I pushed hard for Heroku and that's what we ended up going with.
Now it was time to get down and dirty and start coding the app. In principle it should be fairly simple. It needed a form where a potential donor would fill out his/her information, giving the option to receive the tax receipt by email or regular mail - more on that later. Upon clicking submit users would be taken to the secure payment gateway website where they could input their credit card number and finish the payment, after which they would be taken back to our app with a success - or an error - message and a transaction number.
Now this work flow has a couple of implications: First, all emails would have to be sent in the background so as to not interfere with the website performance. We were expecting to be sending thousands of them - workers anyone?
Second, the payment gateway integration would have to be developed and tested from scratch. Up until now the Queensland Government integrated with it in a different manner that could not be reused in this case.
And most important of all, although simple in concept, we had no idea of the load we should be preparing for. There was just no data from previous telethons. Thus we decided to prepare for the maximum we possibly could.
As we developed the application we deployed continuously to Heroku in order to test the payment gateway integration, benchmark the app using Apache AB, setup cache headers - Heroku uses Varnish - and find bottlenecks.
Email was one of these bottlenecks and that's why we decided to handle that in the background using Delayed::Jobs.
Since the first deployment, we also tweaked a couple of things at Heroku, such as migrating from their free PostgreSQL offering to a dedicated instance that we believed would both take the load and have plenty of room for all the data - as I write this post, we are already well over the 5MB limit they offer for free.
Long story short, by Saturday evening the website was up and running on 5 app instances, a 6th instance running background jobs - sending emails - and a dedicated PostgreSQL database server.
As Heroku is outside the Government network, their SMTP server was a no go on the short term so we also integrated the app with SendGrid, an email delivery service that fitted perfectly our needs - although the site got so much traction that we went over our monthly quota with them. But the nice guys from SendGrid increased our limit after I opened a ticket explaining the situation!
As for performance we used NewRelic to monitor the application, which Heroku also makes a breeze to integrate with.
We all went home to rest and get ready for Sunday, the day of the Telethon, when we would be monitoring the app throughout the day. We were all excited and when the show went live, we started seeing all those beautiful access charts moving like crazy, spiking over 720 requests per minute and being solid like a rock with flat and fast response times throughout the night.
In about two hours we had over AUD$2,000,000.00 (two million) donated through our website.
Since then the number of transactions dropped but has stayed constant and as of today we've received AUD$25,438,518.32 (over 25 millions of dollars) that will be donated to the flood victims in Queensland.
Oh, and the site is still up and going strong so move your fingers and go help: telethon.smartservice.qld.gov.au - there will be heaps of people grateful for your donation.
small update to appconstants
It's been now over a week since we moved to Sydney and everything is just great. We're still house hunting but I got a feeling we'll have a home soon. :)
In the meantime, this morning I got a feature request on github to allow AppConstants to interpret YAML files with embedded code like this:
I haven't needed it myself but thought it would be a nice addition so my latest commit does exactly that. Let me know if you find any issues.
upgrading appconstants to rails 3
Back in January I announced a small but useful plugin called AppConstants, that basically provides a central place where you can store environment specific constants. And since I started using Rails 3 in the past week, I thought I'd make it Rails 3 compatible.
The code is really simple and - as I expected - the upgrade process was quite straight forward.
I'm not gonna write a guide here on how to upgrade your plugins to Rails 3 - there is plenty about that around the web - but instead, just show the steps I went through to upgrade mine. Similar plugins might have a similar upgrade path.
- Generators
My plugin makes use of a simple generator that copies its default constants file and initializer to Rails.root/config and Rails.root/config/initializers, respectively. In Rails 2.x it was located under Rails.root/vendor/plugins/app_constants/generators/app_constants and it was defined like so:
In Rails 3, the generators had to be moved to Rails.root/vendor/plugins/app_constants/lib/generators. Notice the root directory app_constants under generators has been removed as well. And the code was changed to this:
We had three simple changes here:
- The generator now extends from Rails::Generators::Base: This class uses the Thor infrastructure to handle generators. - more info here.
- I had to implement the source_root class method, which basically tells your generator where to find your template files.
- The manifest method is now called copy_config_files - or anything you want.
The way this works is that, once you invoke the generator, Thor will sequentially call all instance methods in your generator class - or the only instance method in the example above. If your generator does a lot, it will allow for a better organization of your tasks.
And that's it! I did change a couple of other things but that had to be changed anyway and are not related to the migration.
For Rails 2.3.x users, you'll find a 2.3.x branch on github that should work for you.
Cheers
learning objective c a ruby analogy
Learning new programming languages is fun. And if it's your 2nd, 3rd...Nth programming language you will eventually look for features you already know and love.
Coming from Ruby - but after having done my fair amount of Java for many years, among other things - I end up looking for features like blocks, open classes and syntax sugar like automatic generation of attribute accessors. These are hard to let go of.
Having decided to learn Objective-C recently, I was delighted to find out that all of these are available - for better or for worse - and wanted to share this analogy with its Ruby counterparts.
- Attribute accessors
In ruby, this class definition
implements for you the getters and setters of the instance variable name.
In Objective-C, the combination of the @property and @synthesize directives provides you with roughly the same result:
Now the compiler is responsible for writing those getters/setters for you.
- Open classes & blocks
Blocks in ruby are the structures that allow you to - among other things - iterate over arrays like this:
Objective-C doesn't have an 'each' method in its root array class (NSArray) but since it does support blocks and open classes, you could just write it yourself:
Yes, I know the syntax isn't appealing, but using it in your program is a bit better:
Given the syntactic differences, the code above is very similar to its ruby counterpart. Iterating over an array is just one of the many things blocks are useful for. Others might include dealing with files, network sockets etc...
Blocks are powerful structures and are not created everyday, but it's nice to know that you can resort to them when the time comes. ;)
hacking rubys syntax
What?
In Ruby you have basically two ways of defining private methods:
I see a small problem with both approaches. In the first one, and the most obvious, is that you need to duplicate the method name as well as add an extra method call - private - just to change its visibility.
The second approach avoids this but adds the risk of accidentally putting a method that is intended to be public under the private section of the source file, which can render an annoying debugging session.
Why?
Personally, I like to have a smooth reading flow in my source files. That means that if the public method_a makes use of the private method_b, I want method_b defined right below its caller, which is possible - but verbose - using the private method call:
But can be somewhat harder to accomplish if you decide to split your source file in sections:
I wanted to be able to define a private method with a single reserved keyword...
How?
What if I could define a private method using this new syntax:
It turns out I can.
Notice the def_p keyword? This is a new keyword I created by changing ruby's parser and that behaves mostly like the def keyword, except that it defines a private method instead.
If you wanna read the code that allows this behavior and try it yourself, download the patch I wrote and apply it to the ruby source code - I patched version 1.9.1-p376.
After applying the patch, just build ruby as usual:
And then try running this script:
You should see the following output:
Happy hacking :)
managing multiple ruby versions
Today I read a nice post - in Portuguese - by Fábio Akita on how to manage multiple ruby versions on your machine. I've tried it once with some tool I can't even remember the name but failed miserably.
But this time things look very different. The tool here is the rvm - short for Ruby Version manager - and it works just great.
Let's cut to the chase and imagine that you, like me, want to run/develop/test your code on both ruby 1.8.7 and ruby 1.9.1. These steps would get you up and running in a few minutes:
Install rvm:
$ gem sources -a http://gemcutter.org/
$ gem install rvm
$ rvm-install
$ echo "if [[ ! -z $HOME/.rvm ]] ; then source $HOME/.rvm ; fi" >> ~/.bash_profile
$ source ~/.rvm/scripts/rvm
Install the ruby interpreters you want to use:
$ rvm install ruby-1.8.7-p160
$ rvm install ruby-1.9.1
Now it's important to notice that at this point you have separate gem installations for each of the interpreters you've installed in the previous step. That said, just go ahead and switch between your interpreters and use your command line scripts - ruby, gem, etc... - as usual.
Switching between interpreters:
$ rvm ruby-1.8.7-p160 #switch to the specified version
$ ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.8.0]
$ gem install rails #note I'm not using sudo since the new gem paths point to the user's home directory
$ rvm ruby-1.9.1 #switch to the specified version
$ ruby -v
ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-darwin9.8.0]
$ gem install rails #note I'm not using sudo since the new gem paths point to the user's home directory
And that's it, just go on and install rails, merb, sinatra or whatever rocks your boat!
rvm will work with MRI/YARV, JRuby, Ruby EE and Rubinius. Enjoy and don't forget to check rvm's website for the complete documentation! :)
refactoring for readability
Yesterday I've done something I should do more often: Revisit some code written a while ago for our current project and make it better.
Let's face it. We all write crappy code the 1st time. The difference is in what we do about it afterwards.
We might decide it's good enough and keep moving, or we could (and should!) stop and refactor it!
The code I revisited worked as a refactoring exercise and it's initial version is shown below:
class Jphoto
...
#a few other methods ...
def post_photo(file_data, hotel_id, send_rss, options = {})
file_name = "tmp/#{Time.now.to_i}_#{rand(1000000).to_s(36)}"
File.open(file_name, "wb") do |f|
f.puts(file_data)
end
params = [Curl::PostField.file('photo',file_name),
Curl::PostField.content('hotel', hotel_id),
Curl::PostField.content('source','PhotoUploadTest')]
extract_extra_params!(params, options)
c = Curl::Easy.new("#{service_uri_base}/photoupld")
c.multipart_form_post = true
c.http_post(*params)
if c.response_code != 200
error_msg = "File upload failed with code: #{c.response_code}"
Rails.logger.info error_msg
raise error_msg
end
File.delete(file_name)
hotel = Hotel.find_by_id(hotel_id)
hotel.cache.destroy_all
send_upload_rss(hotel, original_upload_url(c.body_str) , options) if send_rss
end
private
def send_upload_rss(hotel, photo_url, options)
...
end
def manage_images_link(hotel_id)
...
end
def extract_extra_params!(params, options)
params << Curl::PostField.content('status', options[:status]) if options[:status]
params << Curl::PostField.content('upload_source', options[:upload_source]) if options[:upload_source]
params << Curl::PostField.content('uploader_ip', options[:uploader_ip]) if options[:uploader_ip]
params << Curl::PostField.content('uploader_email', options[:uploader_email]) if options[:uploader_email]
end
end
Look at the post_photo method. It has problems in so many levels that it’s hard to start.
Methods should do “one thing” and that method obviously does much more than that, mixing different levels of abstraction.
But let’s start with the easy parts first, keeping in mind that I was aiming for readability.
Lines 7 to 10 seem to be there just to make the reader’s life harder. It’s creating a temporary file through some custom logic instead of using the tools provided by the language. Unnecessary and only pollutes our eyes. My first measure was to use ruby’s TempFile class for this. Better, but we still have a long way.
Right at line 12 it creates some sort of default parameters list, after which it extracts some extra options. I don’t know what that method does but it’s clearly using output arguments, which we should avoid at all costs, as they lead to confusion. This is a big smell as well, and another refactoring step added to my list.
On line 21 starts the code that handles what to do when we get a response_code other than 200 from our request. Apart from the fact that this code doesn’t feel right here, we just happen to know that in HTTP, 200 means success, but that might not be clear to someone looking at the code for the 1st time.
Then the code goes on to delete the temp file, clear the hotel’s cache and send the rss if the rss’ flag is true.
Let there be refactoring….
Geez, how many lines have I used to explain what the code does? Since I don’t wanna bore you to death, here is my refactored version of this method, trying to avoid as much as I can the problems I highlighted previously:
rails summit 2009 im speaking
I'll be speaking at this year's Rails Summit Latin America in Sao Paulo, Brazil. It will be a good opportunity to meet some amazing people and visit friends back home! :)
Overall I'll be spending 12 days in Brazil, with 2 of them dedicated to the conference. The other 10 I'll be in Rio de Janeiro visiting my family and friends. I strongly advise you to spend some time in Rio too, if at all possible. It's an amazing city and you can contact me if you have any questions.
Back to the conference, my session is called JRuby in the enterprise world: Using Rails with legacy code, and will be given in the form of a tutorial. I will walk you through some problems we had while making this kind of integration at my company, focusing mostly on dependency management.
At the end I hope you'll have a good understanding of what JRuby is capable of in a legacy environment.
If you're planning to attend and would like to hear anything specific about JRuby, please let me know, I can try and squeeze in.
C u there!
rails rumble 09
Update: The service is now down while we move it from the VPS provided by Rails Rumble to our own. I'll let you know once it's up.
Last weekend Philip, Pedro and myself got together for this year's Rails Rumble.
We haven't had really decided what to do until a few days before the competition, but I had this really simple idea and decided to go with it. Seems people liked it, given a few positive comments we received.
So, after 48 hours - which were not used to work full-time in the application - The Bird Watcher was born.
The Bird Watcher is a simple way to show the world what's going on on Twitter for any topic you define. Go ahead and take a look at the website to see a live example.
We're planning to keep the service up after the competition is over and we have some nice features lined up to go live on the next release.
In short, it was an interesting weekend and showed me that this team works really well together.
Cheers
jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
procs lambdas blocks whats the difference
Do you know?
I didn't. And started to get annoyed by using these terms interchangeably and not really knowing the difference.
There are a few. And they are subtle. I don't think most of us would ever have problems with it but it's the kind of information you'll be glad to know when having those weird behaviors in your code on a Friday at 6:01 pm, just before pushing to production. :)
I guess blocks are the most widely used term in the ruby community and there is little mistake on when to use it:
[1,2,3].each do |x|
puts x*2
end
The code between do and end is a block.
What's important to keep in mind is that Procs behave like blocks whereas lambdas behave like methods. To understand what that means, I highlighted a couple of examples:
- The return keyword
I mentioned Procs behave just like blocks and as such, the return keyword abide to the same rules. This means, for instance, that the latest puts statement on the following code snippet, will never run:
def my_proc(x)
p = Proc.new { puts x*2; return }
p.call
puts "After calling proc" #This never gets called
end
my_proc(10)
>>20
For blocks - and procs-, return means "return from the calling method", my_proc in this case. That's why you don't get to see the output of the puts statement.
On the other hand, in the lambda's example, we get the opposite behavior:
def my_lambda(x)
p = lambda { puts x*2; return }
p.call
puts "After calling proc" #This time, we reach this point
end
my_lambda(10)
>>20
>>After calling proc
Here, return says "return from the enclosing iterator", which, in this case, just returns from the block and continnues the execution of the my_lambda method.
- Argument assignment
On to this second difference, procs and lambdas get more interesting when you can call them with arguments. And that's when another subtle difference between them comes in.
I'll start again with a proc:
p = Proc.new { |x,y| puts x, y}
p.call
>>nil
>>nil
p.call(1)
>>1
>>nil
p.call(1,2)
>>1
>>2
p.call(1,2,3)
>>1
>>2
p.call([1,2])
>>1
>>2
See how procs are flexible? They basically won't complain if you do not provide parameters, provide extra parameters or even send an array as an argument where, as seen in the code above, it unpacks the array and assign its values to the correct variables.
As you're probably guessing, lambdas behave like methods and are much less flexible:
l = lambda { |x,y| puts x, y}
l.call
>>ArgumentError: wrong number of arguments (0 for 2)
l.call(1)
>>ArgumentError: wrong number of arguments (1 for 2)
l.call(1,2)
>>1
>>2
l.call(1,2,3)
>>ArgumentError: wrong number of arguments (3 for 2)
l.call([1,2])
>>ArgumentError: wrong number of arguments (1 for 2)
Ruby 1.9 tip
Despite its name, Kernel.proc returns a lambda in Ruby 1.8. This has been fixed in Ruby 1.9. You actually get a Proc back.
- Reference
The Ruby Programming Language
helping the jruby effort debugging the source
Wanna help improve JRuby? Make sure you read this post by Charles Nutter first. There he explains how to run Ruby specs with JRuby.
Start with fixing Ruby specs is a great way to get acquainted with the code. And it’s also a important task in order to make sure JRuby is the most complete and compatible ruby implementation out there.
But before you get your hands dirty, it will be a lot easier if you can actually debug JRuby’s source while fixing any specs - or bugs/features for that matter.
railswaycon jruby internals by ola bini
As always I expected a good talk from Ola and once more he delivered it. But this one was different. It might have been even boring to some ruby developers since we saw a fair amount of java code in this presentation. Ola gave us a tour through the main classes that make JRuby possible with a single purpose: so we can check out the code and hack ourselves. You can download his slides here.
If you've been following both JRuby and Ola Bini for the past year or so, you've noticed the trend and evolution of this alternative - and so far the most complete one - implementation of the ruby language. Specially at conferences.
Last year at QCon London, Ola was also talking about JRuby. At Euruko '08, in Prague, Charles Nutter also talked about it. RailsConf in Berlin also had its share. What all these talks had in common is that they talked about JRuby from a user/developer point of view. They were selling the solution. Convincing people to use it and presenting successful use cases.
And as the trend goes on, JRuby is now faced as a true alternative - one that we, btw, believe here at the company as we're actively using it - and it seems that now the call is for help. Help to make JRuby an even more complete and overall better ruby implementation. Charles' call for help was a great step. As he states, it's a good way to get your feet wet. I answered the call and am hacking JRuby myself, having already submitted a couple of patches. Perhaps this was the reason for which I enjoyed the talk the most. I was already familiar with some of the structure and classes in JRuby.
There were 2 more talks about JRuby: The Pleasure and Pain of Migrating to jRuby, by Steven Bristol and Integrating Enterprise Java with JRuby and Rails, Michael Johann. Unfortunately only the first one was a real case experience, where Steven walked through the problems he faced integrating JRuby with an existing java project. Interesting insights.
Michael Johann basically presented a short tutorial on how to integrate rails with EJB3 which, albeit interesting, failed to address issues faced on real life projects, like dependency management. Issues which we have already addressed in a very cool way here and I plan to share it soon. Still deciding how though...
rails readable test names run individual tests from the console
As you probably know, since rails 2.1 you can write test methods in the following format:
test "hotel should return its permalink" do
#your test code here
end
Which is great, as the test name becomes much more clear. But you can't simply run this test easily from the command line. You'd have to run something like:
$ ruby your_test_file.rb -n test_hotel_should_return_its_permalink
It annoys me. And it's not practical either to make the test fail just so you can get the test's real name.
I wanted to be able to just copy and paste the readable name in the console and have Test::Unit do the conversion and run it for me, like this:
$ ruby your_test_file.rb -n "hotel should return its permalink"
So I created readable_test_names_runner. It's a tiny rails plugin that adds this feature for you.
Enjoy.
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. :)
understanding ruby threads
This post is just to clarify some confusion I've noticed reading some posts around the web. There is some misunderstanding of the differences between Ruby 1.8 and Ruby 1.9 regarding threads. And the difference between them and JRuby.
So I decided to write this small summary:
Ruby 1.8 - Supports only Green Threads
This means that the ruby interpreter has its own scheduler. No matter how many threads you create in your ruby program, there will be only one native thread on your OS. Therefore, your program cannot take advantage of multiple core environments.
Ruby 1.9 - Supports native threads (GIL)
Ruby 1.9 adopted YARV as the new VM implementation, which supports native threads. This means that now your ruby programs can take advantage of multiple core environments, but no truly parallel execution is achieved.
The catch is GIL - Global Interpreter Lock - and it means that each ruby thread runs on its own native thread, but only one of them can be executed at a time.
JRuby - Ruby 1.8 compatible
I think this is the easy part. JRuby runs on the Java VM, which supports native threads and parallel execution.
On this environment, ruby threads are java threads.
The future
There doesn't seem to be any decision about what's gonna happen on the next versions of Ruby. At least to the extent of my research. But this is today's snapshot of Ruby threads and I hope it'll be useful to some folks.
c u around
dont use rexml i mean it
REXML is the standard XML processing library for Ruby. It's on Ruby's core and is terribly slow.
Yeah, I know it's pretty simple to use, got a nice interface and, again, it's just there. And it is a good library, for most things. But if you, as me, came to a point that processing XML is taking 50% of the time to render a rails action, it's time to change.
My tip? Use libxml instead. The numbers on their home page speak for themselves. Try it yourself, you won't be disappointed. And I'm really happy with the performance increase on our app.
railsconf europe 2008 impressions and highlights
I'm back in Madrid again after the RailsConf and I think it's time to say something about it. :)
First off, the infrastructure provided by the conference was really great. The rooms, WiFi connection, food... Really well organized.
Now to the sessions, highlights:
Tutorials (Tuesday)
- Meta-programming Ruby for fun and profit (Neal Ford, Patrick Farley)
The old and good techniques that made Ruby so powerful. Here Neal and Patrick walked us through the main tricks to meta programming like open classes - and conditionally open them - , dynamically define methods, sending messages to objects and how Ruby can help test your Java code in a much easier way.
I've put the link to the slides but honestly I don't think they're too much useful without the talking.
Sessions (Wednessday)
- EC2, MapReduce and Distributed processing (Jonathan Dahl)
Jonathan explained the theory behind MapReduce using very simple ruby examples, providing the basics on how to distribute and paralelize tasks accross multiple machines.
He also introduced Hadoop, a platform built in Java that "lets one easily write and run applications that process vast amounts of data". What I liked the most was the simplicity he explained this subject. As of today, his presentation is not available online. Stay tuned as I'm gonna update this post with the links, as soon as they're available.
Sessions (Thursday)
- Debugging & Testing the Web Tier (Neal Ford)
If you've been concerned about testing your app's web tier lately, this presentation would probably not show you anything new. Neal talks about the need to debug and test javascript behaviour accross multiple browsers, using tools like Firebug, JSUnit and Selenium. If you have no idea about what these tools are, please stop now and go evaluate them!
We are pretty concerned about testing on my actual job, but selenium tests can be a pain sometimes - a.k.a extremely slow. And what ends up happening is that they are forgotten. Developers only run the test suite if it's not painful and it's lightning fast. Here's is where the highlight for this session comes: CrossCheck.
The idea is to be able to test your javascript code accross multiple browsers without the need to launch them. In fact, you don't even need a browser installed. The negative point is that it's kinda fallen behind because now you can only test older versions of browsers. But since the project is getting a lot of traction, I'm pretty sure this will be solved soon.
Conclusion
My overall impression of the other sessions I attended is that some speakers just didn't have time to properly prepare themselves, what made me think this years's RailsConf wasn't all that I expected.
But I also met interesting people and after all one of the key points in a conference is networking. :)
Definitely worth it though. And that's why I took the time to provide this highlights.
c u soon
railsconf europe 2008 heading to berlin
The title says it already.
On monday I'll be going to Berlin to attend this year´s RailsConf.
This will be my first one and of course my expectations are pretty high!
As usual, after the conference I'll try and give a summary of what happened there, providing as much content as I can.
Anyone else's going??? :)
C u there!
mac os x getting mysql and rails to work
So I couldn't resist and bought myself a MacBook Pro! It's my first week with my new toy and I'm really enjoying it.
But I need to do something useful with it so I started to prepare it to be my new development platform, starting with Ruby/Rails + MySQL: Here is where the fun begins!
After I installed both Rails and MySQL, I fired up a terminal an typed:
sudo gem install mysql
...and here is what u get
ERROR: Failed to build gem native extension.
If you google this error you will find a couple solutions and this is the one that worked for me:
ARCHFLAGS="-Os -arch x86_64 -fno-common"
sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
--with-mysql-config=/usr/local/mysql/bin/mysql_config
Now, confident enough, I created a sample rails app and tried to create the development database:
leo$ rake db:create (in /Users/leo/projects/test)
dyld: lazy symbol binding failed: Symbol not found: _mysql_init
Doesn't look happy yet huh? This took me a while to figure out but it turned out to be fairly simple.
I have no idea why but after I installed the gem I had the file mysql.bundle in two different places:
/Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
/Library/Ruby/Gems/1.8/gems/mysql-2.7/mysql.bundle
The solution was to remove the first copy of the file. Now everything is working fine at this end!
I really hope this is useful to someone!
rails vulnerability on rexml
REXML, the XML library uses by many ruby apps, including rails, has a vulnerability that requires an immediate patch on whatever rails version you're using.
Details and instructions on the official rails weblog, here.
But basically, this is what you need to do:
gem install rexml-expansion-fix
Then, require rexml-expansion-fix in your rails's app environment.rb file.
why i like ruby 1 alias_method
So you found yourself in the need to override a method but still count on it's old behaviour?
No problem! Override it with your new code, call super and.... Uh oh!! Suddenly this turned into a problem... Let me give some more context.
I was testing Ferret (and the acts_as_ferret plugin) in a project to provide full text search capabilities to our models. One of the things the plugin does is to add a new method to ActiveRecord, called find_with_ferret. That way, every model can use it. Great!
So I thought that would make sense for me to remove all diatrictics from the input text before letting ferret do its job. You know, like removing umlauts and all that.
I could do that by overriding this method with code to remove the undesired chars and then call its older version to finally do the search - something like calling super, but not quite. And I didn't want my models to inherit from anything else than ActiveRecord::Base. That wouldn't make any sense.
alias_method to the rescue!
You know that to redefine a method in an existing class you can open it up and rewrite it. But since you don't wanna loose the behaviour provided by the original method, this is how you can achieve this:
module ActiveRecord
class Base
alias_method :find_with_ferret_original, :find_with_ferret
def find_with_ferret(q, options = {}, find_options = {})
remove_diatrictics!(q)
find_with_ferret_original(q, options, find_options)
end
end
end
And you're good to go. On line 3 you're just giving the original method an alias, making a copy of it.
Then you redefine it the way you like and on line 6 you call the old version to make sure u still got the same behaviour.
Now all my models can benefit of this change without requiring them to call another method nor inherit from another class.
Cool, huh? :)
the biggest rails event in latin america
Behold latin american railers!
This year we will have the Rails Summit Latin America on October, 15th and 16th, in São Paulo, Brazil.
It's by far the biggest Rails event we've ever had, including many of the speakers that were present at RailsConf.
Fábio Akita is also one of the speakers and provides more details on his blog.
If you're a assumed rails geek don't miss the opportunity to hear from the big names and to know a beautiful country like Brazil.
Oh, btw, if you're brazilian, like me, you have no excuse to miss this party!
Enjoy!!!
passenger mod_rails and problems with custom apache installation
This week we started to test mod_rails in a couple of projects where I work on. One in production.
Of course it's too early for any conclusions, but I just wanted to share a couple of problems you might find when the installer tries to compile the Apache module.
In our case, and I believe it is the case of many servers out there, we have a custom Apache installation, what makes the installer not find it and/or not find the Apache Portable Runtime (APR) sometimes.
The first one is easy and is documented here. You just seed to export the following environment variable, pointing to your apache installation:
export APXS2=/opt/apache2/bin/apxs
The second one is a bit tricky but it happened only when I tried to install passenger in another server that had CentOS. In this case, you will also need the following environment variable, pointing to your Apache APR config:
export APR_CONFIG=/usr/local/apache2/bin/apr-1-config
It took me a fair amount of time googling around to find this answer, so I hope it'll be useful for someone. :)
euruko 2008 materials available
As some of you know I went to the European Ruby Conf in Prague, this year.
The event was awesome and it's good to know they finally made available the majority of the slides, here.
They also published Matz's keynote, and more videos from the conference are being edited right now, so stay tuned to their home page!
Enjoy!
a couple of things from here
It's been some time since my last post but here I am! Where? In Spain, of course! Having a great time, I must say.
I arrived last week in Madrid and the past 2 weeks before that I spent basically packing my stuff. There is still some paperwork going on but everything is flowing well.
Besides this little feedback, I was reading this week's issue of the excellent series This Week In Ruby, from my friend Antonio Cangiano. I found something quite interesting, a plugin called HoboFields.
One of the things that bothers me in rails is the fact that by looking at your model classes, you can't tell the fields you have there. Sure, you can look at the migration script. Yeah, you can also load the development environment and inspect the object. It's a pain in the @zz! But this is the way ActiveRecord works...
Other ORM solutions like DataMapper, allows you to define the fields directly in the class. It's a much cleaner and clear way to maintain your models. And you get to know what properties you have just by looking at your classes.
That's exactly what HoboFields adds to ActiveRecord.
You define your properties and its types straight into your model class, and the plugin creates the migration scripts for you. Coming from a java world my self, I find it rather interesting, useful and it also reminds me of the way Hibernate works. You define your mappings with anotations in your class and hibernate just generate the schemas from there.
It's worth a try.
passengermod_rails released
Passenger(mod_rails) has been released.
The idea is to ease the pain on rails applications deployment. I tested myself and in less than five minutes I had my application working behind Apache!
I'm not going to say much here besides the fact that it seems like a really good option for rails deployment and people have been talking about it already, including DHH.
But I do recommend a read on the architecture overview document. Be sure to read it all, specially the part on handling concurrent requests.
To install, "it doesn't get easier than" that.
Good job guys.
jruby db2 xquery bug
Update: Follow up link to this issue on JRuby's Jira, here
As I told in my last post, it was time to give JRuby a serious try. So I took one of our rails projects at work and decided to migrate it to JRuby and see what happens.
We heavily use the XML capabilities of DB2 and this was a huge problem. Every query would work just fine through the activerecord-jdbc-adapter - part of the JRuby Extras . But every Xquery would gracefully fail!
After some debugging I got stuck and decided to get JRuby and activerecord-jdbc-adapter's source to see what was happening.
As I could see, it has a bug -in my opinion - at the java part of the code. The jdbc-adapter is a bridge to allow Active Record to talk with databases through native JDBC drivers, so it's normal that we do have a java part here. At this point, what the code does is to inspect the sql statement sent from ruby and decide if it's a select, update or insert.
I fixed the problem and submitted a patch to rubyforge. I'm not sure if it's the best solution or not, but now I got the xQueries working just fine.
I'd love to hear from people with similar environments whether this patch works for you or not. I'm sure I didn't try every possibility.
If you wanna try it, just drop me a message (e-mail in the About page) and I can send the pre-compiled jar file - for activerecord-jdbc-0.8
You can also just check out the code and compile yourself. ;)
qcon 2008 slides available
Most of last QCon's presentations are available for download here.
Highlights to Ola Bini's on JRuby(pdf) and Randy Shoup's on eBay's architectural principles(pdf).
And while we're talking about JRuby, it's impressive how it's becoming a recurrent and big subject. Fast. It had its own small space at big event like QCon and in the last Euruko in Prague, we had a presentation by the JRuby Core Developers Charles Nutter and Thomas Enebo.
Big companies are sponsoring JRuby's development indirectly or directly, like Sun. And other big companies are endorsing its production ready state, like Oracle, which has a publicly available website developed with JRuby On Rails.
It's past the time to give it a serious try...
why i like ruby or ruby the language of the lazy programmer
This is quite funny. A friend, Perl addicted, is now learning Ruby. He really enjoys the language but made a interesting observation: Ruby is a language for lazy programmers!
Well, I have to agree... You know, I love saving keystrokes and achieving more by writing less. And this is so true with Ruby.
Let me give a really simple example, comparing with java - don't get me wrong... I love java, specially the platform, but it fits well here since I've always been a Java guy.
Imagine you have a Phone class with the attributes number and type, which can indicate whether the phone is a land line or a mobile phone. Then you got an array filled with phone classes and you want to narrow it by creating a new array only with mobile phones.
In Java, such a class could look very much like this:
public class Phone {
private String number;
private String type;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Quite simple, isn't it? But we are telling the compiler many things we actually shouldn't need to. This class is a java bean and as such, among other things, it needs a pair of getters and setters for each of its attributes.
Now, on with our example, the same class, in ruby, looks like this:
class Phone
attr_accessor :number, :type
end
Yeah, I know the feeling. This class has exactly what we need: the two attributes with its own pairs of getters and setters each. But we didn't need to inform it in the verbose way Java has teached us. Cleaner, period.
Now to the code that actually returns the new array containing only mobile numbers. In java, we can do it in two different ways.
Using an ArrayList:
//Create two phone objects, one land line and one mobile
...
// Add them to an array
ArrayListphones = new ArrayList ();
phones.add(land);
phones.add(mobile);
//Return an array only with mobile numbers:
private static ArrayListselectMobilePhones(ArrayList phones) {
ArrayList<Phone> mobiles = new ArrayList<Phone>();
for (Phone phone : phones) {
if (phone.getType().equals("mobile")) {
mobiles.add(phone);
}
}
return mobiles;
}
Or using ordinary arrays:
// Assume the same phone objects here
...
//Add them to the array
Phone[] phones = new Phone[]{land, mobile};
//Return an array only with mobile numbers:
Phone[] mobiles = new Phone[a.length];
for (int i = 0; i < a.length; i++) {
if (a[i].getType().equals("mobile")) {
mobiles[i] = a[i];
}
}
And you're good to go. Actually this code with an ArrayList here only looks good thanks to generics. But this is another matter. Let's take a look at the ruby code that accomplishes de same task:
//Create two phone objects, one land line and one mobile
...
//Add them to an array
phones = [land, mobile]
//Return an array only with mobile numbers:
mobiles = phones.select { |phone|
phone.type == "mobile"
}
See the difference? Java is a great language but too verbose at times. This is a really simple example but if you take the same principle to a bigger app... yeah, you see where I'm going.
The bottom line... Ruby may be the language of the lazy programmer, as my friend pointed out. But I don't mind being called lazy as long as I can type less and be more productive. Do you? :)
euruko 2008 european rubyconf prague
On friday I'll be heading Prague for the European RubyConf.
Anyone is going? :)
Almost 300 attendees already registered for the event. And a few very interesting people will be speaking there like Matz and DHH (this one, through skype).
Besides that, the organization staff is scheduling 2 parties, friday and saturday, for the attendees.
Networking comes to mind, doesn't it? I think it will be a great opportunity to meet interesting and bright people.
So, see u in Prague!
qcon 2008 domain specific languages
Today was the first day of the conference and it started with a tutorial about DSL's with Martin Fowler, Neal Ford and Rebecca Parsons. We also had as attendants Ola Bini, core developer of JRuby, and others. My expectations were pretty high and the presentation didn't let me down. I'll try to put here toghether my impressions and some notes I took while I was there.
Marting Fowler started discussing what DSL's are and giving some examples that many of us use in our day to day Job. Like the XML configuration files in the Java world. It is a kind of DSL, it has it's own keywords and syntax in order to express some information that will be used , for instance, to configure an underlying framework.
The problem with XML is that it becomes hard to see the overall behavior behind it. It's not very fluent to understand the purpose of an XML file just by looking at it for the first time. There is too much "noise". Things that get into the way of the readability. - YAML files are an much more readable alternatives to XML.
The same happens with a standard framework api code. Let's take for instance a sample API configuration code written in Java to tackle the domain of hotel reservations. A framework like this could have the following implementation:
HotelService hotelService = new HotelService();
PersonService personService = new HotelService();
Hotel hotel = hotelService.findById(1);
Person guest = personService.findById(10) ;
Reservation reservation = new Reservation() ;
reservation.setFrom("2008-03-10") ;
reservation.setTo("2008-03-14");
reservation.setGuests(new Person[]{guest});
hotelService.book(hotel, reservation);
Of course implementations of this simple example may vary but we can see here some of the readability problems. One approach we could use for that is to develop a Fluent Interface to wrap this API. This was one of the techniques explored during the tutorial and the actual fluent interface could now look somewhat similar with this:
new Hotel(1)
.book()
.forGuests({
person.find(10)
})
.rooms(1)
.from("2008-03-10")
.to("2008-03-10");
Much more readable, huh? One of the main benefits of using DSL's they highlighted in the tutorial is the simplicity of code you can achieve. You can actually show this code to a business person and he can understand it. This is a kind of internal DSL.
But there is still a bit of noise in this code. The the parenthesis which are not always desirable, and the use of double quotes for dates. But, this is Java code, and Java doesn't give too much room for you on the DSL subject. Here was when the speakers changed their focus a bit to Ruby. It's dynamic nature and metaprogramming techniques provides a powerful flexibility that allows for a looser syntax.
So in ruby the previous interface could look like this now:
Hotel.find(1) .book(1.room).forGuests {
Person.find(10)
}.from(march.10.2008).to(march.10.2008)
We got rid of the double quotes and the code looks more fluent, like a normal english sentence. I doubt a business guy woudn't understand what this code is doing. With this, we can get closer to the business guys, with a common vocabulary, and fill the gap between us.
This is just one of the ways we could have written this code and is not the actual example used in the tutorial. The syntax also really depends on how readable you wanna make your code. I'll provide those later when they release the digital format of the presentation.
So one of the flows that the development of an internal DSL can get is to build a framework and define the DSL on top of it. But we should also keep in mind that DSL's shouldn't be general purpose programming languages. They should be created to tackle a specific kind of domain problem, so we would have a whole system made of small DSL's.
Another interesting subject that was touched is testing. How do you test DSL's?
The suggested approach, and that I think is quite reasonable, is to have separate tests for the underlying framework and another to test the DSL and its parser you can assure you have the expected behaviour of both parts.
This is really just a summary of my thoughts and of what happened there. I'm not going into too much details right now but if you found something too abstract - and it is! ;) - feel free to ask details. I'll be more than happy to help.
This is definetly an interesting subject and now I'll head to play more with all that. :)
PS; This is not the whole presentation, just the best of it from my stand point. Other subjects include External DSL's which can actually involve you coding Lexers, Parsers and Compilers. It's usually not worth the hassle. And it's too complicated anyway, that's why I left it out from this post.
openid
I think I've been really lucky lately. In my new job I'm getting to work with many interesting things and OpenID is just one of them.
We are investing high in Ruby on Rails and we have now a few internal applications in development stages. Our manager wanted the ability to let people log in to our rails applications(for now) using their OpenID accounts.
It was a funny task, as I knew very little about OpenID. The idea actually is really good. Instead of creating a new user account on each new service/site you'd like to subscribe to, you create a single user account in a OpenID provider - like MyOpenID - and use this identity to authenticate yourself in the services/sites that support this protocol.
What do we earn from that? Well, in my opinion, we can get a couple of benefits:
- You don't need to memorize 723 logins and 723 passwords (if you really care about creating different passwords for all of your user accounts)
- You don't authenticate yourself to the service you're attempting to use. This service actually asks to your provider if your identity is valid, and you authenticate yourself there. Nowhere else.
I strongly recommend you visit the OpenID to understand more about it.
But, back to the problem, we needed to put it working in a rails app. And that's when I found the ruby-openid library, provided by OpenID Enabled.
It is a complete library, really well documented that provides an abstraction layer both for consumer and server applications.
My first step was to develop the consumer. That's what you need if you are going to provide your users with OpenID authentication in your web site. The ruby-openid library comes with several samples that really helped me out here. They were developed using Ruby On Rails and are a really good start point.
After this step, I was asked to evaluate the possibility of being a OpenID provider. At first I thought it would be a really complicated task, but again this ruby library had a great example of a simple provider. The drawback is that the samples were developed in an older version of Rails ( < 2.x ) . So I had to freeze the Rails version to 1.2.5 so I could run the provider sample code.
I am now working on porting this code to Rails 2.x, into one of our applications and it's been flowing well so far. Just wanted to share this library for those of you trying something similar. It is really worth a look.
rails 20 xml data type and db2
[2008/04/30] Update: The ibm_db gem has been updated to support the new Rails 2.0 style migration. Now you can just use t.xml and it will work. Look here for more info. Thanks to Mario Briggs for pointing me to the update.
---
In my new job we work with XML data natively stored on DB2. I have done some test with Rails and DB2 a few weeks ago and it's pretty interesting, specially the easiness that Rails deals with XML.
We decided to test some new features of DB2 9.5 and I decided to test them with Rails 2.0.
So I created a new Rails app, configured the database.yml to use the idm_db gem and fired:$ rake db:create
The output is nice but, the database isn't there! I suppose it's something with the gem that needs to be updated. But really don't know about it. It just doesn't work. But this will not hold us down. I will just create the database by hand and keep going with my tests.
After that, I created a new model XmlDocument, which has a column named data, of type XML. According to the new migrations syntax, my model's migration would look something similar with this:class CreateXmlDocuments < ActiveRecord::Migration
def self.up
create_table :xml_documents do |t|
t.xml :data
t.timestamps
end
end
def self.down
drop_table :xml_documents
end
end
Right? Ok, I fired up a terminal and lauched:$ rake db:migrate
The output? Here it is:== 3 CreateXmlDocuments: migrating ============================================
-- create_table(:xml_documents)
rake aborted!
undefined method `xml' for #
Yes, a big nice exception! The new migration syntax doesn't allow you to do t.xml! But please don't ask me why! :p
The solution? Well, although it's weird - imo - , it's also easy. You can mix the new and the old syntax in the same file. So our model's migration will now look like this:class CreateXmlDocuments < ActiveRecord::Migration
def self.up
create_table :xml_documents do |t|
t.column :data, :xml
t.timestamps
end
end
def self.down
drop_table :xml_documents
end
end
And that's it! We're ready to go! I didn't find anything else different so far, besides what I described here. Hope this helps!
rails 20 scaffold
Following the Rails 2.0 hype, I've been playing around with it and decided to share a first impression: Scaffolding is gone!
But wait, before you knock your head against the wall, let me tell you something: I lied :)
Scaffolding is not really gone. It's just changed a bit.
How can I tell? Well, as a good developer I thought: "I'll just create a scaffold with the new version and see what's different"
I fired up a terminal, created a news rails application and generated a new model:$ script/generate model Contact name:string email:string
- yes you can do this in rails 2.0, and these fields get into your model's migration!
Now the I have a new model, it's time for a controller to manage it:$ script/generate controller Contacts
So your controller would look something like this huh?class ContactsController < ApplicationController
scaffold :contact
end
Well, too bad! The method scaffold is gone from ActionController::Base! And I'm not lying this time!
Now that the dynamic scaffold is gone, we're left with the static one.
Ok, let's try it then:$ script/generate scaffold contact
And it won't work again! ;) At the end of the output, you will get something like this:Another migration is already named create_contacts: db/migrate/001_create_contacts.rb
It really means that if your model is meant to be used by a scaffold, you better generate it in the same line. It will fail, afaik, if the model previously existed. Destroy yout model and controller, and execute the following:$ script/generate scaffold Contact name:string email:string
Done! Just run your migrations, startup your server and your new scaffold in rails 2.0 will be working gracefully!
It took me a while to discover this changes because I didn't find it well documented. But maybe I was not looking in the right places. :)
rubyworks production stack for rails
Well, we all know how hard, or at least cumbersome, it can be to set up a production environment to deploy your applications. Besides all the hardware stuff like storages, links, routers you are still left with a huge amount of software configuration to handle. This often includes configuring things like clusters, load balancing and services monitoring - Including notification of interested parts in case of any failure. Pieces of software you have to tie up and make them work together.
But hey, ruby lovers, you may have a better way to get this going! Released by ThoughtWorks, RubyWorks is, as quoted from their website, a production application stack for Ruby On Rails applications. I decided to give it a try and I really enjoyed it.
First of all I didn't want to mess with my actual configuration so I installed a new vm with Virtual Box. It has Ubuntu 7.10 on it, with 256MB of memory.
After installing RubyWorks - instructions on their website -, you get a new skeleton rails app up and running, being served by 4 mongrels that defaults to production environment! Impressed? There is more. A HAProxy is also set up in front of your mongrel servers acting as a load balancer.
Well, you probably want to monitor all that stuff huh? A monit web interface is waiting for your call on port 2812! It monitors all your mongrel servers - four by default - and your HAProxy, allowing you to measure CPU and Memory usage, among other things.
The coolest thing here is that all these softwares you would have to setup by hand are already working together, ready for production! Well, is it?
Going a little deeper, I deployed a database backed application to test this stack's performance.
I used Siege to stress the app and I am very happy with the results! I compared it with a single mongrel running on production env and no proxy at all.
It is worth mentioning that having 4 mongrels running took my vm to 77% of memory usage, while a single mongrel took it to 38%.
ruby on db2 a linux nightmare with a happy end
Although the title might look dramatic, it's pretty close to what I've been through.
I have set up a Ubuntu 64 bits on my laptop last week to do some tests with Ruby and DB2. Oh man, it is not complicated, is it? It shouldn't be, actually.
Too sad that I found this so late! It's a post from a friend, Antonio Cangiano, describing the most common problems you may find trying to set up this environment (Linux + Ruby + DB2). You will probably get it working the first time, if you read it word by word. But if not, here are some extra tips that I can share with you.
- If you installed Ruby using your distribution's package manager, remove all ruby packages completely. After that, install ruby exactly as described in Antonio's post, typing this in the console:
$ sudo apt-get install build-essential
$ sudo apt-get install ruby-full rubygems
After that, you may try again.
- Another problem I found was after getting the driver built. I have written a simple program to try the connection and got this message:
Failed to load IBM_DB Ruby Driver
The thing is that this error really means it was not able to find the file libdb2.so.1 in the /usr/lib directory. Issuing this command may settle things for you - it will create the missing symbolic link:
$ ln -s /opt/ibm/db2/V9.5/lib64/libdb2.so.1 /usr/lib
Good luck!
Tag: Twitter
look ma no hands tweeting with your voice
This is just another one of those boring weekends where I felt the need to hack on something.
If you follow Google Chrome's blog you're probably aware of this little nifty feature they started to implement in their latest builds: HTML5 voice recognition.
And that's when it struck me: "Hey, what if I use that and tweet with my voice instead of typing?"
The result of this hacking session is LoudParrot, a sample Rails app that shows how to do just that. You will need a fairly recent build of Google Chrome -beta - which you can download here.
You can get the source on GitHub.
Tag: Javascript
simplejquery daterange picker
As in many web apps out there, this week I needed a date range picker. I shopped around and while I did find a couple of good options they were (a) too clunky and (b) didn't prevent you from selecting invalid ranges. The latter being the one I was really interested in.
So I coded up something simple that worked and looked nice and decided to share around. It's the jquery-daterange-picker. Its only dependencies are jQuery and jQueryUI's datepicker.
Got get it, fork it, contribute to it or check out some examples.
are_you_testing_your_javascript_yet
What's the difference between your application's javascript code and its java/ruby/python/whatever code?
Think about it for a second. Done? Well, the answer is: none!
In today's web applications your javascript code is no different from the rest of your code base but yet we treat it with disregard - and we're all to blame.
We often see developers investing time writing all sorts of automated tests around their code base but fail to do the same for their javascript - and yet they get surprised when their client can't click on a button on their web app that depends on that ajax call that has been manually tested once when the page was first released.
Ask yourself this question if you're not sure if you should be testing your javascript: If it breaks, can my users still benefit from my app? - I think the answer for most web apps is obvious.
As for tools, I can only speak of two, JsTestDriver and screw-unit, the latter being the one we're using in my current project at ThoughtWorks.
What I liked about screw-unit is that it's very easy to get it up and running. Being a Behavior-Driven Testing Framework it's not surprising it has a syntax similar to Rspec -which I prefer over JsTestDriver's similarity to JUnit's.
This is how a test written with screw-unit could look like:
Not too bad for a javascript test suite huh?
So the next time you write a javascript line of code, how about writing a test for it? Consider using screw-unit as your tool but if you have been writing tests using a different framework and you're happy with it, share your experience.
I'm always keen to learn better ways of doing what I do.
Cheers!
Tag: Objective-C
rottingnames for iphone available for free
Following the staggering success of the online version of RottingNames - where by success I mean the handful of metal heads constantly using the app :) - I released the iPhone version for free . You can now generate crazy and fun names anywhere! Go get it!
I've been meaning to post this for a while but I was waiting to have some free time and add a few new features to the app, which I just realised won't happen any time soon given the priorities I have at the moment. But by all means feel free to drop a line if you're dying about a missing feature.
Now go have fun ;)
learning objective c a ruby analogy
Learning new programming languages is fun. And if it's your 2nd, 3rd...Nth programming language you will eventually look for features you already know and love.
Coming from Ruby - but after having done my fair amount of Java for many years, among other things - I end up looking for features like blocks, open classes and syntax sugar like automatic generation of attribute accessors. These are hard to let go of.
Having decided to learn Objective-C recently, I was delighted to find out that all of these are available - for better or for worse - and wanted to share this analogy with its Ruby counterparts.
- Attribute accessors
In ruby, this class definition
implements for you the getters and setters of the instance variable name.
In Objective-C, the combination of the @property and @synthesize directives provides you with roughly the same result:
Now the compiler is responsible for writing those getters/setters for you.
- Open classes & blocks
Blocks in ruby are the structures that allow you to - among other things - iterate over arrays like this:
Objective-C doesn't have an 'each' method in its root array class (NSArray) but since it does support blocks and open classes, you could just write it yourself:
Yes, I know the syntax isn't appealing, but using it in your program is a bit better:
Given the syntactic differences, the code above is very similar to its ruby counterpart. Iterating over an array is just one of the many things blocks are useful for. Others might include dealing with files, network sockets etc...
Blocks are powerful structures and are not created everyday, but it's nice to know that you can resort to them when the time comes. ;)
Tag: Presentations
clouds against the floods presentation available
Last Tuesday I gave a short presentation on the whole Clouds Against the Floods thing at the Ruby on Rails Oceania User Group here in Sydney.
Those guys are awesome and they recorded the talk - thanks guys!
If you'd like to download the slides, they're available on Slideshare.
Enjoy! ;)
presentation spring framework
Last friday I've done a small presentation about Dependency Injection and how it can improve the testing environment of a project. You can find it in the presentations page.
Hope you like it.
Tag: Presentatios
clouds against the floods presentation available
Last Tuesday I gave a short presentation on the whole Clouds Against the Floods thing at the Ruby on Rails Oceania User Group here in Sydney.
Those guys are awesome and they recorded the talk - thanks guys!
If you'd like to download the slides, they're available on Slideshare.
Enjoy! ;)
presentation spring framework
Last friday I've done a small presentation about Dependency Injection and how it can improve the testing environment of a project. You can find it in the presentations page.
Hope you like it.
Tag: World
clouds against the floods
I think by now everyone's heard of the hard time the guys up in Queensland, Australia are having because of the recent floods. People have lost their lives and many others have lost their homes and businesses, product of years of hard work.
As a result of this massive disaster the Queensland Government decided to run a telethon to encourage donations to help the flood victims. The Telethon aired last Sunday, 09/01/11, on Channel 9 and lasted for 2 hours.
The problem was the existing donations system that the Government had been using so far: it was just not thought out to handle the load we were expecting to have on Sunday.
That's when my employer, ThoughtWorks, kindly offered a hand to Smart Services Queensland in the attempt to make sure they could receive all donations that were likely to come through the web.
After that, on the Thursday afternoon before the event, Phillip Calçado, Ben Barnard and I set off on a mission against the clock: we had a little over 48 hours to develop, test and deploy an application that was expected to handle thousands of users. Not only that but an application that, should it fail, would prevent millions of dollars from reaching the people in need in Queensland. This was a great responsibility but we knew we could do it.
Given the time constraints it was a bit obvious that we would use Ruby on Rails for this app. Both because of the productivity it's known for and because we had the knowledge right there. With that out of the way, we had to decide how and where we would deploy this thing. We thought a little about it and came down to to 2 options: Amazon EC2 or Heroku (which is powered by Amazon EC2 under the hood). I pushed hard for Heroku and that's what we ended up going with.
Now it was time to get down and dirty and start coding the app. In principle it should be fairly simple. It needed a form where a potential donor would fill out his/her information, giving the option to receive the tax receipt by email or regular mail - more on that later. Upon clicking submit users would be taken to the secure payment gateway website where they could input their credit card number and finish the payment, after which they would be taken back to our app with a success - or an error - message and a transaction number.
Now this work flow has a couple of implications: First, all emails would have to be sent in the background so as to not interfere with the website performance. We were expecting to be sending thousands of them - workers anyone?
Second, the payment gateway integration would have to be developed and tested from scratch. Up until now the Queensland Government integrated with it in a different manner that could not be reused in this case.
And most important of all, although simple in concept, we had no idea of the load we should be preparing for. There was just no data from previous telethons. Thus we decided to prepare for the maximum we possibly could.
As we developed the application we deployed continuously to Heroku in order to test the payment gateway integration, benchmark the app using Apache AB, setup cache headers - Heroku uses Varnish - and find bottlenecks.
Email was one of these bottlenecks and that's why we decided to handle that in the background using Delayed::Jobs.
Since the first deployment, we also tweaked a couple of things at Heroku, such as migrating from their free PostgreSQL offering to a dedicated instance that we believed would both take the load and have plenty of room for all the data - as I write this post, we are already well over the 5MB limit they offer for free.
Long story short, by Saturday evening the website was up and running on 5 app instances, a 6th instance running background jobs - sending emails - and a dedicated PostgreSQL database server.
As Heroku is outside the Government network, their SMTP server was a no go on the short term so we also integrated the app with SendGrid, an email delivery service that fitted perfectly our needs - although the site got so much traction that we went over our monthly quota with them. But the nice guys from SendGrid increased our limit after I opened a ticket explaining the situation!
As for performance we used NewRelic to monitor the application, which Heroku also makes a breeze to integrate with.
We all went home to rest and get ready for Sunday, the day of the Telethon, when we would be monitoring the app throughout the day. We were all excited and when the show went live, we started seeing all those beautiful access charts moving like crazy, spiking over 720 requests per minute and being solid like a rock with flat and fast response times throughout the night.
In about two hours we had over AUD$2,000,000.00 (two million) donated through our website.
Since then the number of transactions dropped but has stayed constant and as of today we've received AUD$25,438,518.32 (over 25 millions of dollars) that will be donated to the flood victims in Queensland.
Oh, and the site is still up and going strong so move your fingers and go help: telethon.smartservice.qld.gov.au - there will be heaps of people grateful for your donation.
goodbye europe a two year retrospective
Now several months after I announced my odyssey to obtain my Australian work visa, the time has finally come!
I'll be flying to Sydney next week, April 15th, and as you can probably guess, I'm excited as hell! :) This starts an important new page both in my life and my career, but that's not what this post is about. It's about sharing the experience of living for over two years in Europe.
First off, I traveled. A whole lot. Both for work and leisure. I've been to 23 cities in 11 countries, which you can check on my map. Getting to explore all these different cultures was definitely rewarding and fun, to say the least. But I have my favorites, including Prague, London, Dublin and Bruges...
While in Madrid, I worked for Mirai España, the company that provided me with great professional experiences. I had the opportunity to work with a few very smart people that, in a way or another, contributed to improve my skills as a software engineer. Not to mention the several conferences I attended, including QCon in London, RailsConf in Berlin and serveral others.
Being a rock/metal fan I am in the ideal place to see just about every band I always wanted to. Concerts in Europe are high quality, frequent and affordable and as such, I've attended a whole bunch of them:
- Metallica
- Megadeth
- Soilwork
- Machine Head
- Offspring
- Cavalera Conspiracy
- Within Temptation
- The Haunted
- At the gates
- Judas Priest
- Testament
- Nine Inch Nails
- AC/DC
- Rammstein
- Grave
- Krisiun
- Nile
On a more personal note Madrid is also the place where I met Enif, my beloved girlfriend. We are both very excited about this new experience and, of course, we're moving together to Sydney, with plans of getting married next year! :D
As you can see, Europe has been kind to me and I will certainly miss the experiences, cities, cultures and people I've met. But I'm only making room for more and more interesting things that will certainly happen on the land down under. Let's conquer it all!
Hopefully my next post will be written by the beach, in my new home in Australia.
Cheers, mate! :)
rupy 2009 poznan
Next week the RuPy Conference 2009 will be held in Poznan, Poland and I was planning to talk there.
My talk had been approved and everything was looking good - I was gonna talk about JRuby in the Enterprise - until my move to ThoughtWorks became a reality less than a month ago.
This move led to a lack of support and time from my current company. I was counting on it to go there but since I'll be leaving soon, that wouldn't be possible.
Since then I've been in touch with Adam Parchimowicz - part of RuPy's organization team - and we tried to find alternatives to this. I wanted to thank him for all the effort he put into trying to make this happen. The terms we agreed on were good enough but this change of priorities kicked in too close to the event.
Long story short, I'd like to apologize for not being able to give my talk at RuPy this year.
Apart from that, I gave a very similar talk at the Rails Summit Latin America this year in Brazil and you can find the slides and sources for it in my Presentations page. ( Video coming soon )
my slides from rails summit 09
{% img /assets/images/rs2009.jpg %}
Rails Summit finished a few days ago and I have only one word to describe it: Awesome!
I met some really cool people, discussed a whole bunch of technical subjects and managed not to get so nervous in my first presentation ever - I'm not counting internal presentations I've done for my team...
My slides and source files can be found here. Feel free to contact me with questions if you got any.
soon off to conquer lands afar
Once more my life is taking a huge turn.
I've been pretty quiet for the past month and honestly don't know how I managed to hold in my excitement. I've just accepted an offer from ThoughtWorks to be based at their australian offices, either in Sydney or Melbourne, depending on where my 1st project will be.
For those of you who don't know, ThoughtWorks is a global IT consultancy that is really well known in the software development community. It's been advocating agile methodologies and test-driven development for several years now and seems to work really hard to attract and keep many bright people working there.
As a result, ThoughtWorks inspires companies and professionals around the world by delivering high quality projects and massively supporting/contributing to open source projects.
Needless to say, I am really excited to be joining a company with such an amazing culture and so many smart people.
The hiring process was long, tough and tiring - but yet enjoyable. It took 5 interviews, 1 code review and 1 pairing session, a process through which I talked to 8 thoughtworkers. They take pride on their hiring process and now I understand why.
Now I'm just going through the bureaucratic side of things: gathering documents, certificates, translations - all in order to apply for my VISA, which can take up to 3 months to get ready. In the meantime, you can still find me here in Madrid, where I'll be celebrating with a few 'cañas'. Feel free to join me! ;)
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!
yes we do eat
Besides the fact that I am a software developer, I do eat. I even enjoy doing so. Specially when I'm traveling.
That's why i decided to put up a new weblog only for this kind of stuff - it's called Travel tips - food & stuff. Basically for friends and whoever else might be interested.
There I plan to share some nice restaurants I've been to. At least to start with.
Hope u like it!
a couple of things from here
It's been some time since my last post but here I am! Where? In Spain, of course! Having a great time, I must say.
I arrived last week in Madrid and the past 2 weeks before that I spent basically packing my stuff. There is still some paperwork going on but everything is flowing well.
Besides this little feedback, I was reading this week's issue of the excellent series This Week In Ruby, from my friend Antonio Cangiano. I found something quite interesting, a plugin called HoboFields.
One of the things that bothers me in rails is the fact that by looking at your model classes, you can't tell the fields you have there. Sure, you can look at the migration script. Yeah, you can also load the development environment and inspect the object. It's a pain in the @zz! But this is the way ActiveRecord works...
Other ORM solutions like DataMapper, allows you to define the fields directly in the class. It's a much cleaner and clear way to maintain your models. And you get to know what properties you have just by looking at your classes.
That's exactly what HoboFields adds to ActiveRecord.
You define your properties and its types straight into your model class, and the plugin creates the migration scripts for you. Coming from a java world my self, I find it rather interesting, useful and it also reminds me of the way Hibernate works. You define your mappings with anotations in your class and hibernate just generate the schemas from there.
It's worth a try.
time to reveal
Some of you may know. Some of you may not. Some of you may find weird. And most of you probably have no idea of what I'm talking about but the thing is: This is a year of big changes for me.
I've been hired by Mirai, a Spanish company located in Madrid, to work as a Software Engineer. Yes, it does mean I'll be moving there. Sooner than later.
Last Friday I've received the great news that my work permit has been approved so I can now request my visa in my hometown and move to Madrid, what will probably happen by the end of this month or the beginning of May.
This post probably explain something to some people. And the bottom line is that this whole story means a great step on my career and for those of you that have been following my posts, that's probably clear.
Because of that I was able to meet wonderful people , learn a bunch of new stuff and be present in important events such as QCon 2008 in London and Euruko 2008 in Prague.
That's it for now. I'll keep you posted about my new endeavor.
I'm really excited about this chance and I invite you all for a beer or two either in Rio or Madrid - Just let me know your preference... :)
qcon 2008 london
Next week I'll be at QCon, in London, so if any of you are going to the conference and would like meet up for a couple of beers and a tech talk, please don't hesitate to drop a message.
For those of you who have never heard of QCon before, it is a really nice event to play along with some of the most popular names in the software engineering community. This year's conference features people like Martin Fowler, Neal Ford, Erich Gamma and much more.
So stay tuned, the conference takes place during the whole week and I'll try and keep you posted about what's happening over there.
C u in London!
why every programmer have to be dumb
At least, dumb for the companies hiring them. The old dream is still for sale out there: Build a "I do everything framework" and hire a bunch of dumb programmers - monkeys? - and you shall make money easily!
Just put some button pressers and a full featured enterprise system will be waiting on the other side of this "machine"!
C'mon, I thought this dream was over! We've had enough proofs that this doesn't work!
Why? Because a framework, system builder, code generator or what you may want to call this thing just can't do everything. And if you try to build this "monster" you will get yourself a hell of a problem:
- Your product will never be ready.
Or you think that "everything" has limits? Someone will always say: Hey, let's put this new feature right there... it's so small.... - Your product will not work well.
Bugs! Bugs! Bugs! I've never knew a team that has written enough tests building such a monster. Be prepared! If it's never ready, you will always be in a rush!
But ok, even if you manage to develop this "framework" and hire a bunch of monkeys to press its buttons, that's when the worst problem arise. (At least worst in my opinion)
With this "philosophy", you assume that you want to hire low level programmers that don't need to learn anything new besides how to use your full-fledged systems generator. And who the hell likes to work in a place like that?
You take from your employees all the joy of development, which is about creativity. All about putting your brain to work. And sooner or later, they will notice that and just quit. You will never be able to stablish a trustworthy relationship within your team as well as to motivate them.
How will you motivate a team by telling them they will learn a new framework that isn't used anywhere else in the world and that they will not improve their thinking?
They will become bored. And if not, man, I wouldn't like to have someone like that in my team.
The problem is that managers usually love the idea to build huge enterprise systems at low costs. And some consultants sell this idea quite well.
I prefer to have trustworthy people in my team. Provide an environment that promotes learning. Let their creativity flow. Only with this approach you will have a first class team of developers producing, happily, high quality enterprise systems.
That's the message for the companies out there: Software development IS a creative process. Promote learning. Let them create.
language change
Well, talking with some friends, I decided that, from now on, I shall only write in english on this blog.
Of course some of you may not like it. But I think it has more advantages than the other way around. I have some friends around the world, including people from the U.S., Spain, Italy, China, India and Australia. This way, they can also enjoy the content of this blog and help me improve it.
I will keep writing on the same subjects, so feel free to comment, as always. You may comment in the language you like more - hey, I can't read Japanese! - but english is highly preferable! ;)
Thanks and see you on my next post!
enquanto isso em portugal
Pois bem, saà do Rio hoje rumo a Madrid, com escala em Lisboa.
A essa hora já estaria por lá.... mas no momento estou no aeroporto de Lisboa esperando o próximo vôo, visto que perdi a conexão! Acontece até na europa! :p
Em teoria o embarque é daqui a 1h:30min...
Os portugueses são muito atenciosos btw!
Até a próxima!
Tag: Uncategorized
help stop the ie money drain
I'm a big heavy metal fan. And so are most of my friends. As a result I launched RottingNames, a band name generator that will generate the most hilarious, nastiest and nonsense names the metal world is yet to discover - ok, that's probably a bit of an overstatement but the idea is good.
However, a friend pointed out the code had a bug when running under - gasp - Internet Explorer. That didn't surprise me at all and I didn't bother to fix it. It's a small app, it's for my own - a few other's - amusement but it did give me the idea about my next micro app.
Ever wondered how much time people all around the world are wasting trying to fix nasty IE bugs? How about putting that in numbers and actually seeing how much money is going down the hole? We can't just drop support - yet. But we can help those poor souls to upgrade to something better.
Enter The IE Money Drain. Whenever you waste time working on trying to make IE behave the way it should, go there and log your hours. Share it with your clients and managers. Show them how much time and money could be saved if we were proactively helping users make the move.
And don't forget to tell colleagues, friends, even your grandma! Share the love ;)
Tag: Testing
are_you_testing_your_javascript_yet
What's the difference between your application's javascript code and its java/ruby/python/whatever code?
Think about it for a second. Done? Well, the answer is: none!
In today's web applications your javascript code is no different from the rest of your code base but yet we treat it with disregard - and we're all to blame.
We often see developers investing time writing all sorts of automated tests around their code base but fail to do the same for their javascript - and yet they get surprised when their client can't click on a button on their web app that depends on that ajax call that has been manually tested once when the page was first released.
Ask yourself this question if you're not sure if you should be testing your javascript: If it breaks, can my users still benefit from my app? - I think the answer for most web apps is obvious.
As for tools, I can only speak of two, JsTestDriver and screw-unit, the latter being the one we're using in my current project at ThoughtWorks.
What I liked about screw-unit is that it's very easy to get it up and running. Being a Behavior-Driven Testing Framework it's not surprising it has a syntax similar to Rspec -which I prefer over JsTestDriver's similarity to JUnit's.
This is how a test written with screw-unit could look like:
Not too bad for a javascript test suite huh?
So the next time you write a javascript line of code, how about writing a test for it? Consider using screw-unit as your tool but if you have been writing tests using a different framework and you're happy with it, share your experience.
I'm always keen to learn better ways of doing what I do.
Cheers!
rcov jruby and rcov_plugin
The rcov_plugin project is a rails plugin for rcov that adds some useful rake tasks to your application. And since I'm currently working in a JRuby project it made sense to use this plugin.
The thing is, among other stuff, an rcov report from a JRuby project includes some files that shouldn't be there at all, plus you also need to change the way you call rcov as such. Thus, I thought I'd contribute these changes to the plugin and my pull request was approved this morning - just install the latest version and you should be good to go.
It was useful for us here, hope it might be useful for you too.
Enjoy :)
mock objects
When testing it's pretty common to see the need for mocking a certain object, say, a Data Access Ojbect. This way you don't need to depend on a database and you can focus on the actual logic implemented by the method being tested.
For that you have several alternatives like creating the Mock class by hand or - and this is the more common - use one of the various mocking libraries out there.
They all look the same but the past couple of days I've come accross to a new - at least for me - mocking library for Java. It's called Mockito. As the creators state, technically, Mockito is a fork of EasyMock.
I have used EasyMock already but I do think Mockito has its advantages. I find it clear and a bit less verbose to write.
From one of the stubbing examples on their website:
//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
//stubbing - before execution
stub(mockedList.get(0)).toReturn("first");
//following prints "first"
System.out.println(mockedList.get(0));
//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
Looking forward to using it in production! ;)
dbunit and hibernate
I never paid too much attention on testing database stuff. While working with java, the closest I got to something workable was using the test case abstractions provided by the Spring framework. It ensures that each test method runs in its own transaction that is rolled back after the test's execution.
Fair enough. I used the setUp() method on my TestCase to configure some records so I could work with them, removing all of them in the tearDown() method. It was quite simple and worked.
But I always felt something strange with this solution. First of all, I had to add another framework just for that. - Actually I was using spring for dependency injection, but if I wasn't, it wouldn't be a nice option. And another thing that bothered me, is that you cannot guarantee that your database is in a known state.
After I started to work with Ruby - and Rails - I discovered the testing fixtures. It is a really nice way to set up your testing data without having to worry about your database state. - If you don't know what I'm talking about, follow the above link first.
Then I received a message from a co-worker saying he was having some trouble in using DBUnit with Hibernate, and asked for some help. I've heard of DBUnit before but never tried it myself. It was a very good opportunity to take a better look into it.
The basic idea after all is very similar to that of the Rails Fixtures: You have some sort of external file - XML in this case - where you set up the testing data. So the framework takes care of erasing the database, inserting your test data and returning it to its original state.
So far so good, DBUnit's default Classes works with JDBC, DataSources and JNDIDatasources, but not with Hibernate. The effort to put them working together is minimal and is documented in their web site.
I decided to share how this can be done with hibernate and in the end, you would have a test case similar to this one:
Tag: Games
fallingdreams my very own tetris clone
This will come as no surprise to my closest friends, but I am a long time game development admirer. Although I've never done anything professionally I did spend some time in the past studying this amazingly interesting field - it's my dark hobby. As hardware evolves and gamers demand more and more reality from their consoles, the game development industry is one of the few that basically didn't suffer with the latest economic crisis.
3D games are getting more and more sophisticated to the point that it's very hard for a single person, or even a small team, to develop something worthwhile - think of all the people you need to develop a game such as God of War III: screenwriters, artists, musicians, sound engineers, 3D artists, animators, programmers, level designers, combat designers, actors, voiceovers...
So I just wanted to have the experience of writing a full game, end-to-end, and that's where FallingDreams comes in. To be able to do that in a short amount of time, it had to be something simple and that's why I chose Tetris. Although simple, it does share most of the steps common to modern games development. It was a very interesting project to work at and you can grab the result here. The source code is also available on my github account, here.
FallingDreams is written in Java (JDK 6) and as such it should work fine on Windows, Linux and Mac OS. I tried to be as loyal as possible to the original Tetris rules, but you might find one thing or two that don't work as one'd exepct.
Enjoy! ;)
Disclaimer: This was my first 'full game' and is not intended to be production ready. The code has definitely got room for improvement and it served as my playground where I experimented different design techniques, both game and general software related. And it doesn't have a single line of tests - crucify me :P
As I said, it's not supposed to be considered bug free but I'm sure people interested in games development can benefit from the source files. Feel free to fork it as well! It would be cool to see what people would do with it :)
Tag: Java
fallingdreams my very own tetris clone
This will come as no surprise to my closest friends, but I am a long time game development admirer. Although I've never done anything professionally I did spend some time in the past studying this amazingly interesting field - it's my dark hobby. As hardware evolves and gamers demand more and more reality from their consoles, the game development industry is one of the few that basically didn't suffer with the latest economic crisis.
3D games are getting more and more sophisticated to the point that it's very hard for a single person, or even a small team, to develop something worthwhile - think of all the people you need to develop a game such as God of War III: screenwriters, artists, musicians, sound engineers, 3D artists, animators, programmers, level designers, combat designers, actors, voiceovers...
So I just wanted to have the experience of writing a full game, end-to-end, and that's where FallingDreams comes in. To be able to do that in a short amount of time, it had to be something simple and that's why I chose Tetris. Although simple, it does share most of the steps common to modern games development. It was a very interesting project to work at and you can grab the result here. The source code is also available on my github account, here.
FallingDreams is written in Java (JDK 6) and as such it should work fine on Windows, Linux and Mac OS. I tried to be as loyal as possible to the original Tetris rules, but you might find one thing or two that don't work as one'd exepct.
Enjoy! ;)
Disclaimer: This was my first 'full game' and is not intended to be production ready. The code has definitely got room for improvement and it served as my playground where I experimented different design techniques, both game and general software related. And it doesn't have a single line of tests - crucify me :P
As I said, it's not supposed to be considered bug free but I'm sure people interested in games development can benefit from the source files. Feel free to fork it as well! It would be cool to see what people would do with it :)
a few more thoughts on final classes
I said final classes are evil and that post got some attention with interesting comments. Maybe because of the title and the tone I wrote it, a few comments didn't get my real intention and perhaps I should have been more explicit about it. Go ahead and read it. I'll wait. :)
Anyway, I thought I'd expand a little more on that subject, explaining my motivation to write that post and going through the topics I think were raised by my dear readers.
First off, final classes are evil for testing. And that's what it was all about in my previous post.
If you depend on a final class, your code will be harder to test. Unless the final class provides an interface that captures its intent - or you wrap that dependency.
But this affirmation has some implications that were pointed out by a few comments, some of which I agree with - others, not so much. So let's start!
- Immutability
Someone said "Why make a class final ? To make it immutable". This is not entirely true. Only by marking it final you do not ensure immutability. There is no point in doing that if you provide mutators - e.g. setters. - and don't declare your members private and final.
I think it's important to make this clear and understand that the immutability part you achieve by marking a class final is the one of preventing inheritance. Subclasses could possibly contain malicious/careless code and change the internal state of the class.
But there is another way of preventing subclassing without marking the parent final: declare its constructor private and provide a static factory.
- Designing for extensibility
This is hard. It basically means that if you don't mark a class final, you should document it for inheritance.
And this is why inheritance is, in general, a bad OO practice. By documenting the class you basically break encapsulation since you tell the world about your internals.
Therefore, the recommendation is to mark a class final if you're not sure if it's safe to subclass it - or if you just don't wanna bother writing documentation and thinking too much about your "client" subclasses.
- Coding against interfaces
This one is simple but yet often forgotten. Do not code to concrete classes. Always choose interfaces where possible.
It roughly means to do this:
List args = new ArrayList();
instead of this:
ArrayList args = new ArrayList();
By doing so you have the flexibility to not care about the implementation you're working with, as long as it obeys the interface. That way, the implementations can be swapped at any time without breaking any client's code.
- The problem with testing
All items listed here so far are widely regarded as best practices and the bullet I raised about hard testing usually happens when you "violate" some of them.
Specifically, if you decide not to design a class for inheritance and mark it as final, it's wise - in my opinion - to try and capture the class's intent through an interface.
That way you can safely mark your class final and users of your class can easily use the interface to extend it - by favoring composition over inheritance - or by providing it to mocking frameworks for easy testing.
- Conclusion
I don't really think there is a rule of thumb here. Java's standard library shows many examples of both approaches and some of them are now considered bad practices but yet are there for backward compatibility. Nevertheless, these are points to consider when designing your classes.
As pointed out by Josua Bloch in his awesome book Effective Java, "If a concrete class does not implement a standard interface, then you may inconvenience some programmers by prohibiting inheritance".
As usual, comments are more than welcome :)
jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
jruby on rails and legacy java apps managing dependencies
The motivation for this post came from a couple of messages I've seen on the jruby's google group and because I think it's pretty cool to share how we tackled this problem.
- A little bit of context
We, as a vast amount of people out there, have legacy Java code. A lot. In our case this legacy is pretty much crucial to our business. We can't just trash it and start from scratch. Bad idea.
On the other hand we do have new features to be built on top of it. But we wanted an easier way to develop this new stuff and decided for a JRuby on Rails solution, using it as a front-end to our existing services.
- What we decided to do
Our final rails project would make use of a specially created jar file containing our Java application. This Jar would also contain a public interface of the services we'd have to interact with from rails.
As any Java application, ours depend on a number of external jar files that correspond to the various framewoks we usually have in place. e.g.: Hibernate, Spring, apache-commons ...
Which means we need to make our app's jar and all it's dependencies available in the JRuby classpath in order to use it.
Given we're using warbler to package our application as a war file, we just need to place all jars needed into our rails app's lib folder. Warbler then takes care of copying any jar files located in there into the war.
- The problem
So we needed a smart way to include all these dependencies into the project, and copy/paste isn't an option.
In the Java world we use Maven to manage our projects dependencies - and you should too. Because of that our approach involved turning our rails application into a Maven aware project.
Basically we needed a pom file that would declaratively list our java project as a dependency. From there on, Maven knows what the dependencies are and downloads them to your local repository.
Which leaves us with one more task. We need to put all these dependencies into our lib folder after maven has downloaded them.
Below you'll find the pom.xml file that we use to achieve this with inline comments explaining each bit:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<!-- notice how we specify the packaging to be a war,
that way, maven knows where to copy the jar files -->
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<artifactId>railsApp</artifactId>
<name>railsApp</name>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>java-legacy-app</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>railsApp</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<!-- This tasks only creates a basic structure expected by maven,
so it can do its work -->
<id>create-mock-web-descriptor</id>
<phase>compile</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
mkdir -p src/main/webapp/WEB-INF
touch src/main/webapp/WEB-INF/web.xml
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Now in the package phase we copy the jar files
that maven put into the fake web app to our rails' lib folder -->
<id>copy-needed-jars-into-lib</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -f lib/*.jar
cp target/railsApp/WEB-INF/lib/*.jar lib
rm -rf target/railsApp*
rm -rf src
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Here we optionally create the final war file containing our rails app using warbler,
doing a small cleanup of the files and folders maven created -->
<id>create-final-war</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -rf *.war tmp/war
jruby -S warble && \
mv *.war target/railsApp.war
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Now from the command line we can just run mvn package and we’re good to go.
Maven will start to package the application as a war file. Since it’s not a Java application we create the empty web.xml file in the compile phase, to fool maven.
After it has copied all the dependencies into WEB-INF/lib the next packaging goals will make sure we copy them to our rails’ lib folder, also creating the final war file, ready for deployment.
Note that once done, you can use a simple code snippet similar to this one as an initializer and load all dependencies:
Dir.entries("#{RAILS_ROOT}/lib").sort.each do |entry|
if entry =~ /.jar$/
require entry
end
end
Then we can just use script/console, script/server and so on, as we normally would.
Sorry for the long post, I tried to pack in as much as I could and I certainly hope it’s useful to someone. Any doubts, comments and etc… just drop me a line. :)
google io thoughtworks on gae
I've just watched a video from Google IO where Martin Fowler and Rebecca Parsons went through some of the aspects that involves the development of an application for the cloud - focusing on the JVM.
In terms of the Google App Engine, you don't have access to a relational database, thing I found out when I first tried it. Instead you get a Big Table.
Martin put out a good analogy and you can just think of it as a nested hash map. It's certainly a shift on how we think these days, but layers of abstraction like google's DataStore and the Java Persistence API will help in the transition.
Another interesting bit about the presentation was on how concurrency works on GAE.
Essentially, in an standard Java application you have a single memory space where you have at least one running thread. You can create threads on the fly, which will share the same memory space, thus making it easy to share data.
On the app engine, things work differently. What you have are separate memory spaces with a single thread on each one. Any attempt to create a new thread will result in an exception. The solution for sharing information in this case? Use the nested hash map (big table).
Now, whereas you might not be worried about this since your application doesn't span any threads, as well pointed by Martin Fowler, it's the code you don't see that you need to be careful with. Any Java application uses a number of 3rd party libraries that might span out threads of their own, which will result in your application blowing up.
That rang a bell. Again, back when I was trying the app engine, one of the configuration bits shared by Ola Bini looked like this:
config.webxml.jruby.min.runtimes = 1
config.webxml.jruby.max.runtimes = 1
config.webxml.jruby.init.serial = true
I think the properties are pretty much self-explanatory but I didn't quite understand the reason for setting it back then.
If you happen to have bigger values for the number of runtimes you want, you need to set the serial property to true, otherwise JRuby will span several threads to create the runtimes.
This is a really good example of things that might fail whether you're migrating or developing a new app to deploy on the App Engine. Luckily for us, JRuby has a smart and neat way to handle this - the configuration I've just shown, but most of the libraries out there that might rely on threads are not prepared.
Martin and Rebecca's opinion on this is that new releases of these same libraries will start to take it into account, since a bigger adoption of the Cloud seem to be on the way.
Make sure you watch the video. I certainly left a lot of interesting stuff out.
helping the jruby effort debugging the source
Wanna help improve JRuby? Make sure you read this post by Charles Nutter first. There he explains how to run Ruby specs with JRuby.
Start with fixing Ruby specs is a great way to get acquainted with the code. And it’s also a important task in order to make sure JRuby is the most complete and compatible ruby implementation out there.
But before you get your hands dirty, it will be a lot easier if you can actually debug JRuby’s source while fixing any specs - or bugs/features for that matter.
railswaycon jruby internals by ola bini
As always I expected a good talk from Ola and once more he delivered it. But this one was different. It might have been even boring to some ruby developers since we saw a fair amount of java code in this presentation. Ola gave us a tour through the main classes that make JRuby possible with a single purpose: so we can check out the code and hack ourselves. You can download his slides here.
If you've been following both JRuby and Ola Bini for the past year or so, you've noticed the trend and evolution of this alternative - and so far the most complete one - implementation of the ruby language. Specially at conferences.
Last year at QCon London, Ola was also talking about JRuby. At Euruko '08, in Prague, Charles Nutter also talked about it. RailsConf in Berlin also had its share. What all these talks had in common is that they talked about JRuby from a user/developer point of view. They were selling the solution. Convincing people to use it and presenting successful use cases.
And as the trend goes on, JRuby is now faced as a true alternative - one that we, btw, believe here at the company as we're actively using it - and it seems that now the call is for help. Help to make JRuby an even more complete and overall better ruby implementation. Charles' call for help was a great step. As he states, it's a good way to get your feet wet. I answered the call and am hacking JRuby myself, having already submitted a couple of patches. Perhaps this was the reason for which I enjoyed the talk the most. I was already familiar with some of the structure and classes in JRuby.
There were 2 more talks about JRuby: The Pleasure and Pain of Migrating to jRuby, by Steven Bristol and Integrating Enterprise Java with JRuby and Rails, Michael Johann. Unfortunately only the first one was a real case experience, where Steven walked through the problems he faced integrating JRuby with an existing java project. Interesting insights.
Michael Johann basically presented a short tutorial on how to integrate rails with EJB3 which, albeit interesting, failed to address issues faced on real life projects, like dependency management. Issues which we have already addressed in a very cool way here and I plan to share it soon. Still deciding how though...
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!
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?
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:
mock objects
When testing it's pretty common to see the need for mocking a certain object, say, a Data Access Ojbect. This way you don't need to depend on a database and you can focus on the actual logic implemented by the method being tested.
For that you have several alternatives like creating the Mock class by hand or - and this is the more common - use one of the various mocking libraries out there.
They all look the same but the past couple of days I've come accross to a new - at least for me - mocking library for Java. It's called Mockito. As the creators state, technically, Mockito is a fork of EasyMock.
I have used EasyMock already but I do think Mockito has its advantages. I find it clear and a bit less verbose to write.
From one of the stubbing examples on their website:
//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
//stubbing - before execution
stub(mockedList.get(0)).toReturn("first");
//following prints "first"
System.out.println(mockedList.get(0));
//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
Looking forward to using it in production! ;)
why i like ruby or ruby the language of the lazy programmer
This is quite funny. A friend, Perl addicted, is now learning Ruby. He really enjoys the language but made a interesting observation: Ruby is a language for lazy programmers!
Well, I have to agree... You know, I love saving keystrokes and achieving more by writing less. And this is so true with Ruby.
Let me give a really simple example, comparing with java - don't get me wrong... I love java, specially the platform, but it fits well here since I've always been a Java guy.
Imagine you have a Phone class with the attributes number and type, which can indicate whether the phone is a land line or a mobile phone. Then you got an array filled with phone classes and you want to narrow it by creating a new array only with mobile phones.
In Java, such a class could look very much like this:
public class Phone {
private String number;
private String type;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Quite simple, isn't it? But we are telling the compiler many things we actually shouldn't need to. This class is a java bean and as such, among other things, it needs a pair of getters and setters for each of its attributes.
Now, on with our example, the same class, in ruby, looks like this:
class Phone
attr_accessor :number, :type
end
Yeah, I know the feeling. This class has exactly what we need: the two attributes with its own pairs of getters and setters each. But we didn't need to inform it in the verbose way Java has teached us. Cleaner, period.
Now to the code that actually returns the new array containing only mobile numbers. In java, we can do it in two different ways.
Using an ArrayList:
//Create two phone objects, one land line and one mobile
...
// Add them to an array
ArrayListphones = new ArrayList ();
phones.add(land);
phones.add(mobile);
//Return an array only with mobile numbers:
private static ArrayListselectMobilePhones(ArrayList phones) {
ArrayList<Phone> mobiles = new ArrayList<Phone>();
for (Phone phone : phones) {
if (phone.getType().equals("mobile")) {
mobiles.add(phone);
}
}
return mobiles;
}
Or using ordinary arrays:
// Assume the same phone objects here
...
//Add them to the array
Phone[] phones = new Phone[]{land, mobile};
//Return an array only with mobile numbers:
Phone[] mobiles = new Phone[a.length];
for (int i = 0; i < a.length; i++) {
if (a[i].getType().equals("mobile")) {
mobiles[i] = a[i];
}
}
And you're good to go. Actually this code with an ArrayList here only looks good thanks to generics. But this is another matter. Let's take a look at the ruby code that accomplishes de same task:
//Create two phone objects, one land line and one mobile
...
//Add them to an array
phones = [land, mobile]
//Return an array only with mobile numbers:
mobiles = phones.select { |phone|
phone.type == "mobile"
}
See the difference? Java is a great language but too verbose at times. This is a really simple example but if you take the same principle to a bigger app... yeah, you see where I'm going.
The bottom line... Ruby may be the language of the lazy programmer, as my friend pointed out. But I don't mind being called lazy as long as I can type less and be more productive. Do you? :)
qcon 2008 domain specific languages
Today was the first day of the conference and it started with a tutorial about DSL's with Martin Fowler, Neal Ford and Rebecca Parsons. We also had as attendants Ola Bini, core developer of JRuby, and others. My expectations were pretty high and the presentation didn't let me down. I'll try to put here toghether my impressions and some notes I took while I was there.
Marting Fowler started discussing what DSL's are and giving some examples that many of us use in our day to day Job. Like the XML configuration files in the Java world. It is a kind of DSL, it has it's own keywords and syntax in order to express some information that will be used , for instance, to configure an underlying framework.
The problem with XML is that it becomes hard to see the overall behavior behind it. It's not very fluent to understand the purpose of an XML file just by looking at it for the first time. There is too much "noise". Things that get into the way of the readability. - YAML files are an much more readable alternatives to XML.
The same happens with a standard framework api code. Let's take for instance a sample API configuration code written in Java to tackle the domain of hotel reservations. A framework like this could have the following implementation:
HotelService hotelService = new HotelService();
PersonService personService = new HotelService();
Hotel hotel = hotelService.findById(1);
Person guest = personService.findById(10) ;
Reservation reservation = new Reservation() ;
reservation.setFrom("2008-03-10") ;
reservation.setTo("2008-03-14");
reservation.setGuests(new Person[]{guest});
hotelService.book(hotel, reservation);
Of course implementations of this simple example may vary but we can see here some of the readability problems. One approach we could use for that is to develop a Fluent Interface to wrap this API. This was one of the techniques explored during the tutorial and the actual fluent interface could now look somewhat similar with this:
new Hotel(1)
.book()
.forGuests({
person.find(10)
})
.rooms(1)
.from("2008-03-10")
.to("2008-03-10");
Much more readable, huh? One of the main benefits of using DSL's they highlighted in the tutorial is the simplicity of code you can achieve. You can actually show this code to a business person and he can understand it. This is a kind of internal DSL.
But there is still a bit of noise in this code. The the parenthesis which are not always desirable, and the use of double quotes for dates. But, this is Java code, and Java doesn't give too much room for you on the DSL subject. Here was when the speakers changed their focus a bit to Ruby. It's dynamic nature and metaprogramming techniques provides a powerful flexibility that allows for a looser syntax.
So in ruby the previous interface could look like this now:
Hotel.find(1) .book(1.room).forGuests {
Person.find(10)
}.from(march.10.2008).to(march.10.2008)
We got rid of the double quotes and the code looks more fluent, like a normal english sentence. I doubt a business guy woudn't understand what this code is doing. With this, we can get closer to the business guys, with a common vocabulary, and fill the gap between us.
This is just one of the ways we could have written this code and is not the actual example used in the tutorial. The syntax also really depends on how readable you wanna make your code. I'll provide those later when they release the digital format of the presentation.
So one of the flows that the development of an internal DSL can get is to build a framework and define the DSL on top of it. But we should also keep in mind that DSL's shouldn't be general purpose programming languages. They should be created to tackle a specific kind of domain problem, so we would have a whole system made of small DSL's.
Another interesting subject that was touched is testing. How do you test DSL's?
The suggested approach, and that I think is quite reasonable, is to have separate tests for the underlying framework and another to test the DSL and its parser you can assure you have the expected behaviour of both parts.
This is really just a summary of my thoughts and of what happened there. I'm not going into too much details right now but if you found something too abstract - and it is! ;) - feel free to ask details. I'll be more than happy to help.
This is definetly an interesting subject and now I'll head to play more with all that. :)
PS; This is not the whole presentation, just the best of it from my stand point. Other subjects include External DSL's which can actually involve you coding Lexers, Parsers and Compilers. It's usually not worth the hassle. And it's too complicated anyway, that's why I left it out from this post.
dbunit and hibernate
I never paid too much attention on testing database stuff. While working with java, the closest I got to something workable was using the test case abstractions provided by the Spring framework. It ensures that each test method runs in its own transaction that is rolled back after the test's execution.
Fair enough. I used the setUp() method on my TestCase to configure some records so I could work with them, removing all of them in the tearDown() method. It was quite simple and worked.
But I always felt something strange with this solution. First of all, I had to add another framework just for that. - Actually I was using spring for dependency injection, but if I wasn't, it wouldn't be a nice option. And another thing that bothered me, is that you cannot guarantee that your database is in a known state.
After I started to work with Ruby - and Rails - I discovered the testing fixtures. It is a really nice way to set up your testing data without having to worry about your database state. - If you don't know what I'm talking about, follow the above link first.
Then I received a message from a co-worker saying he was having some trouble in using DBUnit with Hibernate, and asked for some help. I've heard of DBUnit before but never tried it myself. It was a very good opportunity to take a better look into it.
The basic idea after all is very similar to that of the Rails Fixtures: You have some sort of external file - XML in this case - where you set up the testing data. So the framework takes care of erasing the database, inserting your test data and returning it to its original state.
So far so good, DBUnit's default Classes works with JDBC, DataSources and JNDIDatasources, but not with Hibernate. The effort to put them working together is minimal and is documented in their web site.
I decided to share how this can be done with hibernate and in the end, you would have a test case similar to this one:
spring 25 dependency injection that doesnt hurt
Dependency injection - DIÂ - Â is a great thing. Really. The hability to tweak implementations without touching your code is awesome and the DI frameworks, like spring, saves you a lot of coding. No more service locators stuff.
But, and there is always a but, you're left with a bunch of XML configuration. And I hate it. Not that XML files are bad... the thing is that everything nowadays has its own set of XML configurarion files. And Spring is not different.
eu odeio xml
Isso é um fato. Cada linha de XML que eu escrevo me faz pensar em formas de evita-las. E isso não é simples.
Ultimamente, desde o Java 5, tem se trocado o XML pelas annotations. Tá bom, fica bonitinho né? Até que fica. Em alguns casos, até mais organizado. O Hibernate desde a versão 3 faz uso das annotaions da JPA como alernativa ao seu XML de configuração. E esse sim é um belo caso de sucesso!
São apenas algumas anotações na classe para mapea-la e pronto, adeus xml! Mas como sempre, as anotações já estão sendo exageradas por aÃ. Basta decidir configurar uns 3 frameworks - e provavelmente dois deles são descenessários no seu projeto - usando anotações e as suas classes ficarão uma zona! E muito mais ilegÃveis que um arquivo XML!
As anotações são recursos muito poderosos e devem ser usadas de forma consciente. Use as que realmente valem a pena, como as que vou falar agora, que fazem parte da nova release do Spring framework, a 2.5 RC1.
scea 5 beta
Hoje fiz a versão beta da nova prova de arquiteto da Sun e eis algumas impressões:
- É longa e cansativa... fato justificável se levar-mos em consideração o fato de ser uma prova em estado beta. Ela possui mais questões que a versão final. São 153 questões no total, em 4h e 30min.
como o spring me ajudou a manter o active record
Nesse primeiro post vou falar um pouco sobre meu novo trabalho. Na verdade, sobre um problema que encontramos lá.
Dentre diversas coisas que estamos fazendo, como migrações por exemplo, estou ajudando na elaboração da arquitetura que irá abrigar as novas aplicações desenvolvidas na empresa.
Tag: Programming
fallingdreams my very own tetris clone
This will come as no surprise to my closest friends, but I am a long time game development admirer. Although I've never done anything professionally I did spend some time in the past studying this amazingly interesting field - it's my dark hobby. As hardware evolves and gamers demand more and more reality from their consoles, the game development industry is one of the few that basically didn't suffer with the latest economic crisis.
3D games are getting more and more sophisticated to the point that it's very hard for a single person, or even a small team, to develop something worthwhile - think of all the people you need to develop a game such as God of War III: screenwriters, artists, musicians, sound engineers, 3D artists, animators, programmers, level designers, combat designers, actors, voiceovers...
So I just wanted to have the experience of writing a full game, end-to-end, and that's where FallingDreams comes in. To be able to do that in a short amount of time, it had to be something simple and that's why I chose Tetris. Although simple, it does share most of the steps common to modern games development. It was a very interesting project to work at and you can grab the result here. The source code is also available on my github account, here.
FallingDreams is written in Java (JDK 6) and as such it should work fine on Windows, Linux and Mac OS. I tried to be as loyal as possible to the original Tetris rules, but you might find one thing or two that don't work as one'd exepct.
Enjoy! ;)
Disclaimer: This was my first 'full game' and is not intended to be production ready. The code has definitely got room for improvement and it served as my playground where I experimented different design techniques, both game and general software related. And it doesn't have a single line of tests - crucify me :P
As I said, it's not supposed to be considered bug free but I'm sure people interested in games development can benefit from the source files. Feel free to fork it as well! It would be cool to see what people would do with it :)
learning objective c a ruby analogy
Learning new programming languages is fun. And if it's your 2nd, 3rd...Nth programming language you will eventually look for features you already know and love.
Coming from Ruby - but after having done my fair amount of Java for many years, among other things - I end up looking for features like blocks, open classes and syntax sugar like automatic generation of attribute accessors. These are hard to let go of.
Having decided to learn Objective-C recently, I was delighted to find out that all of these are available - for better or for worse - and wanted to share this analogy with its Ruby counterparts.
- Attribute accessors
In ruby, this class definition
implements for you the getters and setters of the instance variable name.
In Objective-C, the combination of the @property and @synthesize directives provides you with roughly the same result:
Now the compiler is responsible for writing those getters/setters for you.
- Open classes & blocks
Blocks in ruby are the structures that allow you to - among other things - iterate over arrays like this:
Objective-C doesn't have an 'each' method in its root array class (NSArray) but since it does support blocks and open classes, you could just write it yourself:
Yes, I know the syntax isn't appealing, but using it in your program is a bit better:
Given the syntactic differences, the code above is very similar to its ruby counterpart. Iterating over an array is just one of the many things blocks are useful for. Others might include dealing with files, network sockets etc...
Blocks are powerful structures and are not created everyday, but it's nice to know that you can resort to them when the time comes. ;)
how do you keep yourself focused
This is basically a compilation of a few tools/habits that I use to keep focused and at a high level of productivity when working alone. Works great for me and I hope there are useful tips for you as well.
- Music
- This is one of my favorites. When working alone I hate having noisy people around, which happens quite often if you work in an open office space like me. - It is great for pair programming but I find it inefficient otherwise. Thus, I came up with the term the Heavy Metal effect. Ok, just fit your favorite music genre there but the important thing is that it must act as a barrier to the outside world. It won't work if you put something new and start babbling the lyrics!
- Password Manager
- In my day to day I have a number of web sites open like API documents, programming related groups, email... There are also the ones you open a few times a day like the company bug tracker, review board and etc. I find that having a password manager, in my case LastPass, saves a lot of time. The big advantage of it over similar tools like 1Password is that it works on mac, linux or windows. It's just a firefox plugin.
- Multiple Workspaces
- Probably the most obvious item on this list to developers but I's never too much to reinforce it. Multiple workspaces are great. And they are available in whatever platform you happen to be locked in. In my case, I split my environment in at least 3 workspaces:
-Development - where I keep things like my IDE, Browser and Terminal
-Documentation - where I keep API documents, tutorials and related stuff
-Communication - where I have my email, both personal and business, twitter and etc. This allows me to easily set a time per day to do each of my stuff without having noise from things that aren't important to what I'm focusing in that very moment. - App Launcher
- A must! On Mac I use QuickSilver and on Linux, Gnome Do. I won't say much here. If you don't use some sort of application launcher, do yourself a favor, stop reading and install one. You have no idea of how comfortable and time saver they are.
- Batch tasks
- Maybe this wasn't the best title but I couldn't think of anything better.
As a result of having a communication workspace that I use a few times a day, I find stuff that I'm interested in but don't have the time to dig at the moment. So I need a way to queue that and read later when I'm home. The tools of the trade in this case are Twitter + Evernote.
Evernote is roughly a to-do manager. And since they released their Twitter integration it's been dead easy to queue those things I talked about earlier. Just send a direct message to evernote and the item gets added instantly.
why every programmer have to be dumb
At least, dumb for the companies hiring them. The old dream is still for sale out there: Build a "I do everything framework" and hire a bunch of dumb programmers - monkeys? - and you shall make money easily!
Just put some button pressers and a full featured enterprise system will be waiting on the other side of this "machine"!
C'mon, I thought this dream was over! We've had enough proofs that this doesn't work!
Why? Because a framework, system builder, code generator or what you may want to call this thing just can't do everything. And if you try to build this "monster" you will get yourself a hell of a problem:
- Your product will never be ready.
Or you think that "everything" has limits? Someone will always say: Hey, let's put this new feature right there... it's so small.... - Your product will not work well.
Bugs! Bugs! Bugs! I've never knew a team that has written enough tests building such a monster. Be prepared! If it's never ready, you will always be in a rush!
But ok, even if you manage to develop this "framework" and hire a bunch of monkeys to press its buttons, that's when the worst problem arise. (At least worst in my opinion)
With this "philosophy", you assume that you want to hire low level programmers that don't need to learn anything new besides how to use your full-fledged systems generator. And who the hell likes to work in a place like that?
You take from your employees all the joy of development, which is about creativity. All about putting your brain to work. And sooner or later, they will notice that and just quit. You will never be able to stablish a trustworthy relationship within your team as well as to motivate them.
How will you motivate a team by telling them they will learn a new framework that isn't used anywhere else in the world and that they will not improve their thinking?
They will become bored. And if not, man, I wouldn't like to have someone like that in my team.
The problem is that managers usually love the idea to build huge enterprise systems at low costs. And some consultants sell this idea quite well.
I prefer to have trustworthy people in my team. Provide an environment that promotes learning. Let their creativity flow. Only with this approach you will have a first class team of developers producing, happily, high quality enterprise systems.
That's the message for the companies out there: Software development IS a creative process. Promote learning. Let them create.
Tag: Sphinx
monit thinking sphinx and rvm
In one of my Rails projects I'm using Sphinx to provide full-text search capabilities. To integrate both worlds I chose Thinking Sphinx, which is just great and so far has met all of my expectations.
Also, as I previously mentioned, I'm using RVM to manage my ruby installations on both my development and production machines and this setup is what motivated this post.
I use Monit to monitor the services running on my production server - nginx, mysql, php - and as of the first deploy of this application, it only made sense to also monitor Sphinx.
In order to create an initialization script, I would need at least a way to start and stop sphinx from the command line, which, using Thinking Sphinx, can be done using these rake tasks:
$ rake thinking_sphinx:stop
$ rake thinking_sphinx:start
It's worth mentioning now that I don't run sphinx as root. I run it with the same user my rails application uses. For the purpose of this post, let's call it deploy.
When I tried using my script I got errors such as these:
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.
After some digging around I found that the GEM_HOME environment variable for my deploy user wasn't being set correctly - something to do with rvm, but not quite sure - and to fix this, well, I just had to set it, leaving the final working version of my script somewhat like this - simplified :
#! /bin/sh
### BEGIN INIT INFO
### END INIT INFO
set_path="cd /your/rails/app/root; export GEM_HOME=/path/to/your/gems; RAILS_ENV=production;"
case "$1" in
start)
echo -n "Starting sphinx: "
su - deploy -c "$set_path rake ts:start" >> /var/log/sphinx.log 2>&1
echo "done."
;;
stop)
echo -n "Stopping sphinx: "
su - deploy -c "$set_path rake ts:stop" >> /var/log/sphinx.log 2>&1
echo "done."
;;
*)
N=/etc/init.d/sphinx
echo "Usage: $N {start|stop}" >&2
exit 1
;;
esac
exit 0
There are 2 things happening here. First, regardless of the user I’m running this init script as, I drop privileges in order to execute the rake task with my deploy user. Second, I set the GEM_HOME environment variable to stop getting the ‘gem not found’ errors.
After that, monit was able not only to monitor my sphinx instance, but also (re)start/stop it with the correct user.
I’m no Linux wizard so if you wanna suggest improvements to this script, feel free to do so!
Tag: JRuby
managing multiple ruby versions
Today I read a nice post - in Portuguese - by Fábio Akita on how to manage multiple ruby versions on your machine. I've tried it once with some tool I can't even remember the name but failed miserably.
But this time things look very different. The tool here is the rvm - short for Ruby Version manager - and it works just great.
Let's cut to the chase and imagine that you, like me, want to run/develop/test your code on both ruby 1.8.7 and ruby 1.9.1. These steps would get you up and running in a few minutes:
Install rvm:
$ gem sources -a http://gemcutter.org/
$ gem install rvm
$ rvm-install
$ echo "if [[ ! -z $HOME/.rvm ]] ; then source $HOME/.rvm ; fi" >> ~/.bash_profile
$ source ~/.rvm/scripts/rvm
Install the ruby interpreters you want to use:
$ rvm install ruby-1.8.7-p160
$ rvm install ruby-1.9.1
Now it's important to notice that at this point you have separate gem installations for each of the interpreters you've installed in the previous step. That said, just go ahead and switch between your interpreters and use your command line scripts - ruby, gem, etc... - as usual.
Switching between interpreters:
$ rvm ruby-1.8.7-p160 #switch to the specified version
$ ruby -v
ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-darwin9.8.0]
$ gem install rails #note I'm not using sudo since the new gem paths point to the user's home directory
$ rvm ruby-1.9.1 #switch to the specified version
$ ruby -v
ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-darwin9.8.0]
$ gem install rails #note I'm not using sudo since the new gem paths point to the user's home directory
And that's it, just go on and install rails, merb, sinatra or whatever rocks your boat!
rvm will work with MRI/YARV, JRuby, Ruby EE and Rubinius. Enjoy and don't forget to check rvm's website for the complete documentation! :)
refactoring for readability
Yesterday I've done something I should do more often: Revisit some code written a while ago for our current project and make it better.
Let's face it. We all write crappy code the 1st time. The difference is in what we do about it afterwards.
We might decide it's good enough and keep moving, or we could (and should!) stop and refactor it!
The code I revisited worked as a refactoring exercise and it's initial version is shown below:
class Jphoto
...
#a few other methods ...
def post_photo(file_data, hotel_id, send_rss, options = {})
file_name = "tmp/#{Time.now.to_i}_#{rand(1000000).to_s(36)}"
File.open(file_name, "wb") do |f|
f.puts(file_data)
end
params = [Curl::PostField.file('photo',file_name),
Curl::PostField.content('hotel', hotel_id),
Curl::PostField.content('source','PhotoUploadTest')]
extract_extra_params!(params, options)
c = Curl::Easy.new("#{service_uri_base}/photoupld")
c.multipart_form_post = true
c.http_post(*params)
if c.response_code != 200
error_msg = "File upload failed with code: #{c.response_code}"
Rails.logger.info error_msg
raise error_msg
end
File.delete(file_name)
hotel = Hotel.find_by_id(hotel_id)
hotel.cache.destroy_all
send_upload_rss(hotel, original_upload_url(c.body_str) , options) if send_rss
end
private
def send_upload_rss(hotel, photo_url, options)
...
end
def manage_images_link(hotel_id)
...
end
def extract_extra_params!(params, options)
params << Curl::PostField.content('status', options[:status]) if options[:status]
params << Curl::PostField.content('upload_source', options[:upload_source]) if options[:upload_source]
params << Curl::PostField.content('uploader_ip', options[:uploader_ip]) if options[:uploader_ip]
params << Curl::PostField.content('uploader_email', options[:uploader_email]) if options[:uploader_email]
end
end
Look at the post_photo method. It has problems in so many levels that it’s hard to start.
Methods should do “one thing” and that method obviously does much more than that, mixing different levels of abstraction.
But let’s start with the easy parts first, keeping in mind that I was aiming for readability.
Lines 7 to 10 seem to be there just to make the reader’s life harder. It’s creating a temporary file through some custom logic instead of using the tools provided by the language. Unnecessary and only pollutes our eyes. My first measure was to use ruby’s TempFile class for this. Better, but we still have a long way.
Right at line 12 it creates some sort of default parameters list, after which it extracts some extra options. I don’t know what that method does but it’s clearly using output arguments, which we should avoid at all costs, as they lead to confusion. This is a big smell as well, and another refactoring step added to my list.
On line 21 starts the code that handles what to do when we get a response_code other than 200 from our request. Apart from the fact that this code doesn’t feel right here, we just happen to know that in HTTP, 200 means success, but that might not be clear to someone looking at the code for the 1st time.
Then the code goes on to delete the temp file, clear the hotel’s cache and send the rss if the rss’ flag is true.
Let there be refactoring….
Geez, how many lines have I used to explain what the code does? Since I don’t wanna bore you to death, here is my refactored version of this method, trying to avoid as much as I can the problems I highlighted previously:
rails summit 2009 im speaking
I'll be speaking at this year's Rails Summit Latin America in Sao Paulo, Brazil. It will be a good opportunity to meet some amazing people and visit friends back home! :)
Overall I'll be spending 12 days in Brazil, with 2 of them dedicated to the conference. The other 10 I'll be in Rio de Janeiro visiting my family and friends. I strongly advise you to spend some time in Rio too, if at all possible. It's an amazing city and you can contact me if you have any questions.
Back to the conference, my session is called JRuby in the enterprise world: Using Rails with legacy code, and will be given in the form of a tutorial. I will walk you through some problems we had while making this kind of integration at my company, focusing mostly on dependency management.
At the end I hope you'll have a good understanding of what JRuby is capable of in a legacy environment.
If you're planning to attend and would like to hear anything specific about JRuby, please let me know, I can try and squeeze in.
C u there!
jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
jruby on rails and legacy java apps managing dependencies
The motivation for this post came from a couple of messages I've seen on the jruby's google group and because I think it's pretty cool to share how we tackled this problem.
- A little bit of context
We, as a vast amount of people out there, have legacy Java code. A lot. In our case this legacy is pretty much crucial to our business. We can't just trash it and start from scratch. Bad idea.
On the other hand we do have new features to be built on top of it. But we wanted an easier way to develop this new stuff and decided for a JRuby on Rails solution, using it as a front-end to our existing services.
- What we decided to do
Our final rails project would make use of a specially created jar file containing our Java application. This Jar would also contain a public interface of the services we'd have to interact with from rails.
As any Java application, ours depend on a number of external jar files that correspond to the various framewoks we usually have in place. e.g.: Hibernate, Spring, apache-commons ...
Which means we need to make our app's jar and all it's dependencies available in the JRuby classpath in order to use it.
Given we're using warbler to package our application as a war file, we just need to place all jars needed into our rails app's lib folder. Warbler then takes care of copying any jar files located in there into the war.
- The problem
So we needed a smart way to include all these dependencies into the project, and copy/paste isn't an option.
In the Java world we use Maven to manage our projects dependencies - and you should too. Because of that our approach involved turning our rails application into a Maven aware project.
Basically we needed a pom file that would declaratively list our java project as a dependency. From there on, Maven knows what the dependencies are and downloads them to your local repository.
Which leaves us with one more task. We need to put all these dependencies into our lib folder after maven has downloaded them.
Below you'll find the pom.xml file that we use to achieve this with inline comments explaining each bit:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<!-- notice how we specify the packaging to be a war,
that way, maven knows where to copy the jar files -->
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<artifactId>railsApp</artifactId>
<name>railsApp</name>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>java-legacy-app</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>railsApp</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<!-- This tasks only creates a basic structure expected by maven,
so it can do its work -->
<id>create-mock-web-descriptor</id>
<phase>compile</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
mkdir -p src/main/webapp/WEB-INF
touch src/main/webapp/WEB-INF/web.xml
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Now in the package phase we copy the jar files
that maven put into the fake web app to our rails' lib folder -->
<id>copy-needed-jars-into-lib</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -f lib/*.jar
cp target/railsApp/WEB-INF/lib/*.jar lib
rm -rf target/railsApp*
rm -rf src
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Here we optionally create the final war file containing our rails app using warbler,
doing a small cleanup of the files and folders maven created -->
<id>create-final-war</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -rf *.war tmp/war
jruby -S warble && \
mv *.war target/railsApp.war
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Now from the command line we can just run mvn package and we’re good to go.
Maven will start to package the application as a war file. Since it’s not a Java application we create the empty web.xml file in the compile phase, to fool maven.
After it has copied all the dependencies into WEB-INF/lib the next packaging goals will make sure we copy them to our rails’ lib folder, also creating the final war file, ready for deployment.
Note that once done, you can use a simple code snippet similar to this one as an initializer and load all dependencies:
Dir.entries("#{RAILS_ROOT}/lib").sort.each do |entry|
if entry =~ /.jar$/
require entry
end
end
Then we can just use script/console, script/server and so on, as we normally would.
Sorry for the long post, I tried to pack in as much as I could and I certainly hope it’s useful to someone. Any doubts, comments and etc… just drop me a line. :)
google io thoughtworks on gae
I've just watched a video from Google IO where Martin Fowler and Rebecca Parsons went through some of the aspects that involves the development of an application for the cloud - focusing on the JVM.
In terms of the Google App Engine, you don't have access to a relational database, thing I found out when I first tried it. Instead you get a Big Table.
Martin put out a good analogy and you can just think of it as a nested hash map. It's certainly a shift on how we think these days, but layers of abstraction like google's DataStore and the Java Persistence API will help in the transition.
Another interesting bit about the presentation was on how concurrency works on GAE.
Essentially, in an standard Java application you have a single memory space where you have at least one running thread. You can create threads on the fly, which will share the same memory space, thus making it easy to share data.
On the app engine, things work differently. What you have are separate memory spaces with a single thread on each one. Any attempt to create a new thread will result in an exception. The solution for sharing information in this case? Use the nested hash map (big table).
Now, whereas you might not be worried about this since your application doesn't span any threads, as well pointed by Martin Fowler, it's the code you don't see that you need to be careful with. Any Java application uses a number of 3rd party libraries that might span out threads of their own, which will result in your application blowing up.
That rang a bell. Again, back when I was trying the app engine, one of the configuration bits shared by Ola Bini looked like this:
config.webxml.jruby.min.runtimes = 1
config.webxml.jruby.max.runtimes = 1
config.webxml.jruby.init.serial = true
I think the properties are pretty much self-explanatory but I didn't quite understand the reason for setting it back then.
If you happen to have bigger values for the number of runtimes you want, you need to set the serial property to true, otherwise JRuby will span several threads to create the runtimes.
This is a really good example of things that might fail whether you're migrating or developing a new app to deploy on the App Engine. Luckily for us, JRuby has a smart and neat way to handle this - the configuration I've just shown, but most of the libraries out there that might rely on threads are not prepared.
Martin and Rebecca's opinion on this is that new releases of these same libraries will start to take it into account, since a bigger adoption of the Cloud seem to be on the way.
Make sure you watch the video. I certainly left a lot of interesting stuff out.
helping the jruby effort debugging the source
Wanna help improve JRuby? Make sure you read this post by Charles Nutter first. There he explains how to run Ruby specs with JRuby.
Start with fixing Ruby specs is a great way to get acquainted with the code. And it’s also a important task in order to make sure JRuby is the most complete and compatible ruby implementation out there.
But before you get your hands dirty, it will be a lot easier if you can actually debug JRuby’s source while fixing any specs - or bugs/features for that matter.
railswaycon jruby internals by ola bini
As always I expected a good talk from Ola and once more he delivered it. But this one was different. It might have been even boring to some ruby developers since we saw a fair amount of java code in this presentation. Ola gave us a tour through the main classes that make JRuby possible with a single purpose: so we can check out the code and hack ourselves. You can download his slides here.
If you've been following both JRuby and Ola Bini for the past year or so, you've noticed the trend and evolution of this alternative - and so far the most complete one - implementation of the ruby language. Specially at conferences.
Last year at QCon London, Ola was also talking about JRuby. At Euruko '08, in Prague, Charles Nutter also talked about it. RailsConf in Berlin also had its share. What all these talks had in common is that they talked about JRuby from a user/developer point of view. They were selling the solution. Convincing people to use it and presenting successful use cases.
And as the trend goes on, JRuby is now faced as a true alternative - one that we, btw, believe here at the company as we're actively using it - and it seems that now the call is for help. Help to make JRuby an even more complete and overall better ruby implementation. Charles' call for help was a great step. As he states, it's a good way to get your feet wet. I answered the call and am hacking JRuby myself, having already submitted a couple of patches. Perhaps this was the reason for which I enjoyed the talk the most. I was already familiar with some of the structure and classes in JRuby.
There were 2 more talks about JRuby: The Pleasure and Pain of Migrating to jRuby, by Steven Bristol and Integrating Enterprise Java with JRuby and Rails, Michael Johann. Unfortunately only the first one was a real case experience, where Steven walked through the problems he faced integrating JRuby with an existing java project. Interesting insights.
Michael Johann basically presented a short tutorial on how to integrate rails with EJB3 which, albeit interesting, failed to address issues faced on real life projects, like dependency management. Issues which we have already addressed in a very cool way here and I plan to share it soon. Still deciding how though...
rcov jruby and rcov_plugin
The rcov_plugin project is a rails plugin for rcov that adds some useful rake tasks to your application. And since I'm currently working in a JRuby project it made sense to use this plugin.
The thing is, among other stuff, an rcov report from a JRuby project includes some files that shouldn't be there at all, plus you also need to change the way you call rcov as such. Thus, I thought I'd contribute these changes to the plugin and my pull request was approved this morning - just install the latest version and you should be good to go.
It was useful for us here, hope it might be useful for you too.
Enjoy :)
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!
jruby db2 xquery bug
Update: Follow up link to this issue on JRuby's Jira, here
As I told in my last post, it was time to give JRuby a serious try. So I took one of our rails projects at work and decided to migrate it to JRuby and see what happens.
We heavily use the XML capabilities of DB2 and this was a huge problem. Every query would work just fine through the activerecord-jdbc-adapter - part of the JRuby Extras . But every Xquery would gracefully fail!
After some debugging I got stuck and decided to get JRuby and activerecord-jdbc-adapter's source to see what was happening.
As I could see, it has a bug -in my opinion - at the java part of the code. The jdbc-adapter is a bridge to allow Active Record to talk with databases through native JDBC drivers, so it's normal that we do have a java part here. At this point, what the code does is to inspect the sql statement sent from ruby and decide if it's a select, update or insert.
I fixed the problem and submitted a patch to rubyforge. I'm not sure if it's the best solution or not, but now I got the xQueries working just fine.
I'd love to hear from people with similar environments whether this patch works for you or not. I'm sure I didn't try every possibility.
If you wanna try it, just drop me a message (e-mail in the About page) and I can send the pre-compiled jar file - for activerecord-jdbc-0.8
You can also just check out the code and compile yourself. ;)
qcon 2008 slides available
Most of last QCon's presentations are available for download here.
Highlights to Ola Bini's on JRuby(pdf) and Randy Shoup's on eBay's architectural principles(pdf).
And while we're talking about JRuby, it's impressive how it's becoming a recurrent and big subject. Fast. It had its own small space at big event like QCon and in the last Euruko in Prague, we had a presentation by the JRuby Core Developers Charles Nutter and Thomas Enebo.
Big companies are sponsoring JRuby's development indirectly or directly, like Sun. And other big companies are endorsing its production ready state, like Oracle, which has a publicly available website developed with JRuby On Rails.
It's past the time to give it a serious try...
Tag: RailsSummit2009
my slides from rails summit 09
{% img /assets/images/rs2009.jpg %}
Rails Summit finished a few days ago and I have only one word to describe it: Awesome!
I met some really cool people, discussed a whole bunch of technical subjects and managed not to get so nervous in my first presentation ever - I'm not counting internal presentations I've done for my team...
My slides and source files can be found here. Feel free to contact me with questions if you got any.
Tag: Architecture
a few more thoughts on final classes
I said final classes are evil and that post got some attention with interesting comments. Maybe because of the title and the tone I wrote it, a few comments didn't get my real intention and perhaps I should have been more explicit about it. Go ahead and read it. I'll wait. :)
Anyway, I thought I'd expand a little more on that subject, explaining my motivation to write that post and going through the topics I think were raised by my dear readers.
First off, final classes are evil for testing. And that's what it was all about in my previous post.
If you depend on a final class, your code will be harder to test. Unless the final class provides an interface that captures its intent - or you wrap that dependency.
But this affirmation has some implications that were pointed out by a few comments, some of which I agree with - others, not so much. So let's start!
- Immutability
Someone said "Why make a class final ? To make it immutable". This is not entirely true. Only by marking it final you do not ensure immutability. There is no point in doing that if you provide mutators - e.g. setters. - and don't declare your members private and final.
I think it's important to make this clear and understand that the immutability part you achieve by marking a class final is the one of preventing inheritance. Subclasses could possibly contain malicious/careless code and change the internal state of the class.
But there is another way of preventing subclassing without marking the parent final: declare its constructor private and provide a static factory.
- Designing for extensibility
This is hard. It basically means that if you don't mark a class final, you should document it for inheritance.
And this is why inheritance is, in general, a bad OO practice. By documenting the class you basically break encapsulation since you tell the world about your internals.
Therefore, the recommendation is to mark a class final if you're not sure if it's safe to subclass it - or if you just don't wanna bother writing documentation and thinking too much about your "client" subclasses.
- Coding against interfaces
This one is simple but yet often forgotten. Do not code to concrete classes. Always choose interfaces where possible.
It roughly means to do this:
List args = new ArrayList();
instead of this:
ArrayList args = new ArrayList();
By doing so you have the flexibility to not care about the implementation you're working with, as long as it obeys the interface. That way, the implementations can be swapped at any time without breaking any client's code.
- The problem with testing
All items listed here so far are widely regarded as best practices and the bullet I raised about hard testing usually happens when you "violate" some of them.
Specifically, if you decide not to design a class for inheritance and mark it as final, it's wise - in my opinion - to try and capture the class's intent through an interface.
That way you can safely mark your class final and users of your class can easily use the interface to extend it - by favoring composition over inheritance - or by providing it to mocking frameworks for easy testing.
- Conclusion
I don't really think there is a rule of thumb here. Java's standard library shows many examples of both approaches and some of them are now considered bad practices but yet are there for backward compatibility. Nevertheless, these are points to consider when designing your classes.
As pointed out by Josua Bloch in his awesome book Effective Java, "If a concrete class does not implement a standard interface, then you may inconvenience some programmers by prohibiting inheritance".
As usual, comments are more than welcome :)
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?
spring 25 dependency injection that doesnt hurt
Dependency injection - DIÂ - Â is a great thing. Really. The hability to tweak implementations without touching your code is awesome and the DI frameworks, like spring, saves you a lot of coding. No more service locators stuff.
But, and there is always a but, you're left with a bunch of XML configuration. And I hate it. Not that XML files are bad... the thing is that everything nowadays has its own set of XML configurarion files. And Spring is not different.
scea 5 beta
Hoje fiz a versão beta da nova prova de arquiteto da Sun e eis algumas impressões:
- É longa e cansativa... fato justificável se levar-mos em consideração o fato de ser uma prova em estado beta. Ela possui mais questões que a versão final. São 153 questões no total, em 4h e 30min.
como o spring me ajudou a manter o active record
Nesse primeiro post vou falar um pouco sobre meu novo trabalho. Na verdade, sobre um problema que encontramos lá.
Dentre diversas coisas que estamos fazendo, como migrações por exemplo, estou ajudando na elaboração da arquitetura que irá abrigar as novas aplicações desenvolvidas na empresa.
Tag: Refactoring
refactoring for readability
Yesterday I've done something I should do more often: Revisit some code written a while ago for our current project and make it better.
Let's face it. We all write crappy code the 1st time. The difference is in what we do about it afterwards.
We might decide it's good enough and keep moving, or we could (and should!) stop and refactor it!
The code I revisited worked as a refactoring exercise and it's initial version is shown below:
class Jphoto
...
#a few other methods ...
def post_photo(file_data, hotel_id, send_rss, options = {})
file_name = "tmp/#{Time.now.to_i}_#{rand(1000000).to_s(36)}"
File.open(file_name, "wb") do |f|
f.puts(file_data)
end
params = [Curl::PostField.file('photo',file_name),
Curl::PostField.content('hotel', hotel_id),
Curl::PostField.content('source','PhotoUploadTest')]
extract_extra_params!(params, options)
c = Curl::Easy.new("#{service_uri_base}/photoupld")
c.multipart_form_post = true
c.http_post(*params)
if c.response_code != 200
error_msg = "File upload failed with code: #{c.response_code}"
Rails.logger.info error_msg
raise error_msg
end
File.delete(file_name)
hotel = Hotel.find_by_id(hotel_id)
hotel.cache.destroy_all
send_upload_rss(hotel, original_upload_url(c.body_str) , options) if send_rss
end
private
def send_upload_rss(hotel, photo_url, options)
...
end
def manage_images_link(hotel_id)
...
end
def extract_extra_params!(params, options)
params << Curl::PostField.content('status', options[:status]) if options[:status]
params << Curl::PostField.content('upload_source', options[:upload_source]) if options[:upload_source]
params << Curl::PostField.content('uploader_ip', options[:uploader_ip]) if options[:uploader_ip]
params << Curl::PostField.content('uploader_email', options[:uploader_email]) if options[:uploader_email]
end
end
Look at the post_photo method. It has problems in so many levels that it’s hard to start.
Methods should do “one thing” and that method obviously does much more than that, mixing different levels of abstraction.
But let’s start with the easy parts first, keeping in mind that I was aiming for readability.
Lines 7 to 10 seem to be there just to make the reader’s life harder. It’s creating a temporary file through some custom logic instead of using the tools provided by the language. Unnecessary and only pollutes our eyes. My first measure was to use ruby’s TempFile class for this. Better, but we still have a long way.
Right at line 12 it creates some sort of default parameters list, after which it extracts some extra options. I don’t know what that method does but it’s clearly using output arguments, which we should avoid at all costs, as they lead to confusion. This is a big smell as well, and another refactoring step added to my list.
On line 21 starts the code that handles what to do when we get a response_code other than 200 from our request. Apart from the fact that this code doesn’t feel right here, we just happen to know that in HTTP, 200 means success, but that might not be clear to someone looking at the code for the 1st time.
Then the code goes on to delete the temp file, clear the hotel’s cache and send the rss if the rss’ flag is true.
Let there be refactoring….
Geez, how many lines have I used to explain what the code does? Since I don’t wanna bore you to death, here is my refactored version of this method, trying to avoid as much as I can the problems I highlighted previously:
Tag: Groovy
jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
Tag: JVM
jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
Tag: Tools
how do you keep yourself focused
This is basically a compilation of a few tools/habits that I use to keep focused and at a high level of productivity when working alone. Works great for me and I hope there are useful tips for you as well.
- Music
- This is one of my favorites. When working alone I hate having noisy people around, which happens quite often if you work in an open office space like me. - It is great for pair programming but I find it inefficient otherwise. Thus, I came up with the term the Heavy Metal effect. Ok, just fit your favorite music genre there but the important thing is that it must act as a barrier to the outside world. It won't work if you put something new and start babbling the lyrics!
- Password Manager
- In my day to day I have a number of web sites open like API documents, programming related groups, email... There are also the ones you open a few times a day like the company bug tracker, review board and etc. I find that having a password manager, in my case LastPass, saves a lot of time. The big advantage of it over similar tools like 1Password is that it works on mac, linux or windows. It's just a firefox plugin.
- Multiple Workspaces
- Probably the most obvious item on this list to developers but I's never too much to reinforce it. Multiple workspaces are great. And they are available in whatever platform you happen to be locked in. In my case, I split my environment in at least 3 workspaces:
-Development - where I keep things like my IDE, Browser and Terminal
-Documentation - where I keep API documents, tutorials and related stuff
-Communication - where I have my email, both personal and business, twitter and etc. This allows me to easily set a time per day to do each of my stuff without having noise from things that aren't important to what I'm focusing in that very moment. - App Launcher
- A must! On Mac I use QuickSilver and on Linux, Gnome Do. I won't say much here. If you don't use some sort of application launcher, do yourself a favor, stop reading and install one. You have no idea of how comfortable and time saver they are.
- Batch tasks
- Maybe this wasn't the best title but I couldn't think of anything better.
As a result of having a communication workspace that I use a few times a day, I find stuff that I'm interested in but don't have the time to dig at the moment. So I need a way to queue that and read later when I'm home. The tools of the trade in this case are Twitter + Evernote.
Evernote is roughly a to-do manager. And since they released their Twitter integration it's been dead easy to queue those things I talked about earlier. Just send a direct message to evernote and the item gets added instantly.
Tag: CodingDojo
coding dojo 1 the fun begins
Yesterday I organized our first CodingDojo here at the company and I'm glad to say it was a great success!
The problem chosen was the Karate Chop, from Dave Thomas' Code Kata.
As it was also my first time organizing a Dojo, we took some time to get things straight, explain everyone the rules and start coding. Nothing that would compromise the experience, though.
The rules were basically the ones of a RandoriKata and as a mechanism for switching pairs we chose the TimeBox with a limit of 5 minutes.
We came up with 3 different solutions in about 1h 30min. The 1st one looking like crap! :)
Which was actually interesting because the general feeling before we started was that it would be boring, or too easy since "everyone" knows what a binary chop/search is.
Wrong!!! It all changes when you have a time limit and a bunch of people behind you doing funny noises! It's a pressure different from your day to day job. A healthy one in my opinion.
Hearing the feedback afterwards was rewarding. Everyone seemed to have had a lot of fun and can't wait for the next one.
I guess the most important lesson we got from it was to be quiet and not bother the current pair when we do not agree with their idea - not even if we do. This one is very important as it both shows respect and allows you to learn from how your colleagues think.
Next thursday we'll keep going with this one and hopefully finish and pick up the next problem! :)
Tag: Railswaycon
railswaycon jruby internals by ola bini
As always I expected a good talk from Ola and once more he delivered it. But this one was different. It might have been even boring to some ruby developers since we saw a fair amount of java code in this presentation. Ola gave us a tour through the main classes that make JRuby possible with a single purpose: so we can check out the code and hack ourselves. You can download his slides here.
If you've been following both JRuby and Ola Bini for the past year or so, you've noticed the trend and evolution of this alternative - and so far the most complete one - implementation of the ruby language. Specially at conferences.
Last year at QCon London, Ola was also talking about JRuby. At Euruko '08, in Prague, Charles Nutter also talked about it. RailsConf in Berlin also had its share. What all these talks had in common is that they talked about JRuby from a user/developer point of view. They were selling the solution. Convincing people to use it and presenting successful use cases.
And as the trend goes on, JRuby is now faced as a true alternative - one that we, btw, believe here at the company as we're actively using it - and it seems that now the call is for help. Help to make JRuby an even more complete and overall better ruby implementation. Charles' call for help was a great step. As he states, it's a good way to get your feet wet. I answered the call and am hacking JRuby myself, having already submitted a couple of patches. Perhaps this was the reason for which I enjoyed the talk the most. I was already familiar with some of the structure and classes in JRuby.
There were 2 more talks about JRuby: The Pleasure and Pain of Migrating to jRuby, by Steven Bristol and Integrating Enterprise Java with JRuby and Rails, Michael Johann. Unfortunately only the first one was a real case experience, where Steven walked through the problems he faced integrating JRuby with an existing java project. Interesting insights.
Michael Johann basically presented a short tutorial on how to integrate rails with EJB3 which, albeit interesting, failed to address issues faced on real life projects, like dependency management. Issues which we have already addressed in a very cool way here and I plan to share it soon. Still deciding how though...
Tag: Agile
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.
Tag: Performance
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
Tag: Merb
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. :)
Tag: Offers
were hiring
Here at Mirai we're looking for passionate software engineers.
And if it's not clear, by passionate I mean people who actually enjoy their job, aren't afraid of trying new things, likes to research/study, is up to date to what's happening around them and is a true team player.
Interested? Hold on, click here to find out more about the offer, as well as instructions on how to apply.
Doubts? Send them to jobs@hotelsearch.com
ps. If you've been following my blog, you probably have already got a feeling of the sort of stuff that we do here...
Tag: RailsConf2008
railsconf europe 2008 impressions and highlights
I'm back in Madrid again after the RailsConf and I think it's time to say something about it. :)
First off, the infrastructure provided by the conference was really great. The rooms, WiFi connection, food... Really well organized.
Now to the sessions, highlights:
Tutorials (Tuesday)
- Meta-programming Ruby for fun and profit (Neal Ford, Patrick Farley)
The old and good techniques that made Ruby so powerful. Here Neal and Patrick walked us through the main tricks to meta programming like open classes - and conditionally open them - , dynamically define methods, sending messages to objects and how Ruby can help test your Java code in a much easier way.
I've put the link to the slides but honestly I don't think they're too much useful without the talking.
Sessions (Wednessday)
- EC2, MapReduce and Distributed processing (Jonathan Dahl)
Jonathan explained the theory behind MapReduce using very simple ruby examples, providing the basics on how to distribute and paralelize tasks accross multiple machines.
He also introduced Hadoop, a platform built in Java that "lets one easily write and run applications that process vast amounts of data". What I liked the most was the simplicity he explained this subject. As of today, his presentation is not available online. Stay tuned as I'm gonna update this post with the links, as soon as they're available.
Sessions (Thursday)
- Debugging & Testing the Web Tier (Neal Ford)
If you've been concerned about testing your app's web tier lately, this presentation would probably not show you anything new. Neal talks about the need to debug and test javascript behaviour accross multiple browsers, using tools like Firebug, JSUnit and Selenium. If you have no idea about what these tools are, please stop now and go evaluate them!
We are pretty concerned about testing on my actual job, but selenium tests can be a pain sometimes - a.k.a extremely slow. And what ends up happening is that they are forgotten. Developers only run the test suite if it's not painful and it's lightning fast. Here's is where the highlight for this session comes: CrossCheck.
The idea is to be able to test your javascript code accross multiple browsers without the need to launch them. In fact, you don't even need a browser installed. The negative point is that it's kinda fallen behind because now you can only test older versions of browsers. But since the project is getting a lot of traction, I'm pretty sure this will be solved soon.
Conclusion
My overall impression of the other sessions I attended is that some speakers just didn't have time to properly prepare themselves, what made me think this years's RailsConf wasn't all that I expected.
But I also met interesting people and after all one of the key points in a conference is networking. :)
Definitely worth it though. And that's why I took the time to provide this highlights.
c u soon
Tag: Mac
mac os x getting mysql and rails to work
So I couldn't resist and bought myself a MacBook Pro! It's my first week with my new toy and I'm really enjoying it.
But I need to do something useful with it so I started to prepare it to be my new development platform, starting with Ruby/Rails + MySQL: Here is where the fun begins!
After I installed both Rails and MySQL, I fired up a terminal an typed:
sudo gem install mysql
...and here is what u get
ERROR: Failed to build gem native extension.
If you google this error you will find a couple solutions and this is the one that worked for me:
ARCHFLAGS="-Os -arch x86_64 -fno-common"
sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
--with-mysql-config=/usr/local/mysql/bin/mysql_config
Now, confident enough, I created a sample rails app and tried to create the development database:
leo$ rake db:create (in /Users/leo/projects/test)
dyld: lazy symbol binding failed: Symbol not found: _mysql_init
Doesn't look happy yet huh? This took me a while to figure out but it turned out to be fairly simple.
I have no idea why but after I installed the gem I had the file mysql.bundle in two different places:
/Library/Ruby/Gems/1.8/gems/mysql-2.7/lib/mysql.bundle
/Library/Ruby/Gems/1.8/gems/mysql-2.7/mysql.bundle
The solution was to remove the first copy of the file. Now everything is working fine at this end!
I really hope this is useful to someone!
Tag: Security
rails vulnerability on rexml
REXML, the XML library uses by many ruby apps, including rails, has a vulnerability that requires an immediate patch on whatever rails version you're using.
Details and instructions on the official rails weblog, here.
But basically, this is what you need to do:
gem install rexml-expansion-fix
Then, require rexml-expansion-fix in your rails's app environment.rb file.
Tag: Why I Like Ruby
why i like ruby 1 alias_method
So you found yourself in the need to override a method but still count on it's old behaviour?
No problem! Override it with your new code, call super and.... Uh oh!! Suddenly this turned into a problem... Let me give some more context.
I was testing Ferret (and the acts_as_ferret plugin) in a project to provide full text search capabilities to our models. One of the things the plugin does is to add a new method to ActiveRecord, called find_with_ferret. That way, every model can use it. Great!
So I thought that would make sense for me to remove all diatrictics from the input text before letting ferret do its job. You know, like removing umlauts and all that.
I could do that by overriding this method with code to remove the undesired chars and then call its older version to finally do the search - something like calling super, but not quite. And I didn't want my models to inherit from anything else than ActiveRecord::Base. That wouldn't make any sense.
alias_method to the rescue!
You know that to redefine a method in an existing class you can open it up and rewrite it. But since you don't wanna loose the behaviour provided by the original method, this is how you can achieve this:
module ActiveRecord
class Base
alias_method :find_with_ferret_original, :find_with_ferret
def find_with_ferret(q, options = {}, find_options = {})
remove_diatrictics!(q)
find_with_ferret_original(q, options, find_options)
end
end
end
And you're good to go. On line 3 you're just giving the original method an alias, making a copy of it.
Then you redefine it the way you like and on line 6 you call the old version to make sure u still got the same behaviour.
Now all my models can benefit of this change without requiring them to call another method nor inherit from another class.
Cool, huh? :)
why i like ruby or ruby the language of the lazy programmer
This is quite funny. A friend, Perl addicted, is now learning Ruby. He really enjoys the language but made a interesting observation: Ruby is a language for lazy programmers!
Well, I have to agree... You know, I love saving keystrokes and achieving more by writing less. And this is so true with Ruby.
Let me give a really simple example, comparing with java - don't get me wrong... I love java, specially the platform, but it fits well here since I've always been a Java guy.
Imagine you have a Phone class with the attributes number and type, which can indicate whether the phone is a land line or a mobile phone. Then you got an array filled with phone classes and you want to narrow it by creating a new array only with mobile phones.
In Java, such a class could look very much like this:
public class Phone {
private String number;
private String type;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Quite simple, isn't it? But we are telling the compiler many things we actually shouldn't need to. This class is a java bean and as such, among other things, it needs a pair of getters and setters for each of its attributes.
Now, on with our example, the same class, in ruby, looks like this:
class Phone
attr_accessor :number, :type
end
Yeah, I know the feeling. This class has exactly what we need: the two attributes with its own pairs of getters and setters each. But we didn't need to inform it in the verbose way Java has teached us. Cleaner, period.
Now to the code that actually returns the new array containing only mobile numbers. In java, we can do it in two different ways.
Using an ArrayList:
//Create two phone objects, one land line and one mobile
...
// Add them to an array
ArrayListphones = new ArrayList ();
phones.add(land);
phones.add(mobile);
//Return an array only with mobile numbers:
private static ArrayListselectMobilePhones(ArrayList phones) {
ArrayList<Phone> mobiles = new ArrayList<Phone>();
for (Phone phone : phones) {
if (phone.getType().equals("mobile")) {
mobiles.add(phone);
}
}
return mobiles;
}
Or using ordinary arrays:
// Assume the same phone objects here
...
//Add them to the array
Phone[] phones = new Phone[]{land, mobile};
//Return an array only with mobile numbers:
Phone[] mobiles = new Phone[a.length];
for (int i = 0; i < a.length; i++) {
if (a[i].getType().equals("mobile")) {
mobiles[i] = a[i];
}
}
And you're good to go. Actually this code with an ArrayList here only looks good thanks to generics. But this is another matter. Let's take a look at the ruby code that accomplishes de same task:
//Create two phone objects, one land line and one mobile
...
//Add them to an array
phones = [land, mobile]
//Return an array only with mobile numbers:
mobiles = phones.select { |phone|
phone.type == "mobile"
}
See the difference? Java is a great language but too verbose at times. This is a really simple example but if you take the same principle to a bigger app... yeah, you see where I'm going.
The bottom line... Ruby may be the language of the lazy programmer, as my friend pointed out. But I don't mind being called lazy as long as I can type less and be more productive. Do you? :)
Tag: Notices
new provider
I decided to change my blog's hosting provider and this is the first post using the new service.
Please if you see any abnormal behaviour around here don't hesitate to contact me either at leonardoborges@leonardoborges.com or leonardoborges.rj@gmail.com
Thanks!
Tag: DSL
qcon 2008 domain specific languages
Today was the first day of the conference and it started with a tutorial about DSL's with Martin Fowler, Neal Ford and Rebecca Parsons. We also had as attendants Ola Bini, core developer of JRuby, and others. My expectations were pretty high and the presentation didn't let me down. I'll try to put here toghether my impressions and some notes I took while I was there.
Marting Fowler started discussing what DSL's are and giving some examples that many of us use in our day to day Job. Like the XML configuration files in the Java world. It is a kind of DSL, it has it's own keywords and syntax in order to express some information that will be used , for instance, to configure an underlying framework.
The problem with XML is that it becomes hard to see the overall behavior behind it. It's not very fluent to understand the purpose of an XML file just by looking at it for the first time. There is too much "noise". Things that get into the way of the readability. - YAML files are an much more readable alternatives to XML.
The same happens with a standard framework api code. Let's take for instance a sample API configuration code written in Java to tackle the domain of hotel reservations. A framework like this could have the following implementation:
HotelService hotelService = new HotelService();
PersonService personService = new HotelService();
Hotel hotel = hotelService.findById(1);
Person guest = personService.findById(10) ;
Reservation reservation = new Reservation() ;
reservation.setFrom("2008-03-10") ;
reservation.setTo("2008-03-14");
reservation.setGuests(new Person[]{guest});
hotelService.book(hotel, reservation);
Of course implementations of this simple example may vary but we can see here some of the readability problems. One approach we could use for that is to develop a Fluent Interface to wrap this API. This was one of the techniques explored during the tutorial and the actual fluent interface could now look somewhat similar with this:
new Hotel(1)
.book()
.forGuests({
person.find(10)
})
.rooms(1)
.from("2008-03-10")
.to("2008-03-10");
Much more readable, huh? One of the main benefits of using DSL's they highlighted in the tutorial is the simplicity of code you can achieve. You can actually show this code to a business person and he can understand it. This is a kind of internal DSL.
But there is still a bit of noise in this code. The the parenthesis which are not always desirable, and the use of double quotes for dates. But, this is Java code, and Java doesn't give too much room for you on the DSL subject. Here was when the speakers changed their focus a bit to Ruby. It's dynamic nature and metaprogramming techniques provides a powerful flexibility that allows for a looser syntax.
So in ruby the previous interface could look like this now:
Hotel.find(1) .book(1.room).forGuests {
Person.find(10)
}.from(march.10.2008).to(march.10.2008)
We got rid of the double quotes and the code looks more fluent, like a normal english sentence. I doubt a business guy woudn't understand what this code is doing. With this, we can get closer to the business guys, with a common vocabulary, and fill the gap between us.
This is just one of the ways we could have written this code and is not the actual example used in the tutorial. The syntax also really depends on how readable you wanna make your code. I'll provide those later when they release the digital format of the presentation.
So one of the flows that the development of an internal DSL can get is to build a framework and define the DSL on top of it. But we should also keep in mind that DSL's shouldn't be general purpose programming languages. They should be created to tackle a specific kind of domain problem, so we would have a whole system made of small DSL's.
Another interesting subject that was touched is testing. How do you test DSL's?
The suggested approach, and that I think is quite reasonable, is to have separate tests for the underlying framework and another to test the DSL and its parser you can assure you have the expected behaviour of both parts.
This is really just a summary of my thoughts and of what happened there. I'm not going into too much details right now but if you found something too abstract - and it is! ;) - feel free to ask details. I'll be more than happy to help.
This is definetly an interesting subject and now I'll head to play more with all that. :)
PS; This is not the whole presentation, just the best of it from my stand point. Other subjects include External DSL's which can actually involve you coding Lexers, Parsers and Compilers. It's usually not worth the hassle. And it's too complicated anyway, that's why I left it out from this post.
Tag: Spring
spring 25 dependency injection that doesnt hurt
Dependency injection - DIÂ - Â is a great thing. Really. The hability to tweak implementations without touching your code is awesome and the DI frameworks, like spring, saves you a lot of coding. No more service locators stuff.
But, and there is always a but, you're left with a bunch of XML configuration. And I hate it. Not that XML files are bad... the thing is that everything nowadays has its own set of XML configurarion files. And Spring is not different.
eu odeio xml
Isso é um fato. Cada linha de XML que eu escrevo me faz pensar em formas de evita-las. E isso não é simples.
Ultimamente, desde o Java 5, tem se trocado o XML pelas annotations. Tá bom, fica bonitinho né? Até que fica. Em alguns casos, até mais organizado. O Hibernate desde a versão 3 faz uso das annotaions da JPA como alernativa ao seu XML de configuração. E esse sim é um belo caso de sucesso!
São apenas algumas anotações na classe para mapea-la e pronto, adeus xml! Mas como sempre, as anotações já estão sendo exageradas por aÃ. Basta decidir configurar uns 3 frameworks - e provavelmente dois deles são descenessários no seu projeto - usando anotações e as suas classes ficarão uma zona! E muito mais ilegÃveis que um arquivo XML!
As anotações são recursos muito poderosos e devem ser usadas de forma consciente. Use as que realmente valem a pena, como as que vou falar agora, que fazem parte da nova release do Spring framework, a 2.5 RC1.
como o spring me ajudou a manter o active record
Nesse primeiro post vou falar um pouco sobre meu novo trabalho. Na verdade, sobre um problema que encontramos lá.
Dentre diversas coisas que estamos fazendo, como migrações por exemplo, estou ajudando na elaboração da arquitetura que irá abrigar as novas aplicações desenvolvidas na empresa.
Tag: Free Software
software livre
Aqui no trabalho atualmente temos uma grande barreira com relação ao software livre. Pensei em escrever aqui alguma coisa sobre as barreiras que as empresas colocam quando o assunto é esse porém o Cleuton já fez isso, e ficou muito bom.
Vale a visita!
Tag: Patterns
como o spring me ajudou a manter o active record
Nesse primeiro post vou falar um pouco sobre meu novo trabalho. Na verdade, sobre um problema que encontramos lá.
Dentre diversas coisas que estamos fazendo, como migrações por exemplo, estou ajudando na elaboração da arquitetura que irá abrigar as novas aplicações desenvolvidas na empresa.