readline() with editing and history?

J

Josef Wolf

Hello!

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

Josef Wolf

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. :-(

Any idea what is going wrong here?
 
J

Joel VanderWerf

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
 
R

Rick DeNatale

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. :-(

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.
 
K

Ken Bloom

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. :-(

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
 
J

Josef Wolf

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.
 
M

Marc Heiler

"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. :)
 
G

Gene Tani

Marc said:
"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. :)

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)
 
G

Gene Tani

Gene said:
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'
 
R

Rick DeNatale

"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. :)

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
 
J

Josef Wolf

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
 
D

Daniel Harple

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:


$ 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
 
J

Josef Wolf

On Sep 17, 2006, at 11:31 AM, Josef Wolf 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?
 
L

Logan Capaldo

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.
 
J

Josef Wolf

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. [ ... ]
 
L

Logan Capaldo

Are you sure with this? I get false even on the _first_ require.
Are you sure it's the first require? ;) 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 ;) ).
 
J

Josef Wolf

Are you sure it's the first require? ;) For instance, I load readline in
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 ;) ).

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,212
Messages
2,571,102
Members
47,697
Latest member
looped_monk

Latest Threads

Top