From 2c8606c2575ea9a22fe7d847b4ff43308488a18c Mon Sep 17 00:00:00 2001 From: John Barnette Date: Sat, 19 Apr 2008 14:59:22 -0700 Subject: [PATCH] Add a bunch of improvements to bin/johnson. All of these can be specified multiple times. -I [DIRECTORY] Adds DIRECTORY to the Ruby load path. -i [FILE] Pre-evaluate FILE before going into interactive mode. -e [EXPRESSION] Evaluate EXPRESSION and exit. --- bin/johnson | 49 ++++++++++++++++++++++++++++----- lib/johnson.rb | 5 +++- lib/johnson/cli/options.rb | 55 ++++++++++++++++++++++++++++++++++++++ lib/johnson/context.rb | 4 +++ 4 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 lib/johnson/cli/options.rb diff --git a/bin/johnson b/bin/johnson index ef4a6ea..a62a565 100755 --- a/bin/johnson +++ b/bin/johnson @@ -1,11 +1,16 @@ #!/usr/bin/env ruby -require "rubygems" -require "johnson" +begin + require "johnson" +rescue LoadError + require "rubygems" + require "johnson" +end + require "readline" CONTEXT = cx = Johnson::Context.new -CONTEXT[:print] = lambda { |m| puts m } +CONTEXT[:alert] = lambda { |m| puts m } EXIT_VERBS = %w(exit quit) @@ -33,10 +38,37 @@ rescue Object => e puts e.backtrace end +def eval_in_js(expression) + rescued { puts "=> " + CONTEXT.evaluate(expression).inspect } +end + +def eval_in_ruby(expression, bind_to) + rescued { puts "=> " + eval(expression, bind_to).inspect } +end + +options = Johnson::CLI::Options.parse!(ARGV) +options.load_paths.each { |d| $LOAD_PATH << d } +options.files_to_preload.each { |f| CONTEXT.load(f) } + +unless options.files_to_evaluate.empty? + options.files_to_evaluate.each { |f| CONTEXT.load(f) } + exit +end + +unless options.expressions.empty? + options.expressions.each { |e| CONTEXT.evaluate(e) } + exit +end + loop do input = Readline.readline("js> ", true) break if EXIT_VERBS.include?(input) + if input =~ /^rb\s+(.+)$/ + eval_in_ruby($1, local_binding) + next + end + if input == "rb" js_readline = copy_history paste_history(ruby_readline) @@ -45,8 +77,13 @@ loop do input = Readline.readline("rb> ", true) break if input == "js" exit if EXIT_VERBS.include?(input) - - rescued { puts "=> " + eval(input, local_binding).inspect } + + if input =~ /^js\s+(.+)$/ + eval_in_js($1) + next + end + + eval_in_ruby(input, local_binding) end ruby_readline = copy_history @@ -54,5 +91,5 @@ loop do next end - rescued { puts "=> " + CONTEXT.evaluate(input).inspect } + eval_in_js(input) end diff --git a/lib/johnson.rb b/lib/johnson.rb index 7fc7686..37a3fec 100644 --- a/lib/johnson.rb +++ b/lib/johnson.rb @@ -1,6 +1,9 @@ -require 'generator' +require "generator" require "johnson/version" +# the command-line option parser +require "johnson/cli/options" + # the native SpiderMonkey extension require "johnson/spidermonkey" diff --git a/lib/johnson/cli/options.rb b/lib/johnson/cli/options.rb new file mode 100644 index 0000000..67a05fb --- /dev/null +++ b/lib/johnson/cli/options.rb @@ -0,0 +1,55 @@ +require "optparse" + +module Johnson + module CLI + class Options + class << self + alias_method :parse!, :new + end + + attr_reader :expressions, :load_paths, :files_to_preload, :files_to_evaluate + + def initialize(*args) + argv = args.flatten + @expressions = [] + @load_paths = [] + @files_to_preload = [] + @files_to_evaluate = [] + + parser = OptionParser.new do |parser| + parser.banner = "Usage: johnson [options] [files...]" + parser.version = Johnson::VERSION + + parser.on("-e [EXPRESSION]", "Evaluate [EXPRESSION] and exit") do |expression| + @expressions << expression + end + + parser.on("-I [DIRECTORY]", "Specify $LOAD_PATH directories") do |dir| + @load_paths << dir + end + + parser.on("-i [FILE]", "Evaluate [FILE] before interaction") do |file| + @files_to_preload << file + end + + parser.on("-i [FILE]", "Evaluate [FILE] before interaction") do |file| + @files_to_preload << file + end + + parser.on("-h", "-?", "--help", "Show this message") do + puts parser + exit + end + + parser.on("-v", "--version", "Show Johnson's version (#{Johnson::VERSION})") do + puts Johnson::VERSION + exit + end + end + + parser.parse!(argv) + argv.each { |f| @files_to_evaluate << f } + end + end + end +end diff --git a/lib/johnson/context.rb b/lib/johnson/context.rb index 8ec1a11..6a58f77 100644 --- a/lib/johnson/context.rb +++ b/lib/johnson/context.rb @@ -23,5 +23,9 @@ def evaluate(expression) def global delegate.global end + + def load(file) + delegate.evaluate(IO.read(file)) + end end end