Installing eventmachine gem on El Capitan

I keep forgetting how to install eventmachine on El Capitan Mac OS X.

So adding this post to lookup when required.

$ gem install eventmachine -v '1.0.8' -- --with-cppflags=-I/usr/local/opt/openssl/include

More details can be found here and here

Log notes while stopping Org timer

Recently I started tracking the time I spent on various coding activities using Org mode. C-c C-x C-i is used to start the timer and C-c C-x C-o is used to stop the timer. I like to add some details about where the time was spent when the timer is stopped. Org mode allows to enter such notes using org-log-note-clock-out variable.

The description of this variable says -

Non-nil means record a note when clocking out of an item.

So I set the variable to true in my Org settings.

(setq org-log-note-clock-out t)

Now whenever I stop the timer, it opens a new buffer from where I can add a note describing what was done in that particular time.

My complete Org mode settings can be found here

Happy Hacking!

Configuring web-mode with JSX

I use web-mode for editing different templates like html, .erb, .js.jsx. It understands React’s JSX tags also which is great because I don’t need a separate mode just for JSX.

Web mode can support plain jsx or js.jsx by using auto-mode-alist function.

(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))

Here we use auto-mode-alist variable which associates major modes with file patterns so that when that file is opened, the major mode gets automatically activated.

The format is as follows:

(PATTERN . major-mode)

So \\.jsx\\' matches .jsx as well as .js.jsx files and enables web-mode for them. It also sets content-type as jsx for these files so that JSX tags get highlighted and indentation for JSX works properly.

React also allows JSX in plain .js files. My configuration for .js files was as follows:

(add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode))

But JSX tags don’t get highlighted and indentation also does not work with above configuration in plain .js files.

This happens because content-type is set to javascript instead of jsx.

This problem can be solved using adding a hook when web-mode as suggested in this issue.

(add-hook 'web-mode-hook
  (lambda ()
  (web-mode-set-content-type "jsx")
  (message "now set to: %s" web-mode-content-type)))

But problem with this approach is, it sets content-type as jsx for all files like .html or .erb. Due to this indentation of ERB code stopped working.

To solve this, I updated the hook as follows:

(add-hook 'web-mode-hook
  (lambda ()
  (if (equal web-mode-content-type "javascript")
  (web-mode-set-content-type "jsx")
  (message "now set to: %s" web-mode-content-type))))

Now the content-type will be set to jsx only when original content-type is javascript. This solved the issue completely as normal HTML and ERB files work as before and JSX tags and indentation works in plain JavaScript files.

My complete configuration of web mode can found on Github.

Update

Author of web-mode, François-Xavier Bois suggested to me that web-mode-content-types-alist variable provided by web-mode can be used to achieve same thing.

Based on his suggestion, we can force content-type as jsx for files ending with .js and .jsx.

(setq web-mode-content-types-alist
  '(("jsx" . "\\.js[x]?\\'")))

This will force web-mode’s content type as jsx for .js and .jsx files. This is much cleaner than using a hook and also we are using feature designed specifically for this use case. Thanks Francois!

Happy Hacking!

Talk on React.js at RedDotRubyConf 2015

I gave a talk at Red Dot Ruby Conf Singapore in June on React.js.

Here are the slides for the talk.

The video is also uploaded thanks to Confreaks.

Replace character with newline in Emacs

I keep forgetting about newline character in Emacs. Whenever I want to replace a character with newline, I always google. So I decided to blog about it so as to not google each time.

C-q C-j is newline character in Emacs.

To replace a character with it,

M-x replace-string RET;
<string to replace> RET;
C-q C-j RET;

Talk at Garden City Ruby Conf

Recently, I and Vipul gave a talk at Garden City Ruby Conf. Here are our slides for the talk.

The code examples used in the presentation can be found on GitHub.

kgio, raindrops, unicorn and Ruby 2.2.0-preview1

I was trying to upgrade Codetriage to use Ruby 2.2.0-preview, the latest Ruby version. The project is hosted on Heroku. So to upgrade I changed Ruby version in Gemfile:

# Gemfile
ruby '2.2.0'

After that I tried to do bundle install:

bundle install

And boom. Got error:

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /Users/prathamesh/.rbenv/versions/2.2.0-preview1/bin/ruby -r ./siteconf20141002-23644-1wbcnhc.rb extconf.rb
.....
creating Makefile

make "DESTDIR=" clean

make "DESTDIR="
compiling accept.c
In file included from accept.c:90:
/Users/prathamesh/.rbenv/versions/2.2.0-preview1/include/ruby-2.2.0/ruby/backward/rubysig.h:14:2: warning: rubysig.h is obsolete [-W#warnings]
#warning rubysig.h is obsolete
 ^
accept.c:101:2: error: use of undeclared identifier 'TRAP_BEG'
        TRAP_BEG;
        ^
accept.c:103:2: error: use of undeclared identifier 'TRAP_END'
        TRAP_END;
        ^
1 warning and 2 errors generated.
make: *** [accept.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/prathamesh/.rbenv/versions/2.2.0-preview1/lib/ruby/gems/2.2.0/gems/kgio-2.8.0 for inspection.
Results logged to /Users/prathamesh/.rbenv/versions/2.2.0-preview1/lib/ruby/gems/2.2.0/extensions/x86_64-darwin-13/2.2.0-static/kgio-2.8.0/gem_make.out
An error occurred while installing kgio (2.8.0), and Bundler cannot continue.
Make sure that `gem install kgio -v '2.8.0'` succeeds before bundling.

kgio gem is dependency of unicorn which is the application server used by Codetriage. Looking at documentation of kgio, I found out that latest gem version is 2.9.2 while as our Gemfile.lock still had 2.8.0.

The exact changelog entry is:

commit 6243d74cc8296d40a66969594e42963c896968ee
Author: Eric Wong <e@80x24.org>
Date:   Sat Feb 15 09:21:07 2014 +0000

    kgio 2.9.2 - avoid deprecated/removed function

    This release is for compatibility with future releases of mainline ruby,
    as rb_thread_blocking_region is removed in r44955 of ruby trunk
    This also avoids deprecation warnings fo rb_thread_blocking_region
    2.0 and 2.1.

So looks like this is the version that should be used with new versions of Ruby.

Solution

Replaced 2.8.0 with 2.9.2 for kgio gem in Gemfile.lock:

# Gemfile.lock
      multi_json (>= 1.5)
    kgio (2.9.2)
    kramdown (1.3.2)

After updating Gemfile.lock and running bundle install again, it completed successfully. I was able to run the app using Unicorn on Ruby 2.2.0-preview1.

See this PR to see more details.

Happy Hacking!

Update

After i submitted the PR, the tests could not be run on Travis because of error related to installing raindrops gem which is also dependency of Unicorn:

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
    /home/travis/.rvm/rubies/ruby-2.2.0-preview1/bin/ruby -r ./siteconf20141002-1677-1g08hg8.rb extconf.rb
....
linux_inet_diag.c:28:2: error: ‘TRAP_BEG’ undeclared (first use in this function)
linux_inet_diag.c:28:2: note: each undeclared identifier is reported only once for each function it appears in
linux_inet_diag.c:30:2: error: ‘TRAP_END’ undeclared (first use in this function)
linux_inet_diag.c: At top level:
linux_inet_diag.c:22:1: warning: ‘rb_thread_blocking_region’ defined but not used [-Wunused-function]
make: *** [linux_inet_diag.o] Error 1

I did not had this problem locally when I did bundle install. But to fix this, I again checked documentation for raindrops. Turns out that the latest release of raindrops is 0.13.0 whereas Gemfile.lock was still pointing to 0.11.0. Also this release is specific to 2.2.0 according to changelog.

commit d24900b305a02cdedc4a532253798117f9686b5c
Author: Eric Wong <e@80x24.org>
Date:   Tue Feb 18 20:57:46 2014 +0000

    raindrops 0.13.0  several minor fixes and improvements

    Most notably, this release is necessary for Ruby 2.2 (dev).
    Thanks to Koichi Sasada for the bug report!

    Eric Wong (5):
          Rakefile: remove raa_update task
          last_data_recv: do not assume Unicorn includes all constants
          raindrops.gemspec: add wrongdoc dev dependency
          linux_inet_diag: fix Ruby 2.2 (dev) build
          license: use LGPLv2.1 or later (was LGPL (2.1|3.0)-only)

    Hleb Valoshka (1):
          Remove Scope IDs from IPv6 addresses.

Again applied same fix by changing Gemfile.lock and now raindrops is installed on Travis.

After effects of updating openssl on Mac OS X

Today, my openssl library on Mac OS X Mavericks got updated. After the update, when i tried doing rails s on one of the rails apps, it gave following error:

/Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/railties-4.2.0.beta1/lib/rails/app_rails_loader.rb:39: warning: Insecure world writable dir /usr in PATH, mode 040777
/Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/bundler-1.7.2/lib/bundler.rb:302: warning: Insecure world writable dir /usr in PATH, mode 040777
/Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/2.1.0/openssl.rb:17:in `require': dlopen(/Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle, 9): Symbol not found: _SSLv2_client_method (LoadError)
  Referenced from: /Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle
  Expected in: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
 in /Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle - /Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/2.1.0/x86_64-darwin13.0/openssl.bundle
	from
    /Users/prathamesh/.rbenv/versions/2.1.2/lib/ruby/2.1.0/openssl.rb:17:in
    `<top (required)>'

Seems like the link between openssl and Ruby is broken after the update. Fortunately the fix is very simple. Re-install Ruby again. It will re-link the updated openssl and this problem will be gone.

$ rbenv install 2.1.2      [2.1.2]
rbenv: /Users/prathamesh/.rbenv/versions/2.1.2 already exists
continue with installation? (y/N) y
Downloading ruby-2.1.2.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/a5b5c83565f8bd954ee522bd287d2ca1
Installing ruby-2.1.2...

After installing the Ruby again, rails s started without any complains.

Hope this saves some time to somebody! Happy Hacking :)

Talk at RubyKaigi

Recently, I gave a talk at RubyKaigi 2014. It was pretty awesome to talk at RubyKaigi. Here are my slides for the talk.

And here is the video.

Setting up Ruby development setup with rbenv

I wanted to setup ruby source code on my machine. The source on Github has detailed instructions on how to do the setup.

git clone github.com/ruby/ruby
cd ruby
autoconf
./configure
make
make install

worked correctly on Mac OS X and Ruby was installed in usr/local/bin.

I use rbenv for managing Ruby versions. After setting up the Ruby from source, i wanted to use it using rbenv. Why? It will make very easy to switch between dev version and normal version. rbenv shell ruby-dev, do something, make some changes, compile again, test again. rbenv shell 2.1.2, and back to normal.

But as the source Ruby was installed in usr/local/bin, rbenv was not able to find it.

I asked question on #ruby on IRC and Postmodern pointed me to this.

It mentions passing --prefix option to the ./configure command. We can pass the name of directory where we want to install Ruby to this option.

So we can run

./configure --prefix=PATH_TO_INSTALL_RUBY

rbenv by default, installs all rubies in ~/.rbnev/versions

And when we do rbenv versions, it looks for all rubies installed in this directory and lists them.

The content of my ~/.rbnev/versions directory looked like these:

prathamesh ~/.rbenv/versions 2.0.0
$ ls
2.0.0-p247 2.0.0-p353 2.0.0-p481 2.1.0      2.1.1      2.1.2      rbx-2.2.6

prathamesh ~/.rbenv/versions 2.0.0

Now if we give prefix path to configure command, the dev-ruby will be installed in ~/.rbenv/versions

./configure --prefix="$HOME/.rbenv/versions/ruby-dev"

After make and make install, dev ruby was installed in ~/.rbnenv/versions in ruby-dev directory.

Now rbenv versions output had ruby-dev also.

prathamesh ~/.rbenv/versions 2.0.0
$ rbenv versions
* system (set by /Users/prathamesh/.rbenv/version)
  2.0.0-p247
  2.0.0-p353
  2.0.0-p481
  2.1.0
  2.1.1
  2.1.2
  rbx-2.2.6
  ruby-dev

prathamesh ~/.rbenv/versions 2.0.0

As ruby-dev is listed by rbenv versions, i can switch to it easily:

rbenv shell ruby-dev

This sets up Ruby dev version on my machine and also allows me to switch back and forth using rbenv.