Categories
Mass creation of symlinks
03rd September 2010
Today I was installing a new server. Downloaded the latest version of Ruby Enterprise Edition and installed it successfully. As I didn’t have any other ruby sitting in my system, I decided to symlink all of ruby executables from /usr/bin. But how do I do that? The first, obvious and sub-optimal way would be to issue “ln -s” command for each file. “That’s too much work” – I said and started googling.
Long story short, this is the solution I came up with:
find /opt/rubyee/bin/ -type f -name '*' -printf '%f,' | xargs -I '{}' -d , sudo ln -s /opt/rubyee/bin/{} /usr/bin/{}
A bit of explanation:
find /opt/rubyee/bin/ -type f -name '*' -printf '%f,'
This command finds all (-name ‘*’) files (-type f) in /opt/rubyee/bin and list their names, separated by comma (-printf ‘%f,’). Then the resulting output is passed to the next command.
xargs -I '{}' -d , sudo ln -s /opt/rubyee/bin/{} /usr/bin/{}
It basically splits its input stream by comma (-d ,) and executes “sudo ln“, replacing every occurence of {} in its arguments with actual filename.
The resulting command surely seems scary for a novice Linux admin, who I am. Probably I could utilize -exec parameter of the find, but this worked well enough for me. Also, if I did it manually, it actually would be several times faster. But hey, are we programmers or not? :-)
jQuery chaining
24th August 2010
I am beginning to fall in love with jQuery. Screw you, bicycle inventors! :-)
function next_step() {
// note how elegant and self-explanatory this code is.
var cl = 'step_selected';
$('.' + cl).removeClass(cl).next().addClass(cl);
// Also look at previous version of the code,
// before I remembered about chaining methods.
// var li = $('.step_selected');
// li.removeClass('step_selected');
// li.next().addClass('step_selected');
// Not as sexy, right? :-)
}
Funny side benefit :-)
22nd August 2010
There I was, minding my own business, trying to solve problems in graph theory and I accidentally made a Sudoku puzzle solver! Isn’t it funny how life turns out sometimes? But that’s just how awesome LINQ is.
Atomic updates, part 2
02nd June 2010
Let’s review another common scenario: posts and votes. Mongo’s approach would be to store vote count in the post itself (caching) and keep voters also in the post, in an array field. Let’s assume we want to register a new vote on post. This operation consists of three steps:
1. ensure that the voter hasn’t voted yet, and, if not,
2. increment the number of votes and
3. add the new voter to the array.MongoDB’s query and update features allows us to perform all three actions in a single operation. Here’s what that would look like from the shell:
// Assume that story_id and user_id represent real story and user ids. db.stories.update({_id: story_id, voters: {'$ne': user_id}}, {'$inc': {votes: 1}, '$push': {voters: user_id}});What this says is “get me a story with the given id whose voters array does not contain the given user id and, if you find such a story, perform two atomic updates: first, increment votes by 1 and then push the user id onto the voters array.”
This operation highly efficient; it’s also reliable. The one caveat is that, because update operations are “fire and forget,” you won’t get a response from the server. But in most cases, this should be a non-issue.
quote from MongoDB site.
How would you implement this in your regular SQL database?
MongoId and atomic increment
01st June 2010
I am starting to learn this new piece of technology, the MongoDB. It has many sweet features. However, using Ruby driver directly is not too comfortable. Plus we’re all hooked to ORM sweeteners. So people started developing ORM libraries for MongoDB and Ruby (MongoId, MongoMapper to name a few).
I have decided to try MongoId first. It seems to be a quite good library. However, it still has gaps in documentation. Today I was finding out how to perform an atomic increment of a field. In SQL world this would like like:
update users set spam_count = spam_count + 1;
Mongo Ruby driver supports this kind of operation, but MongoId doesn’t. So I was trying to get down to the driver. And this is what I couldn’t easily find in the docs. If you’re like me, I’ll save you a couple of hours. Here it is:
# assume we know object id already
User.collection.update({'_id' => '4c05848e45760182b5000001'}, {'$inc' => {'spam_count' => 1}})
Intuitive behaviour
18th May 2009
Today I was looking at exception stack trace. One of suspicious places was ‘…\reports_controller.rb:129″. Okay, navigating to this location using RubyMine is a piece of cake. Ctrl+Shift+N to get to reports_controller.rb, then Ctrl+G to position caret at specified line. But hey, that’s two actions. I hit Ctrl+Shift+N, put ‘reports_controller.rb:129′ in and voila! It worked just as I expected!
RubyMine: +1 to intuitivity, +1 to overall impression.
Advanced default parameters
09th March 2009
Today I was quite amazed by one of Ruby features. It is about default values of method parameters. For example you can do something like this:
def get_current_actions(project_id, status_id = params[:status_id] || DEFAULT_STATUS_ID)
# implementation goes here
end
The code is saying basically this: “if status_id is not passed explicitly, try to take its value from params array. If it doesn’t contain specified key, then fall back to a constant”. This feature (as almost all the rest of Ruby magic) made avaiable by Ruby’s nature: it is interpreted language. This type of code is totally unusual to guys like me, who come from the world of static typing and compiled languages. But I think I’m gonna get used to it :-)
Iterations are good
04th March 2009
Iterations in software development. Tried to implement proper solution on the first try? I bet you failed. It’s like in Google Earth zooming in your house from the planet view. To achieve your goal, you’ve got to advance a little bit, adjust your position, advance further… Iterate until done.
Making more mockups
03rd March 2009
Today Elen, my manager, approached me and asked to make a prototype of a new functionality in our project management system. This is a reimbursement management module: employees spend some money (taxi from airport, for example), then they create requests for reimbursements and if they are lucky and management approves the requests, they get the money back :-)
So, prototype it is. (more…)
SugarCRM: More colors!
06th February 2009
When I was implementing previous issue, my manager asked me: “Can we also mark meetings with colors, corresponding to users?”. This way it becomes somewhat easier to identify originator of an event. “Yeah, it would be cool, but it can be tricky and difficult to implement”, I said, rejecting the feature request. I said so just to save my ass from potentially frustrating project. Just the day before Marcelo had told me that he has a friend who was working with SugarCRM for a year and he hadn’t quite enjoyed the experience. (more…)