Readline() with editing and history?

Hello!

I’m looking for a readline() with history and editing support (like
perl’s
Term::Readline). Does such a thing exist for ruby?

On 9/15/06, Josef W. [email protected] wrote:

Hello!

I’m looking for a readline() with history and editing support (like perl’s
Term::Readline). Does such a thing exist for ruby?

require ‘readline’

It comes with Ruby.

On Sat, Sep 16, 2006 at 01:58:27AM +0900, Kent S. wrote:

On 9/15/06, Josef W. [email protected] wrote:

I’m looking for a readline() with history and editing support (like perl’s
Term::Readline). Does such a thing exist for ruby?

require ‘readline’

It comes with Ruby.

Thanks for your quick reply, Kent! But somehow I don’t get it:

jw@raven> irb
irb(main):001:0> require ‘readline’
=> false
irb(main):002:0> readline
asdf^[[D^[[D^[[A^[[A
=> “asdf\e[D\e[D\e[A\e[A\n”

The ^[[D is the result of the up-arrow and ^[[A is the result of the
left-arrow. “ri readline” mentiones:

 IO::readlines, IO#readline, IO#readlines, Kernel#readlines,
 Kernel#readline, Pathname#readlines, Zlib::GzipReader#readline,
 Zlib::GzipReader#readlines

But none of them seem to support line-editing or history. :frowning:

Any idea what is going wrong here?

Josef W. wrote:

On Sat, Sep 16, 2006 at 01:58:27AM +0900, Kent S. wrote:

On 9/15/06, Josef W. [email protected] wrote:

I’m looking for a readline() with history and editing support (like perl’s
Term::Readline). Does such a thing exist for ruby?

Here’s a simple example that shows line editing and history (completion
is a little more complicated, but I can give you an example):

#!/usr/bin/env ruby

require “readline”

class Shell
include Readline

def initialize

 puts
 puts 'type "Q" or ^D to quit.'
 puts

 while true do

   line = readline("> ", true)

   if not line
     puts
     break
   end

   if /q/i === line
     break
   end

   puts "You typed #{line.inspect}"

 end

end

end

if FILE == $0
Shell.new
end

On Sat, 16 Sep 2006 02:41:17 +0900, Josef W. wrote:

 IO::readlines, IO#readline, IO#readlines, Kernel#readlines,
 Kernel#readline, Pathname#readlines, Zlib::GzipReader#readline,
 Zlib::GzipReader#readlines

But none of them seem to support line-editing or history. :frowning:

Any idea what is going wrong here?

you need to include the Readline module that is contained within the
‘readline’ file. So the instructions should actually have been

require ‘readline’
include Readline

On Sat, Sep 16, 2006 at 06:42:24AM +0900, Rick DeNatale wrote:

My guess is that your installation of Ruby didn’t successfully install
the readline extension.

The following is based on linux, if you are are on Windows or Mac,
things might be different.

How did you install Ruby? If you installed it as a package then you
might need a separate package to get readline, for example
debian/ubuntu has a separate libreadline-ruby package.

This is suse-10.0 with ruby-1.8.2. I have installed all ruby-related
packages. There’s no such package like libreadline-ruby.

On 9/15/06, Josef W. [email protected] wrote:

 IO::readlines, IO#readline, IO#readlines, Kernel#readlines,
 Kernel#readline, Pathname#readlines, Zlib::GzipReader#readline,
 Zlib::GzipReader#readlines

But none of them seem to support line-editing or history. :frowning:

Any idea what is going wrong here?

My guess is that your installation of Ruby didn’t successfully install
the readline extension.

The following is based on linux, if you are are on Windows or Mac,
things might be different.

How did you install Ruby? If you installed it as a package then you
might need a separate package to get readline, for example
debian/ubuntu has a separate libreadline-ruby package.

If you installed ruby from source, then readline probably didn’t build
when you built ruby because you don’t have the required source files
for the interfaces to the readline library, in which case you need to
figure out what you need and rebuild the readline extension. If this
is the case come back and we can probably work you through it.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Marc H. wrote:

“If you installed ruby from source, then readline probably didn’t build
when you built ruby because you don’t have the required source files
for the interfaces to the readline library”

I think it would be awesome if a check could be added to the configure
script, ie --enable-readline or similar. And when it cant be found,
it wont try to compile ruby so that you can timely compile/install
readline first again. :slight_smile:

here’s the bit to test if readline is compiled in, from Pragmatic’s
“Rails Recipes” (which is simply outstanding)

ruby -rreadline ‘p Something’

( I was going to say i can’t recommend the book highly enogh, but i
think that’s ambiguous)

Gene T. wrote:

here’s the bit to test if readline is compiled in, from Pragmatic’s
“Rails Recipes” (which is simply outstanding)

Oops, should be:

ruby -rreadline -e ‘p Something’

“If you installed ruby from source, then readline probably didn’t build
when you built ruby because you don’t have the required source files
for the interfaces to the readline library”

I think it would be awesome if a check could be added to the configure
script, ie --enable-readline or similar. And when it cant be found,
it wont try to compile ruby so that you can timely compile/install
readline first again. :slight_smile:

On 9/16/06, Marc H. [email protected] wrote:

“If you installed ruby from source, then readline probably didn’t build
when you built ruby because you don’t have the required source files
for the interfaces to the readline library”

I think it would be awesome if a check could be added to the configure
script, ie --enable-readline or similar. And when it cant be found,
it wont try to compile ruby so that you can timely compile/install
readline first again. :slight_smile:

Or maybe not, since it is an optional feature, I don’t know that you
really want to make sure that all of the optional features, some of
which you might not want or need are there before you can use ruby at
all.

However, you don’t need to completely re-build ruby to add an
extension which wasn’t built originally. The build process for
extensions uses ruby to build the make file for each extension, and
what gets tried is logged. So in the ruby source directory theres a
subdirectory called ext, which has a subdirectory for each extension.

in ext/readline you should find a file called mkmf.log which is the
log of what happened when the makefile for readline was being built.
When it’s failed for me it’s usually because I didn’t have one of the
development include files for the library or libraries the extension
was using.

When you figure out what needs to be fixed, from the extensions
directory you can try to rebuild the extensions make file with:

 ruby extconf.rb

which when all goes well builds a makefile for the extension for your
environment.
then
make
and
make install


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Sep 17, 2006, at 11:31 AM, Josef W. wrote:

Are
there different libraries? “ri readline” says:

$ ri Kernel#readline
-------------------------------------------------------- Kernel#readline
readline(separator=$/) => string

  Equivalent to Kernel::gets, except readline raises EOFError at end
  of file.

Not what you want. You want Readline#readline.

$ ruby -rreadline -e ‘Readline.readline’

See Joel VanderWerf’s post for a complete example (he includes
Readline into his class).

– Daniel

On Sun, Sep 17, 2006 at 01:36:05AM +0900, Gene T. wrote:

Gene T. wrote:

here’s the bit to test if readline is compiled in, from Pragmatic’s
“Rails Recipes” (which is simply outstanding)

Oops, should be:

ruby -rreadline -e ‘p Something’

Actually, readline is available. It just don’t support line-editing
and
history:

$ ruby -rreadline -e ‘p readline’
asdfsfs^[[D^[[D
“asdfsfs\e[D\e[D\n”
$

So what might be the reason that history/editing is not supported? Are
there different libraries? “ri readline” says:

More than one method matched your request. You can refine
your search by asking for information on one of:

    IO::readlines, IO#readline, IO#readlines, Kernel#readlines,
    Kernel#readline, Pathname#readlines, Zlib::GzipReader#readline,
    Zlib::GzipReader#readlines

On Sun, Sep 17, 2006 at 06:38:31PM +0900, Daniel H. wrote:

On Sep 17, 2006, at 11:31 AM, Josef W. wrote:

Not what you want. You want Readline#readline.

$ ruby -rreadline -e ‘Readline.readline’

Ah, now I get it! Thanks Daniel!

BTW: what are readline’s parameters? ri don’t seem to know about this
method. And the PickAxe don’t say anything about the parameters,
too.

See Joel VanderWerf’s post for a complete example (he includes
Readline into his class).

I have not tried his example because I assumed the library could not be
loaded. I was confused by the fact that “require ‘readline’” returns
“false”. Isn’t require supposed to return “true” if successful?

On Sun, Sep 17, 2006 at 08:01:17PM +0900, Josef W. wrote:

I have not tried his example because I assumed the library could not be
loaded. I was confused by the fact that “require ‘readline’” returns
“false”. Isn’t require supposed to return “true” if successful?

The return value of require is borderline meaningless. If require
returns false, that just means that the file has already been require’d.
If it can’t require the file for whatever reason it will raise and
exception, not return false.

On Mon, Sep 18, 2006 at 02:31:30AM +0900, Josef W. wrote:

On Mon, Sep 18, 2006 at 01:50:36AM +0900, Logan C. wrote:

On Sun, Sep 17, 2006 at 08:01:17PM +0900, Josef W. wrote:

I have not tried his example because I assumed the library could not be
loaded. I was confused by the fact that “require ‘readline’” returns
“false”. Isn’t require supposed to return “true” if successful?
The return value of require is borderline meaningless. If require
returns false, that just means that the file has already been require’d.

Are you sure with this? I get false even on the first require.
Are you sure it’s the first require? :wink: For instance, I load readline in
my irbrc so I get the fancy line editing.
Try: RUBYOPT="" ruby -e ‘p require(“readline”)’

Or alternatively before doing require ‘readline’, do
$LOADED_FEATURES.grep(/readline/)

If it can’t require the file for whatever reason it will raise and
exception, not return false.

Maybe this should be mentioned in the documentation? Currently, it says:

 Ruby tries to load the library named _string_, returning +true+ if
 successful.  [ ... ]

Well yeah if it’s already require’d it didn’t sucessful load it (since
its already been loaded :wink: ).

On Mon, Sep 18, 2006 at 01:50:36AM +0900, Logan C. wrote:

On Sun, Sep 17, 2006 at 08:01:17PM +0900, Josef W. wrote:

I have not tried his example because I assumed the library could not be
loaded. I was confused by the fact that “require ‘readline’” returns
“false”. Isn’t require supposed to return “true” if successful?
The return value of require is borderline meaningless. If require
returns false, that just means that the file has already been require’d.

Are you sure with this? I get false even on the first require.

If it can’t require the file for whatever reason it will raise and
exception, not return false.

Maybe this should be mentioned in the documentation? Currently, it
says:

 Ruby tries to load the library named _string_, returning +true+ if
 successful.  [ ... ]

On Mon, Sep 18, 2006 at 02:42:57AM +0900, Logan C. wrote:

my irbrc so I get the fancy line editing.
Hmm, I don’t have an irbrc. I’ve just checked: only irb returns false,
so
probably irb loads it even if no irbrc exists.

Try: RUBYOPT="" ruby -e ‘p require(“readline”)’

Or alternatively before doing require ‘readline’, do
$LOADED_FEATURES.grep(/readline/)

$ RUBYOPT="" ruby -e ‘p require(“readline”)’
true
$ ruby -e ‘p $LOADED_FEATURES.grep(/readline/)’
[]
$

If it can’t require the file for whatever reason it will raise and
exception, not return false.

Maybe this should be mentioned in the documentation? Currently, it says:

 Ruby tries to load the library named _string_, returning +true+ if
 successful.  [ ... ]

Well yeah if it’s already require’d it didn’t sucessful load it (since
its already been loaded :wink: ).

I find such behavior somewhat irritating. IMHO, “load not successful”
is
semantically aequivalent to “library not available”. It is not
documented
that require will raise an exception. So the return value is the only
(official) way to find out whether the library is available.