Eric Lippert has a post where he talks about idempotencce. He points out that in programming when we say a function is idempotent we mean:
the effect of the function … is invariant over the number of calls.
In other words, if we call the same function over and over again, the state of the system will be the same as if we’d called the function only once. That can be a big help, because the invariant “this function has been called at least once” is a ton easier to maintain than the invariant “this function has been called exactly once.”
I like idempotence in configuration and set up code. Let’s take a line from my Vagrantfile for this project. (It’s inside an call to the shell script. In Ruby it’s a string literal; we’re interested in what it does in the shell.)
git --version || apt-get install -y git
In other words, “If git is installed, do nothing; otherwise install git.” You’ll notice that no matter how often I run this line, I’ll always have git installed, but the installer won’t check update or anything except for the first time this is run. This is awesome in configuration, because it lets us write commands that say “assert that this is installed,” and not have to remove them later.
Ok, so idempotent is a favorite word, but I’m done talking about it for now. Let’s move on getting some rails done. For this post, I’m going to do part of the rails tutorial book, but I’m going to use this little Vagrant VM we’re working on as the development environment.
Anyway, I wanted get the hello world app working on ruby. Apparently
rails new (sitename) will create an app, and
rails server will run it. I had a little trouble with port forwarding on Windows. Launching the app with
rails server works, in the sense that it launches the app and that other shell windows that are SSHed into my VM can do
curl localhost:3000 and see a response. But it doesn’t work in that I can’t call localhost:3000 from my host machine. I tried configuring some different ports in my Vagrantfile, but without any luck. Then I found some post (which I can’t find again to give credit to, sadly) saying that instead of
rails server, I should run
bundle exec puma -C config/puma.rb to force the server to use the config file. This worked, and the port on my host machine that is forwarded to 3000 on the guest machine indeed hits the rails server now. First difficulty cleared.
The second difficulty was when I scaffolded a “Users” table using
runtimes.rb file, but node is so widely used now that I don’t feel bad taking it as a dependency.
In short, running on through the toy app part of the rails tutorial book works fine, with the two differences:
- We need to launch the server with
bundle exec puma -C config/puma.rbinstead of with
- We need to either install node, or make some changes to ExecJs’s file called
Next time, we’ll try to make some more progress into the rails tutorial book.
Till then, happy learning!