Here's a readline-enabled version of eval.rb that I've had lying around
for awhile. It's a modified version of eval.rb and doesn't require any
changes to jruby to run. It's not sophisticated at all; it's basically
eval.rb with readline's ability to do editing, history, etc. Since I
based the readline part on some java code, it has some java-isms in it
rather than doing things the ruby way. Any bugs should probably be
blamed on the original eval.rb. :)
It's been tested on linux (I don't know if Win has a version of
libreadline-java). You need to have libreadline-java.jar on your
classpath and java also needs to be able to load libJavaReadline.so. So
this does not fulfill a pure java requirement, but it's been enough to
keep me from pulling my hair out.
It handles both ruby exceptions and java ones. You can exit by hitting
C-d.
The indenting is pretty unreliable (it's based on eval.rb) so I would
suggest setting it to 0.
You can specify which readline library to load by editing the string at
the top of the file. You can use something other than GnuReadline
(Editline?) if that causes a licensing problem.
If you put the file into lib/ruby/site_ruby, you can start it with a
shell script similar to this:
#! /bin/sh
export JAVA_HOME=/opt/java
export JRUBY_HOME=/opt/jruby/cvs/jruby
export READLINE=/usr/share/java/libreadline-java.jar
export CLASSPATH=$CLASSPATH:$READLINE:$JRUBY_HOME/lib/jruby.jar:.
exec $JAVA_HOME/bin/java -classpath $CLASSPATH org.jruby.Main
-I$JRUBY_HOME/lib/ruby/site_ruby -reval_readline "$@"
Wes
On Thu, 9 Feb 2006, Charles O Nutter wrote:
| It's become increasingly irritating that there's nothing equivalent to
| IRB that works with JRuby on the command-line. I'm personally tired of
| having a stack of test*.rb files around or using cumbersome -e strings
| to try out every little thing I need to test while working on JRuby.
| Something better is needed.
|
| Could Ruby's IRB be modified to work correctly with JRuby? I know it
| currently doesn't work because we don't have the terminal reading and
| manipulating capabilities necessary in Java, but could those
| requirements be ripped out?
|
| Is there an alternative to IRB that would work in JRuby? I'm not
| looking for anything fancy; just a basic interactive environment that
| I can run easily from the command-line.
|
| Could we just start working on our own simpler "jirb" so there's
| something roughly equivalent to IRB in the JRuby standard distro?
| How's this for a completely naive approach (that doesn't support
| multi-line constructs, naturally):
|
| STDOUT << '> '
|
| while (x =
--
# Wes Nakamura <[EMAIL PROTECTED]>
# configuration
readline_library = "GnuReadline"
indent_width = 0
prompt = "jruby"
# end configuration
require 'java'
$java_classes = [
'java.io.File',
'java.io.BufferedReader',
'java.lang.System',
'java.io.EOFException',
'org.gnu.readline.ReadlineReader',
'org.gnu.readline.ReadlineLibrary'
]
include_class($java_classes) { | p, n | "J" + n }
history = JFile.new(JSystem.getProperty("user.home") + File::Separator +
".#{prompt}_history")
history.createNewFile()
if history.canWrite() && history.canRead()
readline_reader = JReadlineReader.new("#{prompt}% ", history,
JReadlineLibrary.byName(readline_library))
else
readline_reader = JReadlineReader.new("#{prompt}% ",
JReadlineLibrary.byName(readline_library))
end
buffered_readline_reader = JBufferedReader.new(readline_reader)
code = ''
indent = 0
$stdout.sync = true
puts "jruby %s [%s] (ruby %s, %s)" % [ VERSION, RUBY_PLATFORM, RUBY_VERSION,
RELEASE_DATE ]
loop {
begin
line = buffered_readline_reader.readLine()
rescue JEOFException => e
buffered_readline_reader.close()
puts
exit
end
code << line << "\n"
case line
when /[,\[\{]\s*$/
readline_reader.setPrompt("#{prompt}| ")
next
when /^\s*(class|module|def|if|unless|case|while|until|for|begin)\b[^_]/
indent += 1
when /^\s*end\b[^_]?/
indent -= 1
when /\{\s*(\|.*\|)?\s*$/
indent += 1
when /^\s*\}/
indent -= 1
end
if indent > 0
readline_reader.setPrompt("#{prompt}| " + (" " * indent_width))
next
end
begin
print "<", eval(code).inspect, ">\n"
rescue ScriptError, StandardError
$! = 'exception raised' if ! $!
print "ERR: ", $!, "\n"
rescue NativeException => e
$! = 'exception raised' if ! $!
print "ERR: ", $!, "\n"
print " ", e.cause(), "\n"
end
code = ''
readline_reader.setPrompt("#{prompt}% ")
}