<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener("load", function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <iframe src="http://www.blogger.com/navbar.g?targetBlogID=7625526986034013157&amp;blogName=Tim%2C+the+Enchanter&amp;publishMode=PUBLISH_MODE_HOSTED&amp;navbarType=BLUE&amp;layoutType=CLASSIC&amp;searchRoot=http%3A%2F%2Ftim.theenchanter.com%2Fsearch&amp;blogLocale=en&amp;homepageUrl=http%3A%2F%2Ftim.theenchanter.com%2F" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" height="30px" width="100%" id="navbar-iframe" allowtransparency="true" title="Blogger Navigation and Search"></iframe> <div></div>

About

I'm a ruby developer passionate about developing clean code that makes for programming happiness. I'm also am passionate about freedom, liberty, and capitalism, and enjoy jamming out some good rock or jazz on the piano.

I'm a family man and a I'm a member of The Church of Jesus Christ of Latter Day Saints (AKA the "Mormons") and I wield a strong testimony of my Savior Jesus Christ (yes we're Christians).

I'm currently employed by:

Getting ruby to use readline instead of libedit Saturday, January 30, 2010 |

I prefer readline for a variety of reasons:
  • I'm used to it, it's the same command editor that powers bash
  • It's very powerful.
  • In Ruby, it doesn't block other threads from running while waiting for input.
When I installed ruby 1-9 using rvm, it got compiled against libedit. I didn't feel like reinstalling, so I followed these instructions over here.

I'd thought that `port install readline` would suffice, but it didn't. I had to install readline-6.0 from source. Ruby doesn't compile against readline-5.0, it just spits out a load of errors. The following is what I did, if you would like to follow along:

Install readline: (copied from here)
curl -O ftp://ftp.cwru.edu/pub/bash/readline-6.0.tar.gz
tar xvf readline-6.0.tar.gz
cd readline-6.0
./configure && make && sudo make install

Then, go into the src folder where rvm built your ruby. Mine was ~/.rvm/src/ruby-1.9.1-p378/ext/readline.
cd ~/.rvm/src/ruby-1.9.1-p378/ext/readline # <- your path will vary
ruby extconf.rb
Make sure you see this line in the output:
checking for readline/readline.h... yes
If it says no, it didn't find your readline. You might have luck trying to set the C_INCLUDE_PATH=/usr/local/include Then, build it:
make
When it finishes, run otool -l readline.bundle. You should see this:
       name /usr/local/lib/libreadline.6.0.dylib (offset 24)
 time stamp 2 Wed Dec 31 17:00:02 1969
    current version 6.0.0
compatibility version 6.0.0
If you see libedit anywhere in that output, it didn't link against libreadline. Failure. Now, if it's all successful, install the new readline.bundle.
  mv readline.bundle ../../../../rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i386-darwin9.8.0/readline.bundle

(as usual, your path will vary)

Good luck!

Update:

I tried to do these instructions with Ruby 1.8.7, and didn't have any luck. After googling around some, I found that while extconf.rb was finding /usr/local/include/readline/readline.h, it was in fact using /usr/include/libedit/readline.h during buildtime, causing this:

  gcc -I. -I. -I/Users/timcharper/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/1.8/i686-darwin9.8.0 -I. -DHAVE_READLINE_READLINE_H -DHAVE_READLINE_HISTORY_H -DHAVE_RL_DEPREP_TERM_FUNCTION -DHAVE_RL_COMPLETION_APPEND_CHARACTER -DHAVE_RL_BASIC_WORD_BREAK_CHARACTERS -DHAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS -DHAVE_RL_BASIC_QUOTE_CHARACTERS -DHAVE_RL_COMPLETER_QUOTE_CHARACTERS -DHAVE_RL_FILENAME_QUOTE_CHARACTERS -DHAVE_RL_ATTEMPTED_COMPLETION_OVER -DHAVE_RL_LIBRARY_VERSION -DHAVE_RL_EVENT_HOOK -DHAVE_RL_CLEANUP_AFTER_SIGNAL -DHAVE_REPLACE_HISTORY_ENTRY -DHAVE_REMOVE_HISTORY  -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE   -fno-common -g -O2 -pipe -fno-common   -c readline.c
  readline.c: In function ‘filename_completion_proc_call’:
  readline.c:703: error: ‘filename_completion_function’ undeclared (first use in this function)
  readline.c:703: error: (Each undeclared identifier is reported only once
  readline.c:703: error: for each function it appears in.)
  readline.c:703: warning: assignment makes pointer from integer without a cast
  readline.c: In function ‘username_completion_proc_call’:
  readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
  readline.c:730: warning: assignment makes pointer from integer without a cast
  make: *** [readline.o] Error 1

To resolve it, I signaled extconf.rb to force it to use /usr/local/include

  ruby extconf.rb --with-readline-dir=/usr/local
  make clean
  make

Update 2:

If another version of Ruby is used to run the extconf.rb then the target version of Ruby for which you are compiling read line, you will get another stream of build errors, perhaps something like this:

gcc -I. -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 -I. -DHAVE_READLINE_READLINE_H -DHAVE_READLINE_HISTORY_H -DHAVE_RL_DEPREP_TERM_FUNCTION -DHAVE_RL_COMPLETION_APPEND_CHARACTER -DHAVE_RL_BASIC_WORD_BREAK_CHARACTERS -DHAVE_RL_COMPLETER_WORD_BREAK_CHARACTERS -DHAVE_RL_BASIC_QUOTE_CHARACTERS -DHAVE_RL_COMPLETER_QUOTE_CHARACTERS -DHAVE_RL_FILENAME_QUOTE_CHARACTERS -DHAVE_RL_ATTEMPTED_COMPLETION_OVER -DHAVE_RL_LIBRARY_VERSION -DHAVE_RL_EVENT_HOOK -DHAVE_RL_CLEANUP_AFTER_SIGNAL -DHAVE_REPLACE_HISTORY_ENTRY -DHAVE_REMOVE_HISTORY -I/usr/local/include   -fno-common -arch ppc -arch i386 -Os -pipe -fno-common  -c readline.c
readline.c: In function ‘readline_readline’:
readline.c:82: error: ‘rb_io_t’ undeclared (first use in this function)
readline.c:82: error: (Each undeclared identifier is reported only once
readline.c:82: error: for each function it appears in.)
readline.c:82: error: ‘ofp’ undeclared (first use in this function)
readline.c:82: error: ‘ifp’ undeclared (first use in this function)
readline.c: In function ‘filename_completion_proc_call’:
readline.c:703: error: ‘filename_completion_function’ undeclared (first use in this function)
readline.c:703: warning: assignment makes pointer from integer without a cast
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: warning: assignment makes pointer from integer without a cast
readline.c: In function ‘readline_readline’:
readline.c:82: error: ‘rb_io_t’ undeclared (first use in this function)
readline.c:82: error: (Each undeclared identifier is reported only once
readline.c:82: error: for each function it appears in.)
readline.c:82: error: ‘ofp’ undeclared (first use in this function)
readline.c:82: error: ‘ifp’ undeclared (first use in this function)
readline.c: In function ‘filename_completion_proc_call’:
readline.c:703: error: ‘filename_completion_function’ undeclared (first use in this function)
readline.c:703: warning: assignment makes pointer from integer without a cast
readline.c: In function ‘username_completion_proc_call’:
readline.c:730: error: ‘username_completion_function’ undeclared (first use in this function)
readline.c:730: warning: assignment makes pointer from integer without a cast
lipo: can't open input file: /var/folders/jz/jzGJ6Q4BFumSODlDitruR++++TM/-Tmp-//ccvDT283.out (No such file or directory)
make: *** [readline.o] Error 1

To resolve, run extconf.rb with the same version of Ruby for which you are recompiling readline.


Update 3:

ruby 1.8.6 and ruby 1.8.7 appear to have their threads (and signals) blocked by readline now. This seems to be a recent development as I have used readline with ruby 1.8.6 without blocking threads in a past build.

Ruby 1.9.1 doesn't currently block threads with readline

Open in Emacs finder droplet Wednesday, January 6, 2010 |

Here's a handy finder droplet to open a file in Emacs (for MacOS X): OpenInEmacs Here's how you install it / use it: Demo Video