Art Of Programming

musings by Dmytrii Nagirniak

Testing Rails Across Time Zones

Why?

Because it is easy to get the dates/times wrong without even realising it. Even if you don’t need to support multiple time zones, you can catch a lot of the edge cases.

How?

  1. Randomise time zone when running specs
  2. Run the specific specs across the different time zones

Increase Your Productivity in Vim and Terminal

This post will give you minimal suggestions that you can apply in your daily work to immediately increase your productivity.

I’m writing this after watching the Steve Klabnik’s screencast where he is working “in a wild”.

I love this idea and have done videoing how I work on a little ios-checkboxes and knockout-rails.

The world would an awesome place if more people (yes, including you) would start sharing the way they work. Well done Steve!

But today I want to focus on just a few things that should dramatically improve the productivity.

How to Care for Introverts

I’ve just found an interesting poster that describes how to deal with introverts.

Being an introvert myself I agree with most of the points:

  • Respect their need for privacy.
  • Never embarrass them in public.
  • Let them observe first in new situations.
  • Give them time to think. Don’t demand instant answers.
  • Don’t interrupt them.
  • Give them advance notice of expected changes in their lives.
  • Give them 15 minute warnings to finish whatever they are doing before calling them to dinner or moving on to the next activity.
  • Reprimand them privately.
  • Teach them new skills privately rather than in public.
  • Enable them to find one best friend who has similar interests and abilities; encourage this relationship even if the friend moves.
  • Do not push them to make lots of friends.
  • Respect their introversion. Don’t try to remake them into extroverts.

I’m pretty sure it is just a common sense. But it helps when people do know it.

Migrating From Blogger to Octopress

I’ve been a Blogger user since 2006 and decided to switch over to something more geeky.

This post will cover some of the reasons for that and also will provide an overview of how to migrate from Blogger to Octopress.

What do I want to achieve?

  • Merging my personal site and blog – those were totally separate, unrelated entities, not good enough.
  • Write more often, using the same tools I use on a daily basis (Vim ATM).
  • More hands-on kind of blogging, I actually do want to do the dirty work messing with HTML/CSS etc.

Reasons for switching:

  • Markdown, HAML, bare bones HTML. I wanted to have a bit more control over how my blog looks like.
  • Blogging software isn’t good enough. Unfortunately I haven’t found yet a good geeky S/W for blogging.
  • Easier to write from Vim. Writing is much easier, not moving my hands off the keyboard and staying in the terminal.
  • Version controlled. Nice to have, but not crucial for me.

Why I didn’t want to switch:

  • Losing PageRank, which shouldn’t really be an issue (see below).
  • Uncerteinities. So now I have to maintain it myself? Take care of updates? Hell, yeah!
  • Self-hosted. Nothing to say here.
  • I have never ever needed to do anything with the blog in terms of maintenance while being on Blogger. I really just worked.

Switching to a self-hosted blog/site will require a bit of involvement from me. But this is something I am willing to take. It’s time to take my ass out of the comfy couch of Blogger.

So how to actually migrate?

I would split it into the following larger steps:

  1. Preparation.
  2. Deployment.
  3. Finalisation.

Preparation

At this stage you need to setup the Octopress itself, configure it and import your existing posts from Blogger.

I won’t go into details how to customise and set it up, you see the links.

I’ll go directly into the migrating the Blogger posts over to Octopress.

What you need to do is

  1. Export your Blogger posts.
  2. Use this script to import it into Octopress.

After you do this, all you’ll get a bunch of posts that are already part of your site. Double check whether everything is correct or not. You may want to tweak the script for your needs.

Note that the script also imports the comments, but in a little ugly way. (TIP, you may want to disable commenting before exporting the posts from Blogger).

Next thing you want to do is to update your Octopress RSS feed URL so that existing subscribers won’t be lost. I am using FeedBurner and I had to set subscribe_rss: http://feeds.feedburner.com/DmitriyNagirnyak in the _config.yml

Now that you’ve got your posts, you want to set-up the redirection from your blog to your new site.

I prepared simple Sinatra application for that. You definitely want to fork and tweak it to your needs. Note that I’m not using the blog/YYYY/MM/DD/title format. I just use the blog/title format.

Now go ahead and deploy this app. I’ve decided to use Heroku for that which is the simplest and easiest way to go.

But make sure you deploy to the domain of your blog. For example, my Blogger blog was hosted on the blog.approache.com and I deployed it to this domain.

It of course will not take any affect until you change your DNS settings. But this will enable permanent redirects immediately when you’ll do that (thus preserving all your old links).

Deployment

By now you should have:

  • The Octopress site ready to go (with all the posts migrated).
  • Blogger redirection deployed.

It’s time to go ahead and actually deploy your Octopress site.

I wanted to merge blog.approache.com into the approache.com so I deployed the new site to approache.com (hosted on Github Pages).

Now make sure everything is working properly and you have dome everything right. If you’ve missed something out, then go ahead and fix it. Then redeploy.

This may take a couple of iterations to get it right.

The point here is that you basically now have 2 blogs – one is the old Blogger, the other – the Octopress. You can experiment with the Octopress here, but don’t do it for too long (I would say max of 1 day).

After you’re happy with the new site and blog it’s time to finalise everything.

Finalisation

Next step is to make sure your subscribers will still receive updates through the FeedBurner. For that:

  1. Sign in into FeedBurner.
  2. Replace the original feed URL by the Octopress’ one (which is something like http://ApproachE.com/atom.xml).

By now you should be ready to switch your your Blogger domain to your main site.

You probably will do it simply by changing your DNS record to point to your Octopress server. In my case I had to change the DNS record from blog - CNAME - ghs.google.com to . - A - 207.97.227.245 (dot means top-level domain here).

Since you’ve already deployed your redirection app, all the old links will still work. All the PageRank should be preserved.

The very last thing to do is to disable the Blogger if you want to.

Summary

Switching to Octopress was relatively painless thanks to Blogger’s ability to export posts and the script that could import it into Octopress.

Preserving URL was relatively easy too and the rest was left to FeedBurner and DNS hosting.

Hope this is helpful for you.

KnockoutJS Validations Screencast

If you wonder how you can use KnockoutJS with Rails in a similar way to Backbone.js or Spine.js then watch the video. It also shows how easy it is to apply client side validations that work alongsite with the server-side validations.

Have a look at the knockout-rails project for more details.

Comments

Dmytrii Nagirniak
This is actually one of the options of validating in the background:

It doesn't include the bindings, but gives idea how it can be done. Easier than I thought actually.
Dmytrii Nagirniak
Pre-validating on the server can technically be done with the Model Events. But it's not supported out of the box.

It is a good idea, but there's a bit more complexity involved on both client and server. But I'll gladly accept pull requests to knockout-rails if somebody needs to support that.
Aleksey Gureiev
This comment has been removed by the author.

Issues Switching to JRuby From MRI 1.9

UDPATE: The reason for switching to JRuby the native neo4j API. Have to use REST API with MRI.

This is just a quick recap of what issues I have had trying to switch existing app from MRI Ruby (1.9.3) to JRuby (1.6.4).

Unfortunately I stepped back and didn’t want to spend more time as it felt an unbreakable chain of issues. Resolving one, you think “huh, awesome”. But very soon you hit the next.
And I couldn’t see it stopping.

But PLEASE bear in mind that I only spent a couple of hours on that. With a little bit more persistence, you may be able to the end of the tunnel.

The overall impression is that it is not a big deal really. The problems arise when trying to use other libraries. And unfortunately, not all of the gems care deep enough to support JRuby. And this is the biggest issue in my opinion, there are very little issues with JRuby itself. The transition (from the syntax perspective) was extremely easy.

The application is pretty standard Rails 3.1 app that uses gems like Dragonfly, inherited_resources, cancan, paper_trail, Authlogic, CoffeeScript, Haml, Sass, Formtastic etc. For testing - things like rspec-rails, cucumber-rails, capybara-webkit, guard (rspec and cucumber), database_cleaner etc.

So here is a quick list of the things that I faced on my way.

Before everything else I enabled support for 1.9 syntax in JRuby (export JRUBY_OPTS=–1.9).

It all first started with the weird issue where the wrong arguments were passed to RSpec shared example.
Unfortunately I did not figure out why it happened and just patched it as you can see in the comments there.



After fixing this issue I had another one related to database_cleaner. So I ended up with a pull request that worked for me.

The other issue was a huge stack trace. I scrolled 3 pages in the terminal to get to the top. Most of that stack trace is deep inside Java. Additionally I got wrong line number on exception. This “features/step_definitions/company_steps.rb:234” makes me thing that the exception is at line 234. But that file only had 49 lines of code. Now, go figure.

Going on… SimpleCov gem didn’t work out of the box and gave the warning that I need to enable debugging. That’s fine and understandable. But after half an hour of debugging of unrelated exception, it turned out that SimpleCove threw an exception because of that. So had to go and explicitly disable it.

Then I managed to run all of my specs. But I was pretty surprised how slow it was:

# rvm use 1.9.3
# time rspec # real=14s, rspec time ~ 12s

# rvm use jruby
# time rspec # real=52s, rspec time ~ 30s


But this is expected as JRuby doesn’t have enough time to optimise here. It should be much better in production. But it will be also shit slow after deployment.
Ok. That’s fine. I can trust it’s fast.

Then I tried running the cucumber specs and had to file the issue to support new Ruby 1.9.3 syntax (a = b = f 1). Not a big deal, easily fixed with parens: a = b = f(1).

Next and the final issue - I could not run the headless cucumber specs (capybara-webkit). It just got stuck (no CPU used) and feels like there is a dead-lock or something similar.

I couldn’t see way of fixing it easily and decided that for now I am done with it. So going back to Ruby 1.9.3.


To summarise, I did not feel like it’s a problem to switch to JRuby. But it’s really a big deal to actually use it due to the number of C extensions that JRuby doesn’t really support.

Again, to emphasise, there is nothing horribly wrong with JRuby and it seems to be pretty good. But the real showstoppers are the C extensions.

Comments

Dmytrii Nagirniak
Totally with you on this. But real world seems to be a bit different :)
Postmodern
Yet another reason to avoid C-extensions. When selecting dependencies for a new project, I prefer to select pure-Ruby libraries or FFI bindings (https://github.com/ffi/ffi#readme). Pure-Ruby libraries should be faster on Rubinius/JRuby. FFI bindings work perfectly on both MRI and JRuby.

If developers want faster Ruby code, they should help make MRI faster (or switch to Rubinius/JRuby), instead of writing more code in C.

Rails Plugin With Tested Assets Screencast

Some of the most valuable things you can learn are not written in books, not shown in the presentations and demos. Those come from seeing how others work.

How do they do all those small things? What tricks do they have? How would they approach that problem?

Unfortunately, I can’t remember seeing people sharing the way they actually work (unless they pair). I want to see what mistakes they make, how they fix those, how they try to come up with a word erasing a line 10 times.
I believe all this is of a great value for a lot of us.

What I described is partially done by PeepCode’s Play By Play series and Tekpub. Those are amazing (usually). But that’s not exactly what I am after. Those screencasts are high quality, polished and prepared ones. YOU are NOT featuring there. I want to see YOU there. All of you, guys.


So I decided to make a first step (or maybe not so) and screencast myself while working on a Rails Plugin.

This is mostly real-time work. You’ll see how I fail, you’ll spot the mistakes I’ve done and did not even notice, you’ll see how I write README. And, most importantly, you will hopefully see some of the things that will help yourself.

This video features the following tools/technologies:

  • Ruby, Ruby On Rails
  • CoffeeScript
  • SASS
  • Git, Github
  • Vim (MacVim and Terminal)
  • Jasmine and basic testing of JavaScript and even CSS assets
  • etc
Additionally, before watching, make sure you Turn On the Volume. Rare person doesn’t like the music that my wife helped me prepare. Even if you don’t not like the video, you should like the music :)

I hope you enjoy it. UPDATE: Please watch it in full screen as the quality is lower than I expected.





P.S.: Screencasting is really hard. And that’s my first. So apologies if something isn’t in-place.
(If you can’t see the video here, open it on Vimeo. Alternatively, try YouTube - it should work with HTML5-only browser).




Comments

Dmytrii Nagirniak
Pleased to know that you liked it. Yeah, the music sometimes goes a bit off. But it is still fun as for me :)
Flaviu Simihaian
Great video. I also love the music. Beethoven seems to get extra-dramatic near the testing pain point :)

Look forward to seeing more in the future and hope to do some myself.

Thanks,

Flaviu
Dmytrii Nagirniak
Sorry about that. I've embedded the YouTube version of the video. It is of a little better quality.
Anonymous
Video on vimeo is bad quality, I had to watch it on Youtube. Thanks for videolesson.
Dmytrii Nagirniak
If more people will need it, I will probably upload higher resolution somewhere. Have you tried YouTube?

And in the future I will have to record at much lower screen resolution
Anonymous
If see screencast from page - text is unreadable and font size is too small, at full screen (1080p) - too blur and unreadable too. may be if i'll have possibility to view at custom player size - it's will be ok.
Dmytrii Nagirniak
Try it on YouTube: http://www.youtube.com/watch?v=MWvLofLz04k

I'll update the post a bit later with both links.
Anonymous
Unfortunately vimeo does not support html5 video

Use Your Terminal Like a Pro

Keep your config in a separate dotfiles directory and under source control with the structure like:

~/dotfiles:
--+ bashrc, bash_profile
--+ ssh/config
-->--bash -> (env, config, aliases). bash has source bach/env, bash/config etc.

Then:
ln -s ~/.bashrc ~/bin/dotfiles
echo ". ~/.bashrc" > ~/.bash_profile

Put everything into .bashrc except any long running tasks.
.bash_profile - for interactive shells. But you can just usually source .bashrc.
Now some keyboard shortcuts:

  • Cntrl-a - go to the beginning of line
  • Cntrl-e - go to the end of line
  • Cntrl-k - delete everything to the right
  • Cntrl-w - delete previous word
  • ESC->-b - go back one word
  • ESC->-f - go forward one word

If you often connect via SSH like so: ssh -p 2323 username@my-server.example.com Then you can shorten it to ssh my-server if you will add entry to ~/.ssh/config:

Host my-server
    HostName my-server.example.com
    Port 2323
    User username
Then you can use it as:

# Tunnelling
ssh -L7997:127.0.0.1:7979 my-server

# Copy folder to server
scp my_folder my-server:my_other_folder/

# Or even use it with git
git clone my-server:repo-name.git



Now some useful things you can do in the terminal:
  • !! - run previously executed command (you can do `sudo !!` for example)
  • !$ - last argument of previous command
  • !60 - run the command #60. Number comes from history command
  • (for example: run tail file.log and then cat !$ is same as cat file.log
  • !echo - rerun last command starting with echo
  • Ctrl-r - interactive search on history of commands; Use Ctrl-j to abandon.
  • !?file.log?! - run the last matching command (not interactive)
  • ^file.log^another-file.log - run the last matching command replacing file.log with another-file.log
  • !?file.log?! - run the last matching command (not interactive)
  • mv README.{txt,markdown} - same as mv README.txt README.markdown.


You will also appreciate power of the shell when using aliases and functions:

alias ss="./script/server"
alias s="git status"
alias gca="git commit -am"
alias zipr="zip -r"

function take {
  mkdir $1
  cd $1
}
# take create-and-go-here

function gg() {
  git commit -v -a -m "$*"
}
# gg Commit message with no quotes


But when functions get more complicated, you might want to use a scripting language (Ruby, Python etc).
Put those scripts into your ~/bin directory and add it to your PATH variable.

There are also number of Mac specific tricks.
One is is open anything command that will open the file/directory in the default application.
You can also force it to use a specific app: open -a /Applications/Firefox.app index.html.
This one becomes a good candiate for an alias.

You can also pipe output of any command into pbcopy command to copy it to the clipboard.
For example: cat index.html | pbcopy will copy the content of the file into clipboard.

You can also do it the other way around: pbpaste > index.html or pbpaste | grep "jquery".


Another useful thing OpenTerminal (drag the app to finder toolbar). It allows you to open terminal with the current directory set to the Finder window.


You can also use the keyboard to open terminal using LaunchBar. It does much more though. It acts like a global terminal for the system.


You can also try to use zsh shell. It will work with the existing bash aliases just fine.


Most of the tips here come from the PeepCode’s Advanced Command Line screencast.
Hope this helps you on your way to becoming a Terminal Guru.

Templating Done Easy - JavaScript HAML With Rails

HAML templating with no worries: native, precompiled HAML. Blazing fast and as easy to use as it can be.

UPDATE: this functionality moved into ruby-haml-js gem, please use it instead.

Recently I have been working on a Ruby gem that packs a set of common JavaScript libraries in one place so you can just reference those easily from Rails 3.1 app. But now I want to write a bit about a very handy tool that the gem includes. I needed to work on a Backbone app and, unfortunately, there was no very simple and easy way of using HAML markup for my client side templates. Main problems:
  1. I don’t want to embed the template into the document.
  2. The Underscore.js templating is ok, but it is too verbose for me (as most of others).
  3. The haml-js is great, but I do not want to bother precompiling the templates.
  4. I do not want to think about templating as another layer or component. I want it to just work.
Fortunately it was pretty easy solve these problems with the Sprockets and Rails 3.1.
So from now on you can just write normal HAML templates and consume those with no worries from JavaScript.
All you need to do, is to add pakunok gem to your Rails 3.1 Gemfile. This will give you templates as native JavaScript functions that you can use.
It’s better to see than hear
Feel free to head to the issues and provide some feedback or read more.

Easy Rails Deployment With Capistrano and Custom Nginx Configs

In my previous post I provided some info about setting up the server for rails app.

Now I am going to describe the Nginx configuration and example of Capistrano deployment file.

One thing that I don’t want to do for every new app I deploy is to go to the web server and change the settings (as a root user) so that the web server picks the Rails application.

In order to avoid that I decided to use nginx’s include command. It allows to add include multiple nginx config files using UNIX wildcards.

So by simply adding this line to the nginx.config I make it possible to configure Nginx from Rails applicatoins themselves: include /home/*/apps/*/current/nginx.conf;. I decided to include all configs within http tag so that a Rails app can configure multiple servers for itself.

There are obvious drawbacks for this:

  1. It is less “safe” as on application might affect others if you will start adding Nginx settings outside of the server tag. But I am ready to sacrifice this for the sake of having more flexibility by assuming all server citizens are good guys.
  2. We still need to have root access to restart the Nginx. We shouldn’t need to do it often, so that’s ok with me.
Now relying on a very simple conventions, I can configure Nginx from within the app. Just in case you’ve missed it, the conventions are:
  1. To deploy a rails app (and any Rack based app), user should put the app under his home directory in apps/[name]/current.
  2. To “enable” an app, user should put nginx.conf file in apps/[name]/current.

But for now, all this cool structure isn’t very helpful unless we deploy the app.

I went with the Ruby de-facto deployment tool - Capistrano. There are enough resources on the net on how to “Capify” your application, so I won’t go into details. I assume you have just done capify . and understand what is going in there.

Briefly, what I need to do is following:

  1. Deploy the app explicitly to a particular domain (staging, production, local server etc).
  2. On every deployment - backup SQLite database (I know, I’ll use something better when I’ll have 1 million users).
  3. Prepare Nginx config file for the server (it depends on the domain we deploy at).
  4. Pre-Compile assets (SCSS in my case).

So grab the gist (embedded below) with all the details and let me know what can be improved there. The usage is pretty simple:

cap deploy user=dnagir domain=connecty.approache.com
You can deploy the same app multiple times to the same server with different subdomains and they will not conflict:
cap deploy user=dnagir domain=staging.connecty.approache.com
cap deploy user=dnagir domain=demo.connecty.approache.com

The most interesting I think is that the nginx.conf file is created during deployment using default Ruby templating engine and transfered over to the right location on the server. (But still remember root-ed Nginx restart is still required).

You can look at the complete source in the Connecty project at Github.

Please feel free to tell me what you think about this process.

Comments

jlertle
Love it!