Created
June 18, 2012 21:53
-
-
Save gabamnml/2950951 to your computer and use it in GitHub Desktop.
interactive shell for ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/ruby | |
####################################################### | |
# | |
# Ruby interactive input/eval loop | |
# Written by matz ([email protected]) | |
# Modified by Mark Slagell ([email protected]) | |
# with suggestions for improvement from Dave Thomas | |
# ([email protected]) | |
# | |
####################################################### | |
# | |
# NOTE - this file has been renamed with a .txt extension to | |
# allow you to view or download it without the rubyist.net | |
# web server trying to run it as a CGI script. You will | |
# probably want to rename it back to eval.rb. | |
# | |
####################################################### | |
module EvalWrapper | |
# Constants for ANSI screen interaction. Adjust to your liking. | |
Norm = "\033[0m" | |
PCol = Norm # Prompt color | |
Code = "\033[1;32m" # yellow | |
Eval = "\033[0;36m" # cyan | |
Prompt = PCol+"ruby> "+Norm | |
PrMore = PCol+" | "+Norm | |
Ispace = " " # Adjust length of this for indentation. | |
Wipe = "\033[A\033[K" # Move cursor up and erase line | |
# Return a pair of indentation deltas. The first applies before | |
# the current line is printed, the second after. | |
def EvalWrapper.indentation( code ) | |
case code | |
when /^\s*(class|module|def|if|case|while|for|begin)\b[^_]/ | |
[0,1] # increase indentation because of keyword | |
when /^\s*end\b[^_]/ | |
[-1,0] # decrease because of end | |
when /\{\s*(\|.*\|)?\s*$/ | |
[0,1] # increase because of '{' | |
when /^\s*\}/ | |
[-1,0] # decrease because of '}' | |
when /^\s*(rescue|ensure|elsif|else)\b[^_]/ | |
[-1,1] # decrease for this line, then come back | |
else | |
[0,0] # we see no reason to change anything | |
end | |
end | |
# On exit, restore normal screen colors. | |
END { print Norm,"\n" } | |
############################################################## | |
# Execution starts here. | |
############################################################## | |
indent=0 | |
while TRUE # Top of main loop. | |
# Print prompt, move cursor to tentative indentation level, and get | |
# a line of input from the user. | |
if( indent == 0 ) | |
expr = ''; print Prompt # (expecting a fresh expression) | |
else | |
print PrMore # (appending to previous lines) | |
end | |
print Ispace * indent,Code | |
line = gets | |
print Norm | |
if not line | |
# end of input (^D) - if there is no expression, exit, else | |
# reset cursor to the beginning of this line. | |
if expr == '' then break else print "\r" end | |
else | |
# Append the input to whatever we had. | |
expr << line | |
# Determine changes in indentation, reposition this line if | |
# necessary, and adjust indentation for the next prompt. | |
begin | |
ind1,ind2 = indentation( line ) | |
if( ind1 != 0 ) | |
indent += ind1 | |
print Wipe,PrMore,(Ispace*indent),Code,line,Norm | |
end | |
indent += ind2 | |
rescue # On error, restart the main loop. | |
print Eval,"ERR: Nesting violation\n",Norm | |
indent = 0 | |
redo | |
end | |
# Okay, do we have something worth evaulating? | |
if (indent == 0) && (expr.chop =~ /[^; \t\n\r\f]+/) | |
begin | |
result = eval(expr, TOPLEVEL_BINDING).inspect | |
if $! # no exception, but $! non-nil, means a warning | |
print Eval,$!,Norm,"\n" | |
$!=nil | |
end | |
print Eval," ",result,Norm,"\n" | |
rescue ScriptError,StandardError | |
$! = 'exception raised' if not $! | |
print Eval,"ERR: ",$!,Norm,"\n" | |
end | |
break if not line | |
end | |
end | |
end # Bottom of main loop | |
print "\n" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment