Per-project environment variables with Foreman

If you haven't heard of Foreman, it's a painless way to kickstart an app that depends on running multiple tools or processes. In short, if you are using an app with a lot of stuff that requires to be run like Redis, a rake task, and then the development server, then Foreman is for you. Check it out.

I've been working with increasing number of projects lately and managing environments for each of those has been a time sink. I do maintain a per-project gemset using rvmrc, which does a nice job of isolating gems. But when each of your projects need some environment variables, your bashrc or bash_profile is going to hell. 

Well, not actually. I dug up the Foreman docs and found something very useful. If you use Foreman, it supports reading environment variables from a .env file in the project directory. So if your current project uses $GIRLFRIEND_VERSION and $GIRLFRIEND_PATH, just create the following ".env" file in project directory.

And start foreman. Your project can now find your girlfriend's version and path ;)

UPDATE: It is very likely that env variables may be different for your team members. I choose to add .env to my global gitignore file and create a "sample.env" file in the directory, with list of env vars with default values and add it to the repo. Anyone who clones the repo can setup the .env with the values specific to their setup.

Posted
 

the handy bundle-exec

I found myself in a pretty confusing situation today when I was trying out Rails 3.1.rc1. In my Gemfile, I specified Compass to be installed from the github repo and bundler did just that. But I had to run Compass's executable in my rails app and I had no clue as to how to do it, because my rvm gemset for trying the RC version of Rails doesn't have Compass installed in the gem environment. So running the following command, generated a command not found error.

Bundler installs it local to the application, when you choose to install from the git repo, so the executables aren't in your gem path. In such situations, bundle-exec comes handy.

Will run the compass command with it's arguments in the scope of the bundle (I'm referring to the gem dependency environment managed by bundler not to git-bundle).

 

Posted
 

The binding method in ruby

I stumbled upon the binding method in Ruby.

Try Binding.new and it'll throw an error. It seems that the only way you can get an instance of the Binding class is by calling the binding method. I'm sure this method calls the Object.binding method either directly or indirectly. Try Object.binding and i'll say that its a private method.

So what's binding?

binding contains the scope of the current ruby block and allows accessing stuff that would else not be in scope. For example,

And you get a NameError. (I love the errors in Ruby. They are well named and are a pleasure to read.)

Modify the say method to accept an argument. Change the puts to eval a ruby expression and pass the binding as second argument to it. When the binding instance is passed, eval evaluates the expression in the scope of the binding.

Now try passing the scope to the say method and see how msg is accessed by magic

Posted
 

Rails 3.1.0 beta1

ERROR:  While generating documentation for activesupport-3.1.0.beta1

... MESSAGE:   incompatible character encodings: UTF-8 and ASCII-8BIT
... RDOC args: --op /home/akashmanohar/.rvm/gems/ruby-1.9.2-p180@rails31/doc/activesupport-3.1.0.beta1/rdoc lib --title activesupport-3.1.0.beta1 Documentation --quiet

That's what you get when you have rubygems 1.7.2. Just do a 

gem update --system

to get 1.8.0 (or whatever is the latest by your date) and the install will go smooth.

Could not find a JavaScript runtime (ExecJS::RuntimeError)

That happens when the ExecJS gem cannot find any javascript runtime installed on your computer. Just install nodejs for now and the error should disappear. I usually choose to install nodejs from the github repo. That way it's easier to get the latest and greatest quickly, rather than having to download and install a new pkg everytime.

And then go generate an app and run the dev server, it'll work. But just don't expect to checkout details of the changes to the frontend (the sass, coffee-script stuff). If you open app/assets/javascript/application.css you might notice a FIXME message. Things aren't that clear to me. Maybe I'll have to spend more time reading the available docs or I'll checkout the next beta (or the RC) and try creating an app with that. Like the release blog post on the rails blog mentions, there isn't enough documentation right now.

 

Posted
 

Creating git bundles you can clone from

I always thought git bundles were fancy to use. You could carry them on a drive and clone them without requiring the internet. I regularly update my basic rails bundle which I create from repos using

Trying to clone (git clone basic-rails.bundle) from that bundle gave me an error I couldn't understand. I had cloned from the bundle which I had created from a clean no-errors repo.

"warning: remote HEAD refers to nonexistent ref, unable to checkout"

A bit of googling and then someone's StackOverflow post enlightened me. It seems that to be able to clone from a bundle you have to use the --all flag like below.

And now when you try to clone from such a bundle, it'll work fine :)

I've created a github repo for my git bundles. Somehow I feel having bundles in a repo helps and is far better than creating a repo for each starter app.

Posted
 

Removing cached or initialized files from git [or what's happening when you think gitignore is broken]

Today I had a horrid 15min trying to figure out why git isn't ignoring my database config file inspite of adding that to the repo's .gitignore. I dug through the gitignore files of all my other repos and it seemed like I had done everything right but still the file I asked git to ignore wasn't being ignored.

Finally, found out what caused the issue. Me. I had already added the database config file to a repo. I should have added it to the .gitignore file even before trying to make my first commit. It seems that git tracks all files you add to it before adding it to .gitignore. So you'll have to remove it from git's cache when you add it to the .gitignore.

 

Posted
 

DrRacket's Stepper

I just started reading How to Design Programs (HTDP), a book that focuses on teaching the concepts of programming to the reader via Scheme. Now if you've read or heard of Structure and Interpretation of Computer Programs (SICP) but not HTDP and wondering why it isn't popular, this comment on Hacker News sums it up. Navigating through the online version of the book, it feels like it's a much better alternative to beginners, than SICP which assumes that you atleast have average math skills (my overall math skills are ok, but Calculus... I cannot drink and derive like many ;)

In section-2, the book mentions the use of the Stepper in DrRacket. I tried it assuming that it's going to suck, but the interface is the best I've seen for a stepper. Here's a bunch of screenshots taken while stepping through a simple program, with a procedure to evaluate the number, that results in the concatenation of the reverse of 3 integers (easier using string functions right? but we are asked to use a math formula which sounds cool actually).

Stepper-1
Stepper-2
Stepper-3
Stepper-4
Stepper-5

 

Most interfaces for debuggers are scary with a lot of buttons or text in the interface. But this interface impresses me. It's simple but versatile with step numbers, options to jump to any particular step, substitutes values in-place and also highlights them with a color pleasing to the eye (atleast to mine).

 

P.S: "convert3"??? I'm not bad at naming functions. When you name functions according to what the exercise in the book specifies, you get to test your programs with the TeachPacks that come with it (supported by DrRacket).

Posted
 

Automatically creating and switching gemsets for projects

I just forked a very useful trick from tundrax on the #ruby IRC.

Adding that to your project's dir's .rvmrc will automatically create (if necessary) and also automatically switch to the respective gemset, when you cd into the project's dir.

Posted
 

Latent type systems

A lot of people echo the fact that learning Lisp teaches you a lot of concepts in computer science. I was confused with choosing a particular implementation of Lisp (tried a bunch) and felt lazy to skim through the tutorial or documentation of each of those implementations of Lisp. Finally, I just decided to read the R5RS paper (A paper about Scheme). And I'm excited to say that I learnt something new while just reading the Overview section of the paper.

Scheme has latent as opposed to manifest types
And that caught my eye. A bit of searching led me here, which explains Latent type systems in a really simple way.

From my understanding of that awesome piece of explanation, labeling Lisp as a dynamically-typed language is very mis-leading.

"Latent" describes types from a syntactic perspective while the terms "Dynamic" or "Static" describes types from a run-time perspective.

And I'm sure that's confusing. Consider the following variable in Java:

String name;
(Yes! Java is static). And not latent. But the following is latent.

(define x 1)
You don't say it's of a particular type. The interpreter or compiler understands it and plays it's own game (static or dynamic). Now this might be dynamic or static in run-time, but just look at the syntax. It's LATENT :)

P.S: I guess a language like ruby is an example for having latent type system. But do correct me if I'm wrong. Really waiting for someone into Lisp to say if that's right.
Posted
 

Quickly finding model associations in rails

In Jan-2011, at my internship, I got a chance to work on a really complex application. And I had to get upto speed with everyone else by understanding the app and the reasons behind certain decisions. The one i worked on had more than two dozen models. Thanks to my commandLineFu, I accidentally, found a trick to list associations between models in a rails app in a readable way. And it's very simple.

From the root of the app (can be done from anywhere, but i'll just say I'm in the root of the app).

grep -ri "has_many" ./

Assuming you don't have the text "has_many" anywhere else in the app. If you do, just change ./ to app/models
The same can be done for belongs_to

grep -ri "belongs_to" ./

You'll be surprised to find that bash (ubuntu guy here!) gives you a really nice readable view of the associations. Each line, when read fully, shouts out the association :)
Posted