usr/bin/irb000075500000000472147207344700006642 0ustar00#!/usr/bin/ruby # # irb.rb - interactive ruby # $Release Version: 0.9.6 $ # $Revision: 25189 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # require "irb" if __FILE__ == $0 IRB.start(__FILE__) else # check -e option if /^-e$/ =~ $0 IRB.start(__FILE__) else IRB.setup(__FILE__) end end opt/cpanel/ea-ruby24/root/usr/bin/irb000075500000000324147235072400013373 0ustar00#!/opt/cpanel/ea-ruby24/root/usr/bin/ruby # # irb.rb - interactive ruby # $Release Version: 0.9.6 $ # $Revision: 40560 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # require "irb" IRB.start(__FILE__) cmd/nop.rb000064400000001051147556205260006441 0ustar00# frozen_string_literal: false # # nop.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # # :stopdoc: module IRB module ExtendCommand class Nop def self.execute(conf, *opts) command = new(conf) command.execute(*opts) end def initialize(conf) @irb_context = conf end attr_reader :irb_context def irb @irb_context.irb end def execute(*opts) #nop end end end end # :startdoc: cmd/pushws.rb000064400000001253147556205260007202 0ustar00# frozen_string_literal: false # # change-ws.rb - # $Release Version: 0.9.6$ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "irb/cmd/nop.rb" require "irb/ext/workspaces.rb" # :stopdoc: module IRB module ExtendCommand class Workspaces < Nop def execute(*obj) irb_context.workspaces.collect{|ws| ws.main} end end class PushWorkspace < Workspaces def execute(*obj) irb_context.push_workspace(*obj) super end end class PopWorkspace < Workspaces def execute(*obj) irb_context.pop_workspace(*obj) super end end end end # :startdoc: cmd/subirb.rb000064400000001227147556205260007140 0ustar00# frozen_string_literal: false # multi.rb - # $Release Version: 0.9.6$ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "irb/cmd/nop.rb" require "irb/ext/multi-irb" # :stopdoc: module IRB module ExtendCommand class IrbCommand < Nop def execute(*obj) IRB.irb(nil, *obj) end end class Jobs < Nop def execute IRB.JobManager end end class Foreground < Nop def execute(key) IRB.JobManager.switch(key) end end class Kill < Nop def execute(*keys) IRB.JobManager.kill(*keys) end end end end # :startdoc: cmd/chws.rb000064400000001036147556205260006614 0ustar00# frozen_string_literal: false # # change-ws.rb - # $Release Version: 0.9.6$ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "irb/cmd/nop.rb" require "irb/ext/change-ws.rb" # :stopdoc: module IRB module ExtendCommand class CurrentWorkingWorkspace < Nop def execute(*obj) irb_context.main end end class ChangeWorkspace < Nop def execute(*obj) irb_context.change_workspace(*obj) irb_context.main end end end end # :startdoc: cmd/load.rb000064400000002320147556205260006564 0ustar00# frozen_string_literal: false # # load.rb - # $Release Version: 0.9.6$ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "irb/cmd/nop.rb" require "irb/ext/loader" # :stopdoc: module IRB module ExtendCommand class Load < Nop include IrbLoader def execute(file_name, priv = nil) return irb_load(file_name, priv) end end class Require < Nop include IrbLoader def execute(file_name) rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?") return false if $".find{|f| f =~ rex} case file_name when /\.rb$/ begin if irb_load(file_name) $".push file_name return true end rescue LoadError end when /\.(so|o|sl)$/ return ruby_require(file_name) end begin irb_load(f = file_name + ".rb") $".push f return true rescue LoadError return ruby_require(file_name) end end end class Source < Nop include IrbLoader def execute(file_name) source_file(file_name) end end end end # :startdoc: cmd/fork.rb000064400000001205147556205260006607 0ustar00# frozen_string_literal: false # # fork.rb - # $Release Version: 0.9.6 $ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # # :stopdoc: module IRB module ExtendCommand class Fork < Nop def execute pid = send ExtendCommand.irb_original_method_name("fork") unless pid class << self alias_method :exit, ExtendCommand.irb_original_method_name('exit') end if iterator? begin yield ensure exit end end end pid end end end end # :startdoc: cmd/help.rb000064400000001271147556205260006601 0ustar00# frozen_string_literal: false # # help.rb - helper using ri # $Release Version: 0.9.6$ # $Revision: 56371 $ # # -- # # # require 'rdoc/ri/driver' require "irb/cmd/nop.rb" # :stopdoc: module IRB module ExtendCommand class Help < Nop begin Ri = RDoc::RI::Driver.new rescue SystemExit else def execute(*names) if names.empty? Ri.interactive return end names.each do |name| begin Ri.display_name(name.to_s) rescue RDoc::RI::Error puts $!.message end end nil end end end end end # :startdoc: output-method.rb000064400000004707147556205260007733 0ustar00# frozen_string_literal: false # # output-method.rb - output methods used by irb # $Release Version: 0.9.6$ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "e2mmap" module IRB # An abstract output class for IO in irb. This is mainly used internally by # IRB::Notifier. You can define your own output method to use with Irb.new, # or Context.new class OutputMethod extend Exception2MessageMapper def_exception :NotImplementedError, "Need to define `%s'" # Open this method to implement your own output method, raises a # NotImplementedError if you don't define #print in your own class. def print(*opts) OutputMethod.Raise NotImplementedError, "print" end # Prints the given +opts+, with a newline delimiter. def printn(*opts) print opts.join(" "), "\n" end # Extends IO#printf to format the given +opts+ for Kernel#sprintf using # #parse_printf_format def printf(format, *opts) if /(%*)%I/ =~ format format, opts = parse_printf_format(format, opts) end print sprintf(format, *opts) end # Returns an array of the given +format+ and +opts+ to be used by # Kernel#sprintf, if there was a successful Regexp match in the given # +format+ from #printf # # % # [#0- +] # (\*|\*[1-9][0-9]*\$|[1-9][0-9]*) # .(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)? # #(hh|h|l|ll|L|q|j|z|t) # [diouxXeEfgGcsb%] def parse_printf_format(format, opts) return format, opts if $1.size % 2 == 1 end # Calls #print on each element in the given +objs+, followed by a newline # character. def puts(*objs) for obj in objs print(*obj) print "\n" end end # Prints the given +objs+ calling Object#inspect on each. # # See #puts for more detail. def pp(*objs) puts(*objs.collect{|obj| obj.inspect}) end # Prints the given +objs+ calling Object#inspect on each and appending the # given +prefix+. # # See #puts for more detail. def ppx(prefix, *objs) puts(*objs.collect{|obj| prefix+obj.inspect}) end end # A standard output printer class StdioOutputMethod < OutputMethod # Prints the given +opts+ to standard output, see IO#print for more # information. def print(*opts) STDOUT.print(*opts) end end end extend-command.rb000064400000023335147556205260010016 0ustar00# frozen_string_literal: false # # irb/extend-command.rb - irb extend command # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: # Installs the default irb extensions command bundle. module ExtendCommandBundle EXCB = ExtendCommandBundle # :nodoc: # See #install_alias_method. NO_OVERRIDE = 0 # See #install_alias_method. OVERRIDE_PRIVATE_ONLY = 0x01 # See #install_alias_method. OVERRIDE_ALL = 0x02 # Quits the current irb context # # +ret+ is the optional signal or message to send to Context#exit # # Same as IRB.CurrentContext.exit. def irb_exit(ret = 0) irb_context.exit(ret) end # Displays current configuration. # # Modifing the configuration is achieved by sending a message to IRB.conf. def irb_context IRB.CurrentContext end @ALIASES = [ [:context, :irb_context, NO_OVERRIDE], [:conf, :irb_context, NO_OVERRIDE], [:irb_quit, :irb_exit, OVERRIDE_PRIVATE_ONLY], [:exit, :irb_exit, OVERRIDE_PRIVATE_ONLY], [:quit, :irb_exit, OVERRIDE_PRIVATE_ONLY], ] @EXTEND_COMMANDS = [ [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws", [:irb_print_working_workspace, OVERRIDE_ALL], [:irb_cwws, OVERRIDE_ALL], [:irb_pwws, OVERRIDE_ALL], [:cwws, NO_OVERRIDE], [:pwws, NO_OVERRIDE], [:irb_current_working_binding, OVERRIDE_ALL], [:irb_print_working_binding, OVERRIDE_ALL], [:irb_cwb, OVERRIDE_ALL], [:irb_pwb, OVERRIDE_ALL], ], [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws", [:irb_chws, OVERRIDE_ALL], [:irb_cws, OVERRIDE_ALL], [:chws, NO_OVERRIDE], [:cws, NO_OVERRIDE], [:irb_change_binding, OVERRIDE_ALL], [:irb_cb, OVERRIDE_ALL], [:cb, NO_OVERRIDE]], [:irb_workspaces, :Workspaces, "irb/cmd/pushws", [:workspaces, NO_OVERRIDE], [:irb_bindings, OVERRIDE_ALL], [:bindings, NO_OVERRIDE]], [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws", [:irb_pushws, OVERRIDE_ALL], [:pushws, NO_OVERRIDE], [:irb_push_binding, OVERRIDE_ALL], [:irb_pushb, OVERRIDE_ALL], [:pushb, NO_OVERRIDE]], [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws", [:irb_popws, OVERRIDE_ALL], [:popws, NO_OVERRIDE], [:irb_pop_binding, OVERRIDE_ALL], [:irb_popb, OVERRIDE_ALL], [:popb, NO_OVERRIDE]], [:irb_load, :Load, "irb/cmd/load"], [:irb_require, :Require, "irb/cmd/load"], [:irb_source, :Source, "irb/cmd/load", [:source, NO_OVERRIDE]], [:irb, :IrbCommand, "irb/cmd/subirb"], [:irb_jobs, :Jobs, "irb/cmd/subirb", [:jobs, NO_OVERRIDE]], [:irb_fg, :Foreground, "irb/cmd/subirb", [:fg, NO_OVERRIDE]], [:irb_kill, :Kill, "irb/cmd/subirb", [:kill, OVERRIDE_PRIVATE_ONLY]], [:irb_help, :Help, "irb/cmd/help", [:help, NO_OVERRIDE]], ] # Installs the default irb commands: # # +irb_current_working_workspace+:: Context#main # +irb_change_workspace+:: Context#change_workspace # +irb_workspaces+:: Context#workspaces # +irb_push_workspace+:: Context#push_workspace # +irb_pop_workspace+:: Context#pop_workspace # +irb_load+:: #irb_load # +irb_require+:: #irb_require # +irb_source+:: IrbLoader#source_file # +irb+:: IRB.irb # +irb_jobs+:: JobManager # +irb_fg+:: JobManager#switch # +irb_kill+:: JobManager#kill # +irb_help+:: IRB@Command+line+options def self.install_extend_commands for args in @EXTEND_COMMANDS def_extend_command(*args) end end # Evaluate the given +cmd_name+ on the given +cmd_class+ Class. # # Will also define any given +aliases+ for the method. # # The optional +load_file+ parameter will be required within the method # definition. def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases) case cmd_class when Symbol cmd_class = cmd_class.id2name when String when Class cmd_class = cmd_class.name end if load_file line = __LINE__; eval %[ def #{cmd_name}(*opts, &b) require "#{load_file}" arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s } args << "*opts" if arity < 0 args << "&block" args = args.join(", ") line = __LINE__; eval %[ def #{cmd_name}(\#{args}) ExtendCommand::#{cmd_class}.execute(irb_context, \#{args}) end ], nil, __FILE__, line send :#{cmd_name}, *opts, &b end ], nil, __FILE__, line else line = __LINE__; eval %[ def #{cmd_name}(*opts, &b) ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b) end ], nil, __FILE__, line end for ali, flag in aliases @ALIASES.push [ali, cmd_name, flag] end end # Installs alias methods for the default irb commands, see # ::install_extend_commands. def install_alias_method(to, from, override = NO_OVERRIDE) to = to.id2name unless to.kind_of?(String) from = from.id2name unless from.kind_of?(String) if override == OVERRIDE_ALL or (override == OVERRIDE_PRIVATE_ONLY) && !respond_to?(to) or (override == NO_OVERRIDE) && !respond_to?(to, true) target = self (class << self; self; end).instance_eval{ if target.respond_to?(to, true) && !target.respond_to?(EXCB.irb_original_method_name(to), true) alias_method(EXCB.irb_original_method_name(to), to) end alias_method to, from } else print "irb: warn: can't alias #{to} from #{from}.\n" end end def self.irb_original_method_name(method_name) # :nodoc: "irb_" + method_name + "_org" end # Installs alias methods for the default irb commands on the given object # using #install_alias_method. def self.extend_object(obj) unless (class << obj; ancestors; end).include?(EXCB) super for ali, com, flg in @ALIASES obj.install_alias_method(ali, com, flg) end end end install_extend_commands end # Extends methods for the Context module module ContextExtender CE = ContextExtender # :nodoc: @EXTEND_COMMANDS = [ [:eval_history=, "irb/ext/history.rb"], [:use_tracer=, "irb/ext/tracer.rb"], [:math_mode=, "irb/ext/math-mode.rb"], [:use_loader=, "irb/ext/use-loader.rb"], [:save_history=, "irb/ext/save-history.rb"], ] # Installs the default context extensions as irb commands: # # Context#eval_history=:: +irb/ext/history.rb+ # Context#use_tracer=:: +irb/ext/tracer.rb+ # Context#math_mode=:: +irb/ext/math-mode.rb+ # Context#use_loader=:: +irb/ext/use-loader.rb+ # Context#save_history=:: +irb/ext/save-history.rb+ def self.install_extend_commands for args in @EXTEND_COMMANDS def_extend_command(*args) end end # Evaluate the given +command+ from the given +load_file+ on the Context # module. # # Will also define any given +aliases+ for the method. def self.def_extend_command(cmd_name, load_file, *aliases) line = __LINE__; Context.module_eval %[ def #{cmd_name}(*opts, &b) Context.module_eval {remove_method(:#{cmd_name})} require "#{load_file}" send :#{cmd_name}, *opts, &b end for ali in aliases alias_method ali, cmd_name end ], __FILE__, line end CE.install_extend_commands end # A convenience module for extending Ruby methods. module MethodExtender # Extends the given +base_method+ with a prefix call to the given # +extend_method+. def def_pre_proc(base_method, extend_method) base_method = base_method.to_s extend_method = extend_method.to_s alias_name = new_alias_name(base_method) module_eval %[ alias_method alias_name, base_method def #{base_method}(*opts) send :#{extend_method}, *opts send :#{alias_name}, *opts end ] end # Extends the given +base_method+ with a postfix call to the given # +extend_method+. def def_post_proc(base_method, extend_method) base_method = base_method.to_s extend_method = extend_method.to_s alias_name = new_alias_name(base_method) module_eval %[ alias_method alias_name, base_method def #{base_method}(*opts) send :#{alias_name}, *opts send :#{extend_method}, *opts end ] end # Returns a unique method name to use as an alias for the given +name+. # # Usually returns #{prefix}#{name}#{postfix}, example: # # new_alias_name('foo') #=> __alias_of__foo__ # def bar; end # new_alias_name('bar') #=> __alias_of__bar__2 def new_alias_name(name, prefix = "__alias_of__", postfix = "__") base_name = "#{prefix}#{name}#{postfix}" all_methods = instance_methods(true) + private_instance_methods(true) same_methods = all_methods.grep(/^#{Regexp.quote(base_name)}[0-9]*$/) return base_name if same_methods.empty? no = same_methods.size while !same_methods.include?(alias_name = base_name + no) no += 1 end alias_name end end end inspector.rb000064400000007156147556205260007124 0ustar00# frozen_string_literal: false # # irb/inspector.rb - inspect methods # $Release Version: 0.9.6$ # $Revision: 1.19 $ # $Date: 2002/06/11 07:51:31 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: # Convenience method to create a new Inspector, using the given +inspect+ # proc, and optional +init+ proc and passes them to Inspector.new # # irb(main):001:0> ins = IRB::Inspector(proc{ |v| "omg! #{v}" }) # irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! # # irb(main):001:0> "what?" #=> omg! what? # def IRB::Inspector(inspect, init = nil) Inspector.new(inspect, init) end # An irb inspector # # In order to create your own custom inspector there are two things you # should be aware of: # # Inspector uses #inspect_value, or +inspect_proc+, for output of return values. # # This also allows for an optional #init+, or +init_proc+, which is called # when the inspector is activated. # # Knowing this, you can create a rudimentary inspector as follows: # # irb(main):001:0> ins = IRB::Inspector.new(proc{ |v| "omg! #{v}" }) # irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! # # irb(main):001:0> "what?" #=> omg! what? # class Inspector # Default inspectors available to irb, this includes: # # +:pp+:: Using Kernel#pretty_inspect # +:yaml+:: Using YAML.dump # +:marshal+:: Using Marshal.dump INSPECTORS = {} # Determines the inspector to use where +inspector+ is one of the keys passed # during inspector definition. def self.keys_with_inspector(inspector) INSPECTORS.select{|k,v| v == inspector}.collect{|k, v| k} end # Example # # Inspector.def_inspector(key, init_p=nil){|v| v.inspect} # Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect} # Inspector.def_inspector(key, inspector) # Inspector.def_inspector([key1,...], inspector) def self.def_inspector(key, arg=nil, &block) if block_given? inspector = IRB::Inspector(block, arg) else inspector = arg end case key when Array for k in key def_inspector(k, inspector) end when Symbol INSPECTORS[key] = inspector INSPECTORS[key.to_s] = inspector when String INSPECTORS[key] = inspector INSPECTORS[key.intern] = inspector else INSPECTORS[key] = inspector end end # Creates a new inspector object, using the given +inspect_proc+ when # output return values in irb. def initialize(inspect_proc, init_proc = nil) @init = init_proc @inspect = inspect_proc end # Proc to call when the inspector is activated, good for requiring # dependent libraries. def init @init.call if @init end # Proc to call when the input is evaluated and output in irb. def inspect_value(v) @inspect.call(v) end end Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s} Inspector.def_inspector([true, :p, :inspect]){|v| begin v.inspect rescue NoMethodError puts "(Object doesn't support #inspect)" end } Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v| v.pretty_inspect.chomp} Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v| begin YAML.dump(v) rescue puts "(can't dump yaml. use inspect)" v.inspect end } Inspector.def_inspector([:marshal, :Marshal, :MARSHAL, Marshal]){|v| Marshal.dump(v) } end init.rb000064400000017257147556205260006064 0ustar00# frozen_string_literal: false # # irb/init.rb - irb initialize module # $Release Version: 0.9.6$ # $Revision: 62185 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: # initialize config def IRB.setup(ap_path, argv: ::ARGV) IRB.init_config(ap_path) IRB.init_error IRB.parse_opts(argv: argv) IRB.run_config IRB.load_modules unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]] IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE]) end end # @CONF default setting def IRB.init_config(ap_path) # class instance variables @TRACER_INITIALIZED = false # default configurations unless ap_path and @CONF[:AP_NAME] ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb") end @CONF[:AP_NAME] = File::basename(ap_path, ".rb") @CONF[:IRB_NAME] = "irb" @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__) @CONF[:RC] = true @CONF[:LOAD_MODULES] = [] @CONF[:IRB_RC] = nil @CONF[:MATH_MODE] = false @CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod) @CONF[:INSPECT_MODE] = true @CONF[:USE_TRACER] = false @CONF[:USE_LOADER] = false @CONF[:IGNORE_SIGINT] = true @CONF[:IGNORE_EOF] = false @CONF[:ECHO] = nil @CONF[:VERBOSE] = nil @CONF[:EVAL_HISTORY] = nil @CONF[:SAVE_HISTORY] = nil @CONF[:BACK_TRACE_LIMIT] = 16 @CONF[:PROMPT] = { :NULL => { :PROMPT_I => nil, :PROMPT_N => nil, :PROMPT_S => nil, :PROMPT_C => nil, :RETURN => "%s\n" }, :DEFAULT => { :PROMPT_I => "%N(%m):%03n:%i> ", :PROMPT_N => "%N(%m):%03n:%i> ", :PROMPT_S => "%N(%m):%03n:%i%l ", :PROMPT_C => "%N(%m):%03n:%i* ", :RETURN => "=> %s\n" }, :CLASSIC => { :PROMPT_I => "%N(%m):%03n:%i> ", :PROMPT_N => "%N(%m):%03n:%i> ", :PROMPT_S => "%N(%m):%03n:%i%l ", :PROMPT_C => "%N(%m):%03n:%i* ", :RETURN => "%s\n" }, :SIMPLE => { :PROMPT_I => ">> ", :PROMPT_N => ">> ", :PROMPT_S => nil, :PROMPT_C => "?> ", :RETURN => "=> %s\n" }, :INF_RUBY => { :PROMPT_I => "%N(%m):%03n:%i> ", :PROMPT_N => nil, :PROMPT_S => nil, :PROMPT_C => nil, :RETURN => "%s\n", :AUTO_INDENT => true }, :XMP => { :PROMPT_I => nil, :PROMPT_N => nil, :PROMPT_S => nil, :PROMPT_C => nil, :RETURN => " ==>%s\n" } } @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL) @CONF[:AUTO_INDENT] = false @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING @CONF[:SINGLE_IRB] = false @CONF[:LC_MESSAGES] = Locale.new @CONF[:AT_EXIT] = [] @CONF[:DEBUG_LEVEL] = 0 end def IRB.init_error @CONF[:LC_MESSAGES].load("irb/error.rb") end # option analyzing def IRB.parse_opts(argv: ::ARGV) load_path = [] while opt = argv.shift case opt when "-f" @CONF[:RC] = false when "-m" @CONF[:MATH_MODE] = true when "-d" $DEBUG = true $VERBOSE = true when "-w" $VERBOSE = true when /^-W(.+)?/ opt = $1 || argv.shift case opt when "0" $VERBOSE = nil when "1" $VERBOSE = false else $VERBOSE = true end when /^-r(.+)?/ opt = $1 || argv.shift @CONF[:LOAD_MODULES].push opt if opt when /^-I(.+)?/ opt = $1 || argv.shift load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt when '-U' set_encoding("UTF-8", "UTF-8") when /^-E(.+)?/, /^--encoding(?:=(.+))?/ opt = $1 || argv.shift set_encoding(*opt.split(':', 2)) when "--inspect" if /^-/ !~ argv.first @CONF[:INSPECT_MODE] = argv.shift else @CONF[:INSPECT_MODE] = true end when "--noinspect" @CONF[:INSPECT_MODE] = false when "--readline" @CONF[:USE_READLINE] = true when "--noreadline" @CONF[:USE_READLINE] = false when "--echo" @CONF[:ECHO] = true when "--noecho" @CONF[:ECHO] = false when "--verbose" @CONF[:VERBOSE] = true when "--noverbose" @CONF[:VERBOSE] = false when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/ opt = $1 || argv.shift prompt_mode = opt.upcase.tr("-", "_").intern @CONF[:PROMPT_MODE] = prompt_mode when "--noprompt" @CONF[:PROMPT_MODE] = :NULL when "--inf-ruby-mode" @CONF[:PROMPT_MODE] = :INF_RUBY when "--sample-book-mode", "--simple-prompt" @CONF[:PROMPT_MODE] = :SIMPLE when "--tracer" @CONF[:USE_TRACER] = true when /^--back-trace-limit(?:=(.+))?/ @CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i when /^--context-mode(?:=(.+))?/ @CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i when "--single-irb" @CONF[:SINGLE_IRB] = true when /^--irb_debug(?:=(.+))?/ @CONF[:DEBUG_LEVEL] = ($1 || argv.shift).to_i when "-v", "--version" print IRB.version, "\n" exit 0 when "-h", "--help" require "irb/help" IRB.print_usage exit 0 when "--" if opt = argv.shift @CONF[:SCRIPT] = opt $0 = opt end break when /^-/ IRB.fail UnrecognizedSwitch, opt else @CONF[:SCRIPT] = opt $0 = opt break end end load_path.collect! do |path| /\A\.\// =~ path ? path : File.expand_path(path) end $LOAD_PATH.unshift(*load_path) end # running config def IRB.run_config if @CONF[:RC] begin load rc_file rescue LoadError, Errno::ENOENT rescue # StandardError, ScriptError print "load error: #{rc_file}\n" print $!.class, ": ", $!, "\n" for err in $@[0, $@.size - 2] print "\t", err, "\n" end end end end IRBRC_EXT = "rc" def IRB.rc_file(ext = IRBRC_EXT) if !@CONF[:RC_NAME_GENERATOR] rc_file_generators do |rcgen| @CONF[:RC_NAME_GENERATOR] ||= rcgen if File.exist?(rcgen.call(IRBRC_EXT)) @CONF[:RC_NAME_GENERATOR] = rcgen break end end end case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext) when String return rc_file else IRB.fail IllegalRCNameGenerator end end # enumerate possible rc-file base name generators def IRB.rc_file_generators if irbrc = ENV["IRBRC"] yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc} end if home = ENV["HOME"] yield proc{|rc| home+"/.irb#{rc}"} end home = Dir.pwd yield proc{|rc| home+"/.irb#{rc}"} yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"} yield proc{|rc| home+"/_irb#{rc}"} yield proc{|rc| home+"/$irb#{rc}"} end # loading modules def IRB.load_modules for m in @CONF[:LOAD_MODULES] begin require m rescue LoadError => err warn err.backtrace[0] << ":#{err.class}: #{err}" end end end DefaultEncodings = Struct.new(:external, :internal) class << IRB private def set_encoding(extern, intern = nil) verbose, $VERBOSE = $VERBOSE, nil Encoding.default_external = extern unless extern.nil? || extern.empty? Encoding.default_internal = intern unless intern.nil? || intern.empty? @CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern) [$stdin, $stdout, $stderr].each do |io| io.set_encoding(extern, intern) end @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern) ensure $VERBOSE = verbose end end end input-method.rb000064400000011211147556205260007516 0ustar00# frozen_string_literal: false # # irb/input-method.rb - input methods used irb # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require 'irb/src_encoding' require 'irb/magic-file' module IRB STDIN_FILE_NAME = "(line)" # :nodoc: class InputMethod # Creates a new input method object def initialize(file = STDIN_FILE_NAME) @file_name = file end # The file name of this input method, usually given during initialization. attr_reader :file_name # The irb prompt associated with this input method attr_accessor :prompt # Reads the next line from this input method. # # See IO#gets for more information. def gets IRB.fail NotImplementedError, "gets" end public :gets # Whether this input method is still readable when there is no more data to # read. # # See IO#eof for more information. def readable_after_eof? false end end class StdioInputMethod < InputMethod # Creates a new input method object def initialize super @line_no = 0 @line = [] @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-") @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-") end # Reads the next line from this input method. # # See IO#gets for more information. def gets print @prompt line = @stdin.gets @line[@line_no += 1] = line end # Whether the end of this input method has been reached, returns +true+ if # there is no more data to read. # # See IO#eof? for more information. def eof? @stdin.eof? end # Whether this input method is still readable when there is no more data to # read. # # See IO#eof for more information. def readable_after_eof? true end # Returns the current line number for #io. # # #line counts the number of times #gets is called. # # See IO#lineno for more information. def line(line_no) @line[line_no] end # The external encoding for standard input. def encoding @stdin.external_encoding end end # Use a File for IO with irb, see InputMethod class FileInputMethod < InputMethod # Creates a new input method object def initialize(file) super @io = IRB::MagicFile.open(file) end # The file name of this input method, usually given during initialization. attr_reader :file_name # Whether the end of this input method has been reached, returns +true+ if # there is no more data to read. # # See IO#eof? for more information. def eof? @io.eof? end # Reads the next line from this input method. # # See IO#gets for more information. def gets print @prompt l = @io.gets l end # The external encoding for standard input. def encoding @io.external_encoding end end begin require "readline" class ReadlineInputMethod < InputMethod include Readline # Creates a new input method object using Readline def initialize super @line_no = 0 @line = [] @eof = false @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-") @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-") end # Reads the next line from this input method. # # See IO#gets for more information. def gets Readline.input = @stdin Readline.output = @stdout if l = readline(@prompt, false) HISTORY.push(l) if !l.empty? @line[@line_no += 1] = l + "\n" else @eof = true l end end # Whether the end of this input method has been reached, returns +true+ # if there is no more data to read. # # See IO#eof? for more information. def eof? @eof end # Whether this input method is still readable when there is no more data to # read. # # See IO#eof for more information. def readable_after_eof? true end # Returns the current line number for #io. # # #line counts the number of times #gets is called. # # See IO#lineno for more information. def line(line_no) @line[line_no] end # The external encoding for standard input. def encoding @stdin.external_encoding end end rescue LoadError end end ext/use-loader.rb000064400000003375147556205260007755 0ustar00# frozen_string_literal: false # # use-loader.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "irb/cmd/load" require "irb/ext/loader" class Object alias __original__load__IRB_use_loader__ load alias __original__require__IRB_use_loader__ require end module IRB module ExtendCommandBundle # Loads the given file similarly to Kernel#load, see IrbLoader#irb_load def irb_load(*opts, &b) ExtendCommand::Load.execute(irb_context, *opts, &b) end # Loads the given file similarly to Kernel#require def irb_require(*opts, &b) ExtendCommand::Require.execute(irb_context, *opts, &b) end end class Context IRB.conf[:USE_LOADER] = false # Returns whether +irb+'s own file reader method is used by # +load+/+require+ or not. # # This mode is globally affected (irb-wide). def use_loader IRB.conf[:USE_LOADER] end alias use_loader? use_loader # Sets IRB.conf[:USE_LOADER] # # See #use_loader for more information. def use_loader=(opt) if IRB.conf[:USE_LOADER] != opt IRB.conf[:USE_LOADER] = opt if opt if !$".include?("irb/cmd/load") end (class<<@workspace.main;self;end).instance_eval { alias_method :load, :irb_load alias_method :require, :irb_require } else (class<<@workspace.main;self;end).instance_eval { alias_method :load, :__original__load__IRB_use_loader__ alias_method :require, :__original__require__IRB_use_loader__ } end end print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose? opt end end end ext/multi-irb.rb000064400000014762147556205260007623 0ustar00# frozen_string_literal: false # # irb/multi-irb.rb - multiple irb module # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # IRB.fail CantShiftToMultiIrbMode unless defined?(Thread) require "thread" module IRB class JobManager # Creates a new JobManager object def initialize @jobs = [] @current_job = nil end # The active irb session attr_accessor :current_job # The total number of irb sessions, used to set +irb_name+ of the current # Context. def n_jobs @jobs.size end # Returns the thread for the given +key+ object, see #search for more # information. def thread(key) th, = search(key) th end # Returns the irb session for the given +key+ object, see #search for more # information. def irb(key) _, irb = search(key) irb end # Returns the top level thread. def main_thread @jobs[0][0] end # Returns the top level irb session. def main_irb @jobs[0][1] end # Add the given +irb+ session to the jobs Array. def insert(irb) @jobs.push [Thread.current, irb] end # Changes the current active irb session to the given +key+ in the jobs # Array. # # Raises an IrbAlreadyDead exception if the given +key+ is no longer alive. # # If the given irb session is already active, an IrbSwitchedToCurrentThread # exception is raised. def switch(key) th, irb = search(key) IRB.fail IrbAlreadyDead unless th.alive? IRB.fail IrbSwitchedToCurrentThread if th == Thread.current @current_job = irb th.run Thread.stop @current_job = irb(Thread.current) end # Terminates the irb sessions specified by the given +keys+. # # Raises an IrbAlreadyDead exception if one of the given +keys+ is already # terminated. # # See Thread#exit for more information. def kill(*keys) for key in keys th, _ = search(key) IRB.fail IrbAlreadyDead unless th.alive? th.exit end end # Returns the associated job for the given +key+. # # If given an Integer, it will return the +key+ index for the jobs Array. # # When an instance of Irb is given, it will return the irb session # associated with +key+. # # If given an instance of Thread, it will return the associated thread # +key+ using Object#=== on the jobs Array. # # Otherwise returns the irb session with the same top-level binding as the # given +key+. # # Raises a NoSuchJob exception if no job can be found with the given +key+. def search(key) job = case key when Integer @jobs[key] when Irb @jobs.find{|k, v| v.equal?(key)} when Thread @jobs.assoc(key) else @jobs.find{|k, v| v.context.main.equal?(key)} end IRB.fail NoSuchJob, key if job.nil? job end # Deletes the job at the given +key+. def delete(key) case key when Integer IRB.fail NoSuchJob, key unless @jobs[key] @jobs[key] = nil else catch(:EXISTS) do @jobs.each_index do |i| if @jobs[i] and (@jobs[i][0] == key || @jobs[i][1] == key || @jobs[i][1].context.main.equal?(key)) @jobs[i] = nil throw :EXISTS end end IRB.fail NoSuchJob, key end end until assoc = @jobs.pop; end unless @jobs.empty? @jobs.push assoc end # Outputs a list of jobs, see the irb command +irb_jobs+, or +jobs+. def inspect ary = [] @jobs.each_index do |i| th, irb = @jobs[i] next if th.nil? if th.alive? if th.stop? t_status = "stop" else t_status = "running" end else t_status = "exited" end ary.push format("#%d->%s on %s (%s: %s)", i, irb.context.irb_name, irb.context.main, th, t_status) end ary.join("\n") end end @JobManager = JobManager.new # The current JobManager in the session def IRB.JobManager @JobManager end # The current Context in this session def IRB.CurrentContext IRB.JobManager.irb(Thread.current).context end # Creates a new IRB session, see Irb.new. # # The optional +file+ argument is given to Context.new, along with the # workspace created with the remaining arguments, see WorkSpace.new def IRB.irb(file = nil, *main) workspace = WorkSpace.new(*main) parent_thread = Thread.current Thread.start do begin irb = Irb.new(workspace, file) rescue print "Subirb can't start with context(self): ", workspace.main.inspect, "\n" print "return to main irb\n" Thread.pass Thread.main.wakeup Thread.exit end @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] @JobManager.insert(irb) @JobManager.current_job = irb begin system_exit = false catch(:IRB_EXIT) do irb.eval_input end rescue SystemExit system_exit = true raise #fail ensure unless system_exit @JobManager.delete(irb) if @JobManager.current_job == irb if parent_thread.alive? @JobManager.current_job = @JobManager.irb(parent_thread) parent_thread.run else @JobManager.current_job = @JobManager.main_irb @JobManager.main_thread.run end end end end end Thread.stop @JobManager.current_job = @JobManager.irb(Thread.current) end @CONF[:SINGLE_IRB_MODE] = false @JobManager.insert(@CONF[:MAIN_CONTEXT].irb) @JobManager.current_job = @CONF[:MAIN_CONTEXT].irb class Irb def signal_handle unless @context.ignore_sigint? print "\nabort!!\n" if @context.verbose? exit end case @signal_status when :IN_INPUT print "^C\n" IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput when :IN_EVAL IRB.irb_abort(self) when :IN_LOAD IRB.irb_abort(self, LoadAbort) when :IN_IRB # ignore else # ignore other cases as well end end end trap("SIGINT") do @JobManager.current_job.signal_handle Thread.stop end end ext/loader.rb000064400000006205147556205260007156 0ustar00# frozen_string_literal: false # # loader.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: # Raised in the event of an exception in a file loaded from an Irb session class LoadAbort < Exception;end # Provides a few commands for loading files within an irb session. # # See ExtendCommandBundle for more information. module IrbLoader alias ruby_load load alias ruby_require require # Loads the given file similarly to Kernel#load def irb_load(fn, priv = nil) path = search_file_from_ruby_path(fn) raise LoadError, "No such file to load -- #{fn}" unless path load_file(path, priv) end def search_file_from_ruby_path(fn) # :nodoc: if /^#{Regexp.quote(File::Separator)}/ =~ fn return fn if File.exist?(fn) return nil end for path in $: if File.exist?(f = File.join(path, fn)) return f end end return nil end # Loads a given file in the current session and displays the source lines # # See Irb#suspend_input_method for more information. def source_file(path) irb.suspend_name(path, File.basename(path)) do irb.suspend_input_method(FileInputMethod.new(path)) do |back_io| irb.signal_status(:IN_LOAD) do if back_io.kind_of?(FileInputMethod) irb.eval_input else begin irb.eval_input rescue LoadAbort print "load abort!!\n" end end end end end end # Loads the given file in the current session's context and evaluates it. # # See Irb#suspend_input_method for more information. def load_file(path, priv = nil) irb.suspend_name(path, File.basename(path)) do if priv ws = WorkSpace.new(Module.new) else ws = WorkSpace.new end irb.suspend_workspace(ws) do irb.suspend_input_method(FileInputMethod.new(path)) do |back_io| irb.signal_status(:IN_LOAD) do if back_io.kind_of?(FileInputMethod) irb.eval_input else begin irb.eval_input rescue LoadAbort print "load abort!!\n" end end end end end end end def old # :nodoc: back_io = @io back_path = @irb_path back_name = @irb_name back_scanner = @irb.scanner begin @io = FileInputMethod.new(path) @irb_name = File.basename(path) @irb_path = path @irb.signal_status(:IN_LOAD) do if back_io.kind_of?(FileInputMethod) @irb.eval_input else begin @irb.eval_input rescue LoadAbort print "load abort!!\n" end end end ensure @io = back_io @irb_name = back_name @irb_path = back_path @irb.scanner = back_scanner end end end end ext/math-mode.rb000064400000001712147556205260007561 0ustar00# frozen_string_literal: false # # math-mode.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "mathn" module IRB class Context # Returns whether bc mode is enabled. # # See #math_mode= attr_reader :math_mode # Alias for #math_mode alias math? math_mode # Sets bc mode, which loads +lib/mathn.rb+ so fractions or matrix are # available. # # Also available as the +-m+ command line option. # # See IRB@Command+line+options and the unix manpage bc(1) for # more information. def math_mode=(opt) if @math_mode == true && !opt IRB.fail CantReturnToNormalMode return end @math_mode = opt if math_mode main.extend Math print "start math mode\n" if verbose? end end def inspect? @inspect_mode.nil? && !@math_mode or @inspect_mode end end end ext/save-history.rb000064400000005226147556205260010347 0ustar00# frozen_string_literal: false # save-history.rb - # $Release Version: 0.9.6$ # $Revision: 54596 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "readline" module IRB module HistorySavingAbility # :nodoc: end class Context def init_save_history# :nodoc: unless (class<<@io;self;end).include?(HistorySavingAbility) @io.extend(HistorySavingAbility) end end # A copy of the default IRB.conf[:SAVE_HISTORY] def save_history IRB.conf[:SAVE_HISTORY] end remove_method :save_history= if respond_to?(:save_history=) # Sets IRB.conf[:SAVE_HISTORY] to the given +val+ and calls # #init_save_history with this context. # # Will store the number of +val+ entries of history in the #history_file # # Add the following to your +.irbrc+ to change the number of history # entries stored to 1000: # # IRB.conf[:SAVE_HISTORY] = 1000 def save_history=(val) IRB.conf[:SAVE_HISTORY] = val if val main_context = IRB.conf[:MAIN_CONTEXT] main_context = self unless main_context main_context.init_save_history end end # A copy of the default IRB.conf[:HISTORY_FILE] def history_file IRB.conf[:HISTORY_FILE] end # Set IRB.conf[:HISTORY_FILE] to the given +hist+. def history_file=(hist) IRB.conf[:HISTORY_FILE] = hist end end module HistorySavingAbility # :nodoc: include Readline def HistorySavingAbility.extended(obj) IRB.conf[:AT_EXIT].push proc{obj.save_history} obj.load_history obj end def load_history if history_file = IRB.conf[:HISTORY_FILE] history_file = File.expand_path(history_file) end history_file = IRB.rc_file("_history") unless history_file if File.exist?(history_file) open(history_file) do |f| f.each {|l| HISTORY << l.chomp} end end end def save_history if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0 if history_file = IRB.conf[:HISTORY_FILE] history_file = File.expand_path(history_file) end history_file = IRB.rc_file("_history") unless history_file # Change the permission of a file that already exists[BUG #7694] begin if File.stat(history_file).mode & 066 != 0 File.chmod(0600, history_file) end rescue Errno::ENOENT rescue raise end open(history_file, 'w', 0600 ) do |f| hist = HISTORY.to_a f.puts(hist[-num..-1] || hist) end end end end end ext/history.rb000064400000004723147556205260007414 0ustar00# frozen_string_literal: false # # history.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: class Context NOPRINTING_IVARS.push "@eval_history_values" # See #set_last_value alias _set_last_value set_last_value def set_last_value(value) _set_last_value(value) if @eval_history @eval_history_values.push @line_no, @last_value @workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}" end @last_value end # The command result history limit. attr_reader :eval_history # Sets command result history limit. # # +no+ is an Integer or +nil+. # # Returns +no+ of history items if greater than 0. # # If +no+ is 0, the number of history items is unlimited. # # If +no+ is +nil+, execution result history isn't used (default). def eval_history=(no) if no if defined?(@eval_history) && @eval_history @eval_history_values.size(no) else @eval_history_values = History.new(no) IRB.conf[:__TMP__EHV__] = @eval_history_values @workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]") IRB.conf.delete(:__TMP_EHV__) end else @eval_history_values = nil end @eval_history = no end end class History # :nodoc: def initialize(size = 16) @size = size @contents = [] end def size(size) if size != 0 && size < @size @contents = @contents[@size - size .. @size] end @size = size end def [](idx) begin if idx >= 0 @contents.find{|no, val| no == idx}[1] else @contents[idx][1] end rescue NameError nil end end def push(no, val) @contents.push [no, val] @contents.shift if @size != 0 && @contents.size > @size end alias real_inspect inspect def inspect if @contents.empty? return real_inspect end unless (last = @contents.pop)[1].equal?(self) @contents.push last last = nil end str = @contents.collect{|no, val| if val.equal?(self) "#{no} ...self-history..." else "#{no} #{val.inspect}" end }.join("\n") if str == "" str = "Empty." end @contents.push last if last str end end end ext/change-ws.rb000064400000002022147556205260007555 0ustar00# frozen_string_literal: false # # irb/ext/cb.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: class Context # Inherited from +TOPLEVEL_BINDING+. def home_workspace if defined? @home_workspace @home_workspace else @home_workspace = @workspace end end # Changes the current workspace to given object or binding. # # If the optional argument is omitted, the workspace will be # #home_workspace which is inherited from +TOPLEVEL_BINDING+ or the main # object, IRB.conf[:MAIN_CONTEXT] when irb was initialized. # # See IRB::WorkSpace.new for more information. def change_workspace(*_main) if _main.empty? @workspace = home_workspace return main end @workspace = WorkSpace.new(_main[0]) if !(class<[[:alpha:]]{2,3}) (?:_ (?[[:alpha:]]{2,3}) )? (?:\. (?[^@]+) )? (?:@ (?.*) )? ]x LOCALE_DIR = "/lc/" @@legacy_encoding_alias_map = {}.freeze def initialize(locale = nil) @lang = @territory = @encoding_name = @modifier = nil @locale = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] || "C" if m = LOCALE_NAME_RE.match(@locale) @lang, @territory, @encoding_name, @modifier = m[:language], m[:territory], m[:codeset], m[:modifier] if @encoding_name begin load 'irb/encoding_aliases.rb'; rescue LoadError; end if @encoding = @@legacy_encoding_alias_map[@encoding_name] warn "%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"] end @encoding = Encoding.find(@encoding_name) rescue nil end end @encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT) end attr_reader :lang, :territory, :encoding, :modifier def String(mes) mes = super(mes) if @encoding mes.encode(@encoding, undef: :replace) else mes end end def format(*opts) String(super(*opts)) end def gets(*rs) String(super(*rs)) end def readline(*rs) String(super(*rs)) end def print(*opts) ary = opts.collect{|opt| String(opt)} super(*ary) end def printf(*opts) s = format(*opts) print s end def puts(*opts) ary = opts.collect{|opt| String(opt)} super(*ary) end def require(file, priv = nil) rex = Regexp.new("lc/#{Regexp.quote(file)}\.(so|o|sl|rb)?") return false if $".find{|f| f =~ rex} case file when /\.rb$/ begin load(file, priv) $".push file return true rescue LoadError end when /\.(so|o|sl)$/ return super end begin load(f = file + ".rb") $".push f #" return true rescue LoadError return ruby_require(file) end end alias toplevel_load load def load(file, priv=nil) found = find(file) if found return real_load(found, priv) else raise LoadError, "No such file to load -- #{file}" end end def find(file , paths = $:) dir = File.dirname(file) dir = "" if dir == "." base = File.basename(file) if dir.start_with?('/') return each_localized_path(dir, base).find{|full_path| File.readable? full_path} else return search_file(paths, dir, base) end end private def real_load(path, priv) src = MagicFile.open(path){|f| f.read} if priv eval("self", TOPLEVEL_BINDING).extend(Module.new {eval(src, nil, path)}) else eval(src, TOPLEVEL_BINDING, path) end end # @param paths load paths in which IRB find a localized file. # @param dir directory # @param file basename to be localized # # typically, for the parameters and a in paths, it searches # /// def search_file(lib_paths, dir, file) each_localized_path(dir, file) do |lc_path| lib_paths.each do |libpath| full_path = File.join(libpath, lc_path) return full_path if File.readable?(full_path) end redo if defined?(Gem) and Gem.try_activate(lc_path) end nil end def each_localized_path(dir, file) return enum_for(:each_localized_path) unless block_given? each_sublocale do |lc| yield lc.nil? ? File.join(dir, LOCALE_DIR, file) : File.join(dir, LOCALE_DIR, lc, file) end end def each_sublocale if @lang if @territory if @encoding_name yield "#{@lang}_#{@territory}.#{@encoding_name}@#{@modifier}" if @modifier yield "#{@lang}_#{@territory}.#{@encoding_name}" end yield "#{@lang}_#{@territory}@#{@modifier}" if @modifier yield "#{@lang}_#{@territory}" end if @encoding_name yield "#{@lang}.#{@encoding_name}@#{@modifier}" if @modifier yield "#{@lang}.#{@encoding_name}" end yield "#{@lang}@#{@modifier}" if @modifier yield "#{@lang}" end yield nil end end end ruby-token.rb000064400000016573147556205260007220 0ustar00# frozen_string_literal: false # # irb/ruby-token.rb - ruby tokens # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # # :stopdoc: module RubyToken EXPR_BEG = :EXPR_BEG EXPR_MID = :EXPR_MID EXPR_END = :EXPR_END EXPR_ARG = :EXPR_ARG EXPR_FNAME = :EXPR_FNAME EXPR_DOT = :EXPR_DOT EXPR_CLASS = :EXPR_CLASS class Token def initialize(seek, line_no, char_no) @seek = seek @line_no = line_no @char_no = char_no end attr_reader :seek, :line_no, :char_no end class TkNode < Token def initialize(seek, line_no, char_no) super end attr_reader :node end class TkId < Token def initialize(seek, line_no, char_no, name) super(seek, line_no, char_no) @name = name end attr_reader :name end class TkVal < Token def initialize(seek, line_no, char_no, value = nil) super(seek, line_no, char_no) @value = value end attr_reader :value end class TkOp < Token attr_accessor :name end class TkOPASGN < TkOp def initialize(seek, line_no, char_no, op) super(seek, line_no, char_no) op = TkReading2Token[op][0] unless op.kind_of?(Symbol) @op = op end attr_reader :op end class TkUnknownChar < Token def initialize(seek, line_no, char_no, id) super(seek, line_no, char_no) @name = name end attr_reader :name end class TkError < Token end def Token(token, value = nil) case token when String if (tk = TkReading2Token[token]).nil? IRB.fail TkReading2TokenNoKey, token end tk = Token(tk[0], value) if tk.kind_of?(TkOp) tk.name = token end return tk when Symbol if (tk = TkSymbol2Token[token]).nil? IRB.fail TkSymbol2TokenNoKey, token end return Token(tk[0], value) else if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty? token.new(@prev_seek, @prev_line_no, @prev_char_no) else token.new(@prev_seek, @prev_line_no, @prev_char_no, value) end end end TokenDefinitions = [ [:TkCLASS, TkId, "class", EXPR_CLASS], [:TkMODULE, TkId, "module", EXPR_BEG], [:TkDEF, TkId, "def", EXPR_FNAME], [:TkUNDEF, TkId, "undef", EXPR_FNAME], [:TkBEGIN, TkId, "begin", EXPR_BEG], [:TkRESCUE, TkId, "rescue", EXPR_MID], [:TkENSURE, TkId, "ensure", EXPR_BEG], [:TkEND, TkId, "end", EXPR_END], [:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD], [:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD], [:TkTHEN, TkId, "then", EXPR_BEG], [:TkELSIF, TkId, "elsif", EXPR_BEG], [:TkELSE, TkId, "else", EXPR_BEG], [:TkCASE, TkId, "case", EXPR_BEG], [:TkWHEN, TkId, "when", EXPR_BEG], [:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD], [:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD], [:TkFOR, TkId, "for", EXPR_BEG], [:TkBREAK, TkId, "break", EXPR_END], [:TkNEXT, TkId, "next", EXPR_END], [:TkREDO, TkId, "redo", EXPR_END], [:TkRETRY, TkId, "retry", EXPR_END], [:TkIN, TkId, "in", EXPR_BEG], [:TkDO, TkId, "do", EXPR_BEG], [:TkRETURN, TkId, "return", EXPR_MID], [:TkYIELD, TkId, "yield", EXPR_END], [:TkSUPER, TkId, "super", EXPR_END], [:TkSELF, TkId, "self", EXPR_END], [:TkNIL, TkId, "nil", EXPR_END], [:TkTRUE, TkId, "true", EXPR_END], [:TkFALSE, TkId, "false", EXPR_END], [:TkAND, TkId, "and", EXPR_BEG], [:TkOR, TkId, "or", EXPR_BEG], [:TkNOT, TkId, "not", EXPR_BEG], [:TkIF_MOD, TkId], [:TkUNLESS_MOD, TkId], [:TkWHILE_MOD, TkId], [:TkUNTIL_MOD, TkId], [:TkALIAS, TkId, "alias", EXPR_FNAME], [:TkDEFINED, TkId, "defined?", EXPR_END], [:TklBEGIN, TkId, "BEGIN", EXPR_END], [:TklEND, TkId, "END", EXPR_END], [:Tk__LINE__, TkId, "__LINE__", EXPR_END], [:Tk__FILE__, TkId, "__FILE__", EXPR_END], [:TkIDENTIFIER, TkId], [:TkFID, TkId], [:TkGVAR, TkId], [:TkCVAR, TkId], [:TkIVAR, TkId], [:TkCONSTANT, TkId], [:TkINTEGER, TkVal], [:TkFLOAT, TkVal], [:TkSTRING, TkVal], [:TkXSTRING, TkVal], [:TkREGEXP, TkVal], [:TkSYMBOL, TkVal], [:TkDSTRING, TkNode], [:TkDXSTRING, TkNode], [:TkDREGEXP, TkNode], [:TkNTH_REF, TkNode], [:TkBACK_REF, TkNode], [:TkUPLUS, TkOp, "+@"], [:TkUMINUS, TkOp, "-@"], [:TkPOW, TkOp, "**"], [:TkCMP, TkOp, "<=>"], [:TkEQ, TkOp, "=="], [:TkEQQ, TkOp, "==="], [:TkNEQ, TkOp, "!="], [:TkGEQ, TkOp, ">="], [:TkLEQ, TkOp, "<="], [:TkANDOP, TkOp, "&&"], [:TkOROP, TkOp, "||"], [:TkMATCH, TkOp, "=~"], [:TkNMATCH, TkOp, "!~"], [:TkDOT2, TkOp, ".."], [:TkDOT3, TkOp, "..."], [:TkAREF, TkOp, "[]"], [:TkASET, TkOp, "[]="], [:TkLSHFT, TkOp, "<<"], [:TkRSHFT, TkOp, ">>"], [:TkCOLON2, TkOp], [:TkCOLON3, TkOp], [:TkASSOC, TkOp, "=>"], [:TkQUESTION, TkOp, "?"], #? [:TkCOLON, TkOp, ":"], #: [:TkfLPAREN], # func( # [:TkfLBRACK], # func[ # [:TkfLBRACE], # func{ # [:TkSTAR], # *arg [:TkAMPER], # &arg # [:TkSYMBEG], # :SYMBOL [:TkGT, TkOp, ">"], [:TkLT, TkOp, "<"], [:TkPLUS, TkOp, "+"], [:TkMINUS, TkOp, "-"], [:TkMULT, TkOp, "*"], [:TkDIV, TkOp, "/"], [:TkMOD, TkOp, "%"], [:TkBITOR, TkOp, "|"], [:TkBITXOR, TkOp, "^"], [:TkBITAND, TkOp, "&"], [:TkBITNOT, TkOp, "~"], [:TkNOTOP, TkOp, "!"], [:TkBACKQUOTE, TkOp, "`"], [:TkASSIGN, Token, "="], [:TkDOT, Token, "."], [:TkLPAREN, Token, "("], #(exp) [:TkLBRACK, Token, "["], #[arry] [:TkLBRACE, Token, "{"], #{hash} [:TkRPAREN, Token, ")"], [:TkRBRACK, Token, "]"], [:TkRBRACE, Token, "}"], [:TkCOMMA, Token, ","], [:TkSEMICOLON, Token, ";"], [:TkCOMMENT], [:TkRD_COMMENT], [:TkSPACE], [:TkNL], [:TkEND_OF_SCRIPT], [:TkBACKSLASH, TkUnknownChar, "\\"], [:TkAT, TkUnknownChar, "@"], [:TkDOLLAR, TkUnknownChar, "$"], ] # {reading => token_class} # {reading => [token_class, *opt]} TkReading2Token = {} TkSymbol2Token = {} def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts) token_n = token_n.id2name if token_n.kind_of?(Symbol) if RubyToken.const_defined?(token_n) IRB.fail AlreadyDefinedToken, token_n end token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}") if reading if TkReading2Token[reading] IRB.fail TkReading2TokenDuplicateError, token_n, reading end if opts.empty? TkReading2Token[reading] = [token_c] else TkReading2Token[reading] = [token_c].concat(opts) end end TkSymbol2Token[token_n.intern] = token_c end for defs in TokenDefinitions def_token(*defs) end end # :startdoc: ruby-lex.rb000064400000060060147556205260006656 0ustar00# frozen_string_literal: false # # irb/ruby-lex.rb - ruby lexcal analyzer # $Release Version: 0.9.6$ # $Revision: 57027 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "e2mmap" require "irb/slex" require "irb/ruby-token" # :stopdoc: class RubyLex extend Exception2MessageMapper def_exception(:AlreadyDefinedToken, "Already defined token(%s)") def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')") def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')") def_exception(:TkReading2TokenDuplicateError, "key duplicate(token_n='%s', key='%s')") def_exception(:SyntaxError, "%s") def_exception(:TerminateLineInput, "Terminate Line Input") include RubyToken class << self attr_accessor :debug_level def debug? @debug_level > 0 end end @debug_level = 0 def initialize lex_init set_input(STDIN) @seek = 0 @exp_line_no = @line_no = 1 @base_char_no = 0 @char_no = 0 @rests = [] @readed = [] @here_readed = [] @indent = 0 @indent_stack = [] @lex_state = EXPR_BEG @space_seen = false @here_header = false @post_symbeg = false @continue = false @line = "" @skip_space = false @readed_auto_clean_up = false @exception_on_syntax_error = true @prompt = nil end attr_accessor :skip_space attr_accessor :readed_auto_clean_up attr_accessor :exception_on_syntax_error attr_reader :seek attr_reader :char_no attr_reader :line_no attr_reader :indent # io functions def set_input(io, p = nil, &block) @io = io if p.respond_to?(:call) @input = p elsif block_given? @input = block else @input = Proc.new{@io.gets} end end def get_readed if idx = @readed.rindex("\n") @base_char_no = @readed.size - (idx + 1) else @base_char_no += @readed.size end readed = @readed.join("") @readed = [] readed end def getc while @rests.empty? @rests.push nil unless buf_input end c = @rests.shift if @here_header @here_readed.push c else @readed.push c end @seek += 1 if c == "\n" @line_no += 1 @char_no = 0 else @char_no += 1 end c end def gets l = "" while c = getc l.concat(c) break if c == "\n" end return nil if l == "" and c.nil? l end def eof? @io.eof? end def getc_of_rests if @rests.empty? nil else getc end end def ungetc(c = nil) if @here_readed.empty? c2 = @readed.pop else c2 = @here_readed.pop end c = c2 unless c @rests.unshift c #c = @seek -= 1 if c == "\n" @line_no -= 1 if idx = @readed.rindex("\n") @char_no = idx + 1 else @char_no = @base_char_no + @readed.size end else @char_no -= 1 end end def peek_equal?(str) chrs = str.split(//) until @rests.size >= chrs.size return false unless buf_input end @rests[0, chrs.size] == chrs end def peek_match?(regexp) while @rests.empty? return false unless buf_input end regexp =~ @rests.join("") end def peek(i = 0) while @rests.size <= i return nil unless buf_input end @rests[i] end def buf_input prompt line = @input.call return nil unless line @rests.concat line.chars.to_a true end private :buf_input def set_prompt(p = nil, &block) p = block if block_given? if p.respond_to?(:call) @prompt = p else @prompt = Proc.new{print p} end end def prompt if @prompt @prompt.call(@ltype, @indent, @continue, @line_no) end end def initialize_input @ltype = nil @quoted = nil @indent = 0 @indent_stack = [] @lex_state = EXPR_BEG @space_seen = false @here_header = false @continue = false @post_symbeg = false prompt @line = "" @exp_line_no = @line_no end def each_top_level_statement initialize_input catch(:TERM_INPUT) do loop do begin @continue = false prompt unless l = lex throw :TERM_INPUT if @line == '' else @line.concat l if @ltype or @continue or @indent > 0 next end end if @line != "\n" @line.force_encoding(@io.encoding) yield @line, @exp_line_no end break unless l @line = '' @exp_line_no = @line_no @indent = 0 @indent_stack = [] prompt rescue TerminateLineInput initialize_input prompt get_readed end end end end def lex until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) && !@continue or tk.nil?) end line = get_readed if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil? nil else line end end def token @prev_seek = @seek @prev_line_no = @line_no @prev_char_no = @char_no begin begin tk = @OP.match(self) @space_seen = tk.kind_of?(TkSPACE) @lex_state = EXPR_END if @post_symbeg && tk.kind_of?(TkOp) @post_symbeg = tk.kind_of?(TkSYMBEG) rescue SyntaxError raise if @exception_on_syntax_error tk = TkError.new(@seek, @line_no, @char_no) end end while @skip_space and tk.kind_of?(TkSPACE) if @readed_auto_clean_up get_readed end tk end ENINDENT_CLAUSE = [ "case", "class", "def", "do", "for", "if", "module", "unless", "until", "while", "begin" ] DEINDENT_CLAUSE = ["end" ] PERCENT_LTYPE = { "q" => "\'", "Q" => "\"", "x" => "\`", "r" => "/", "w" => "]", "W" => "]", "i" => "]", "I" => "]", "s" => ":" } PERCENT_PAREN = { "{" => "}", "[" => "]", "<" => ">", "(" => ")" } Ltype2Token = { "\'" => TkSTRING, "\"" => TkSTRING, "\`" => TkXSTRING, "/" => TkREGEXP, "]" => TkDSTRING, ":" => TkSYMBOL } DLtype2Token = { "\"" => TkDSTRING, "\`" => TkDXSTRING, "/" => TkDREGEXP, } def lex_init() @OP = IRB::SLex.new @OP.def_rules("\0", "\004", "\032") do |op, io| Token(TkEND_OF_SCRIPT) end @OP.def_rules(" ", "\t", "\f", "\r", "\13") do |op, io| @space_seen = true while getc =~ /[ \t\f\r\13]/; end ungetc Token(TkSPACE) end @OP.def_rule("#") do |op, io| identify_comment end @OP.def_rule("=begin", proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do |op, io| @ltype = "=" until getc == "\n"; end until peek_equal?("=end") && peek(4) =~ /\s/ until getc == "\n"; end end gets @ltype = nil Token(TkRD_COMMENT) end @OP.def_rule("\n") do |op, io| print "\\n\n" if RubyLex.debug? case @lex_state when EXPR_BEG, EXPR_FNAME, EXPR_DOT @continue = true else @continue = false @lex_state = EXPR_BEG until (@indent_stack.empty? || [TkLPAREN, TkLBRACK, TkLBRACE, TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) @indent_stack.pop end end @here_header = false @here_readed = [] Token(TkNL) end @OP.def_rules("*", "**", "=", "==", "===", "=~", "<=>", "<", "<=", ">", ">=", ">>", "!", "!=", "!~") do |op, io| case @lex_state when EXPR_FNAME, EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_BEG end Token(op) end @OP.def_rules("<<") do |op, io| tk = nil if @lex_state != EXPR_END && @lex_state != EXPR_CLASS && (@lex_state != EXPR_ARG || @space_seen) c = peek(0) if /\S/ =~ c && (/["'`]/ =~ c || /\w/ =~ c || c == "-" || c == "~") tk = identify_here_document end end unless tk tk = Token(op) case @lex_state when EXPR_FNAME, EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_BEG end end tk end @OP.def_rules("'", '"') do |op, io| identify_string(op) end @OP.def_rules("`") do |op, io| if @lex_state == EXPR_FNAME @lex_state = EXPR_END Token(op) else identify_string(op) end end @OP.def_rules('?') do |op, io| if @lex_state == EXPR_END @lex_state = EXPR_BEG Token(TkQUESTION) else ch = getc if @lex_state == EXPR_ARG && ch =~ /\s/ ungetc @lex_state = EXPR_BEG; Token(TkQUESTION) else if (ch == '\\') read_escape end @lex_state = EXPR_END Token(TkINTEGER) end end end @OP.def_rules("&", "&&", "|", "||") do |op, io| @lex_state = EXPR_BEG Token(op) end @OP.def_rules("+=", "-=", "*=", "**=", "&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do |op, io| @lex_state = EXPR_BEG op =~ /^(.*)=$/ Token(TkOPASGN, $1) end @OP.def_rule("+@", proc{|op, io| @lex_state == EXPR_FNAME}) do |op, io| @lex_state = EXPR_ARG Token(op) end @OP.def_rule("-@", proc{|op, io| @lex_state == EXPR_FNAME}) do |op, io| @lex_state = EXPR_ARG Token(op) end @OP.def_rules("+", "-") do |op, io| catch(:RET) do if @lex_state == EXPR_ARG if @space_seen and peek(0) =~ /[0-9]/ throw :RET, identify_number else @lex_state = EXPR_BEG end elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/ throw :RET, identify_number else @lex_state = EXPR_BEG end Token(op) end end @OP.def_rule(".") do |op, io| @lex_state = EXPR_BEG if peek(0) =~ /[0-9]/ ungetc identify_number else # for "obj.if" etc. @lex_state = EXPR_DOT Token(TkDOT) end end @OP.def_rules("..", "...") do |op, io| @lex_state = EXPR_BEG Token(op) end lex_int2 end def lex_int2 @OP.def_rules("]", "}", ")") do |op, io| @lex_state = EXPR_END @indent -= 1 @indent_stack.pop Token(op) end @OP.def_rule(":") do |op, io| if @lex_state == EXPR_END || peek(0) =~ /\s/ @lex_state = EXPR_BEG Token(TkCOLON) else @lex_state = EXPR_FNAME Token(TkSYMBEG) end end @OP.def_rule("::") do |op, io| if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen @lex_state = EXPR_BEG Token(TkCOLON3) else @lex_state = EXPR_DOT Token(TkCOLON2) end end @OP.def_rule("/") do |op, io| if @lex_state == EXPR_BEG || @lex_state == EXPR_MID identify_string(op) elsif peek(0) == '=' getc @lex_state = EXPR_BEG Token(TkOPASGN, "/") #/) elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ identify_string(op) else @lex_state = EXPR_BEG Token("/") #/) end end @OP.def_rules("^") do |op, io| @lex_state = EXPR_BEG Token("^") end @OP.def_rules(",") do |op, io| @lex_state = EXPR_BEG Token(op) end @OP.def_rules(";") do |op, io| @lex_state = EXPR_BEG until (@indent_stack.empty? || [TkLPAREN, TkLBRACK, TkLBRACE, TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last)) @indent_stack.pop end Token(op) end @OP.def_rule("~") do |op, io| @lex_state = EXPR_BEG Token("~") end @OP.def_rule("~@", proc{|op, io| @lex_state == EXPR_FNAME}) do |op, io| @lex_state = EXPR_BEG Token("~") end @OP.def_rule("(") do |op, io| @indent += 1 if @lex_state == EXPR_BEG || @lex_state == EXPR_MID @lex_state = EXPR_BEG tk_c = TkfLPAREN else @lex_state = EXPR_BEG tk_c = TkLPAREN end @indent_stack.push tk_c Token(tk_c) end @OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do |op, io| @lex_state = EXPR_ARG Token("[]") end @OP.def_rule("[]=", proc{|op, io| @lex_state == EXPR_FNAME}) do |op, io| @lex_state = EXPR_ARG Token("[]=") end @OP.def_rule("[") do |op, io| @indent += 1 if @lex_state == EXPR_FNAME tk_c = TkfLBRACK else if @lex_state == EXPR_BEG || @lex_state == EXPR_MID tk_c = TkLBRACK elsif @lex_state == EXPR_ARG && @space_seen tk_c = TkLBRACK else tk_c = TkfLBRACK end @lex_state = EXPR_BEG end @indent_stack.push tk_c Token(tk_c) end @OP.def_rule("{") do |op, io| @indent += 1 if @lex_state != EXPR_END && @lex_state != EXPR_ARG tk_c = TkLBRACE else tk_c = TkfLBRACE end @lex_state = EXPR_BEG @indent_stack.push tk_c Token(tk_c) end @OP.def_rule('\\') do |op, io| if getc == "\n" @space_seen = true @continue = true Token(TkSPACE) else read_escape Token("\\") end end @OP.def_rule('%') do |op, io| if @lex_state == EXPR_BEG || @lex_state == EXPR_MID identify_quotation elsif peek(0) == '=' getc Token(TkOPASGN, :%) elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/ identify_quotation else @lex_state = EXPR_BEG Token("%") #)) end end @OP.def_rule('$') do |op, io| identify_gvar end @OP.def_rule('@') do |op, io| if peek(0) =~ /[\w@]/ ungetc identify_identifier else Token("@") end end @OP.def_rule("") do |op, io| printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug? if peek(0) =~ /[0-9]/ t = identify_number elsif peek(0) =~ /[^\x00-\/:-@\[-^`{-\x7F]/ t = identify_identifier end printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug? t end p @OP if RubyLex.debug? end def identify_gvar @lex_state = EXPR_END case ch = getc when /[~_*$?!@\/\\;,=:<>".]/ #" Token(TkGVAR, "$" + ch) when "-" Token(TkGVAR, "$-" + getc) when "&", "`", "'", "+" Token(TkBACK_REF, "$"+ch) when /[1-9]/ while getc =~ /[0-9]/; end ungetc Token(TkNTH_REF) when /\w/ ungetc ungetc identify_identifier else ungetc Token("$") end end def identify_identifier token = "" if peek(0) =~ /[$@]/ token.concat(c = getc) if c == "@" and peek(0) == "@" token.concat getc end end while (ch = getc) =~ /[^\x00-\/:-@\[-^`{-\x7F]/ print ":", ch, ":" if RubyLex.debug? token.concat ch end ungetc if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "=" token.concat getc end # almost fix token case token when /^\$/ return Token(TkGVAR, token) when /^\@\@/ @lex_state = EXPR_END # p Token(TkCVAR, token) return Token(TkCVAR, token) when /^\@/ @lex_state = EXPR_END return Token(TkIVAR, token) end if @lex_state != EXPR_DOT print token, "\n" if RubyLex.debug? token_c, *trans = TkReading2Token[token] if token_c # reserved word? if (@lex_state != EXPR_BEG && @lex_state != EXPR_FNAME && trans[1]) # modifiers token_c = TkSymbol2Token[trans[1]] @lex_state = trans[0] else if @lex_state != EXPR_FNAME and peek(0) != ':' if ENINDENT_CLAUSE.include?(token) # check for ``class = val'' etc. valid = true case token when "class" valid = false unless peek_match?(/^\s*(<<|\w|::)/) when "def" valid = false if peek_match?(/^\s*(([+\-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/) when "do" valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&)/) when *ENINDENT_CLAUSE valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&|\|)/) else # no nothing end if valid if token == "do" if ![TkFOR, TkWHILE, TkUNTIL].include?(@indent_stack.last) @indent += 1 @indent_stack.push token_c end else @indent += 1 @indent_stack.push token_c end end elsif DEINDENT_CLAUSE.include?(token) @indent -= 1 @indent_stack.pop end @lex_state = trans[0] else @lex_state = EXPR_END end end return Token(token_c, token) end end if @lex_state == EXPR_FNAME @lex_state = EXPR_END if peek(0) == '=' token.concat getc end elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_END end if token[0, 1] =~ /[A-Z]/ return Token(TkCONSTANT, token) elsif token[token.size - 1, 1] =~ /[!?]/ return Token(TkFID, token) else return Token(TkIDENTIFIER, token) end end def identify_here_document ch = getc if ch == "-" || ch == "~" ch = getc indent = true end if /['"`]/ =~ ch lt = ch quoted = "" while (c = getc) && c != lt quoted.concat c end else lt = '"' quoted = ch.dup while (c = getc) && c =~ /\w/ quoted.concat c end ungetc end ltback, @ltype = @ltype, lt reserve = [] while ch = getc reserve.push ch if ch == "\\" reserve.push ch = getc elsif ch == "\n" break end end @here_header = false line = "" while ch = getc if ch == "\n" if line == quoted break end line = "" else line.concat ch unless indent && line == "" && /\s/ =~ ch if @ltype != "'" && ch == "#" && peek(0) == "{" identify_string_dvar end end end @here_header = true @here_readed.concat reserve while ch = reserve.pop ungetc ch end @ltype = ltback @lex_state = EXPR_END Token(Ltype2Token[lt]) end def identify_quotation ch = getc if lt = PERCENT_LTYPE[ch] ch = getc elsif ch =~ /\W/ lt = "\"" else RubyLex.fail SyntaxError, "unknown type of %string" end @quoted = ch unless @quoted = PERCENT_PAREN[ch] identify_string(lt, @quoted) end def identify_number @lex_state = EXPR_END if peek(0) == "0" && peek(1) !~ /[.eE]/ getc case peek(0) when /[xX]/ ch = getc match = /[0-9a-fA-F_]/ when /[bB]/ ch = getc match = /[01_]/ when /[oO]/ ch = getc match = /[0-7_]/ when /[dD]/ ch = getc match = /[0-9_]/ when /[0-7]/ match = /[0-7_]/ when /[89]/ RubyLex.fail SyntaxError, "Invalid octal digit" else return Token(TkINTEGER) end len0 = true non_digit = false while ch = getc if match =~ ch if ch == "_" if non_digit RubyLex.fail SyntaxError, "trailing `#{ch}' in number" else non_digit = ch end else non_digit = false len0 = false end else ungetc if len0 RubyLex.fail SyntaxError, "numeric literal without digits" end if non_digit RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" end break end end return Token(TkINTEGER) end type = TkINTEGER allow_point = true allow_e = true non_digit = false while ch = getc case ch when /[0-9]/ non_digit = false when "_" non_digit = ch when allow_point && "." if non_digit RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" end type = TkFLOAT if peek(0) !~ /[0-9]/ type = TkINTEGER ungetc break end allow_point = false when allow_e && "e", allow_e && "E" if non_digit RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" end type = TkFLOAT if peek(0) =~ /[+-]/ getc end allow_e = false allow_point = false non_digit = ch else if non_digit RubyLex.fail SyntaxError, "trailing `#{non_digit}' in number" end ungetc break end end Token(type) end def identify_string(ltype, quoted = ltype) @ltype = ltype @quoted = quoted subtype = nil begin nest = 0 while ch = getc if @quoted == ch and nest == 0 break elsif @ltype != "'" && ch == "#" && peek(0) == "{" identify_string_dvar elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#" subtype = true elsif ch == '\\' and @ltype == "'" #' case ch = getc when "\\", "\n", "'" else ungetc end elsif ch == '\\' #' read_escape end if PERCENT_PAREN.values.include?(@quoted) if PERCENT_PAREN[ch] == @quoted nest += 1 elsif ch == @quoted nest -= 1 end end end if @ltype == "/" while /[imxoesun]/ =~ peek(0) getc end end if subtype Token(DLtype2Token[ltype]) else Token(Ltype2Token[ltype]) end ensure @ltype = nil @quoted = nil @lex_state = EXPR_END end end def identify_string_dvar begin getc reserve_continue = @continue reserve_ltype = @ltype reserve_indent = @indent reserve_indent_stack = @indent_stack reserve_state = @lex_state reserve_quoted = @quoted @ltype = nil @quoted = nil @indent = 0 @indent_stack = [] @lex_state = EXPR_BEG loop do @continue = false prompt tk = token if @ltype or @continue or @indent >= 0 next end break if tk.kind_of?(TkRBRACE) end ensure @continue = reserve_continue @ltype = reserve_ltype @indent = reserve_indent @indent_stack = reserve_indent_stack @lex_state = reserve_state @quoted = reserve_quoted end end def identify_comment @ltype = "#" while ch = getc if ch == "\n" @ltype = nil ungetc break end end return Token(TkCOMMENT) end def read_escape case ch = getc when "\n", "\r", "\f" when "\\", "n", "t", "r", "f", "v", "a", "e", "b", "s" #" when /[0-7]/ ungetc ch 3.times do case ch = getc when /[0-7]/ when nil break else ungetc break end end when "x" 2.times do case ch = getc when /[0-9a-fA-F]/ when nil break else ungetc break end end when "M" if (ch = getc) != '-' ungetc else if (ch = getc) == "\\" #" read_escape end end when "C", "c" #, "^" if ch == "C" and (ch = getc) != "-" ungetc elsif (ch = getc) == "\\" #" read_escape end else # other characters end end end # :startdoc: xmp.rb000064400000010021147556205260005703 0ustar00# frozen_string_literal: false # # xmp.rb - irb version of gotoken xmp # $Release Version: 0.9$ # $Revision: 53141 $ # by Keiju ISHITSUKA(Nippon Rational Inc.) # # -- # # # require "irb" require "irb/frame" # An example printer for irb. # # It's much like the standard library PrettyPrint, that shows the value of each # expression as it runs. # # In order to use this library, you must first require it: # # require 'irb/xmp' # # Now, you can take advantage of the Object#xmp convenience method. # # xmp < foo = "bar" # #==>"bar" # #=> baz = 42 # #==>42 # # You can also create an XMP object, with an optional binding to print # expressions in the given binding: # # ctx = binding # x = XMP.new ctx # x.puts # #=> today = "a good day" # #==>"a good day" # ctx.eval 'today # is what?' # #=> "a good day" class XMP # Creates a new XMP object. # # The top-level binding or, optional +bind+ parameter will be used when # creating the workspace. See WorkSpace.new for more information. # # This uses the +:XMP+ prompt mode, see IRB@Customizing+the+IRB+Prompt for # full detail. def initialize(bind = nil) IRB.init_config(nil) IRB.conf[:PROMPT_MODE] = :XMP bind = IRB::Frame.top(1) unless bind ws = IRB::WorkSpace.new(bind) @io = StringInputMethod.new @irb = IRB::Irb.new(ws, @io) @irb.context.ignore_sigint = false IRB.conf[:MAIN_CONTEXT] = @irb.context end # Evaluates the given +exps+, for example: # # require 'irb/xmp' # x = XMP.new # # x.puts '{:a => 1, :b => 2, :c => 3}' # #=> {:a => 1, :b => 2, :c => 3} # # ==>{:a=>1, :b=>2, :c=>3} # x.puts 'foo = "bar"' # # => foo = "bar" # # ==>"bar" def puts(exps) @io.puts exps if @irb.context.ignore_sigint begin trap_proc_b = trap("SIGINT"){@irb.signal_handle} catch(:IRB_EXIT) do @irb.eval_input end ensure trap("SIGINT", trap_proc_b) end else catch(:IRB_EXIT) do @irb.eval_input end end end # A custom InputMethod class used by XMP for evaluating string io. class StringInputMethod < IRB::InputMethod # Creates a new StringInputMethod object def initialize super @exps = [] end # Whether there are any expressions left in this printer. def eof? @exps.empty? end # Reads the next expression from this printer. # # See IO#gets for more information. def gets while l = @exps.shift next if /^\s+$/ =~ l l.concat "\n" print @prompt, l break end l end # Concatenates all expressions in this printer, separated by newlines. # # An Encoding::CompatibilityError is raised of the given +exps+'s encoding # doesn't match the previous expression evaluated. def puts(exps) if @encoding and exps.encoding != @encoding enc = Encoding.compatible?(@exps.join("\n"), exps) if enc.nil? raise Encoding::CompatibilityError, "Encoding in which the passed expression is encoded is not compatible to the preceding's one" else @encoding = enc end else @encoding = exps.encoding end @exps.concat exps.split(/\n/) end # Returns the encoding of last expression printed by #puts. attr_reader :encoding end end # A convenience method that's only available when the you require the IRB::XMP standard library. # # Creates a new XMP object, using the given expressions as the +exps+ # parameter, and optional binding as +bind+ or uses the top-level binding. Then # evaluates the given expressions using the +:XMP+ prompt mode. # # For example: # # require 'irb/xmp' # ctx = binding # xmp 'foo = "bar"', ctx # #=> foo = "bar" # #==>"bar" # ctx.eval 'foo' # #=> "bar" # # See XMP.new for more information. def xmp(exps, bind = nil) bind = IRB::Frame.top(1) unless bind xmp = XMP.new(bind) xmp.puts exps xmp end completion.rb000064400000014761147556205260007267 0ustar00# frozen_string_literal: false # # irb/completor.rb - # $Release Version: 0.9$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ishitsuka.com) # From Original Idea of shugo@ruby-lang.org # require "readline" module IRB module InputCompletor # :nodoc: # Set of reserved words used by Ruby, you should not use these for # constants or variables ReservedWords = %w[ BEGIN END alias and begin break case class def defined do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield ] CompletionProc = proc { |input| bind = IRB.conf[:MAIN_CONTEXT].workspace.binding case input when /^((["'`]).*\2)\.([^.]*)$/ # String receiver = $1 message = Regexp.quote($3) candidates = String.instance_methods.collect{|m| m.to_s} select_message(receiver, message, candidates) when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp receiver = $1 message = Regexp.quote($2) candidates = Regexp.instance_methods.collect{|m| m.to_s} select_message(receiver, message, candidates) when /^([^\]]*\])\.([^.]*)$/ # Array receiver = $1 message = Regexp.quote($2) candidates = Array.instance_methods.collect{|m| m.to_s} select_message(receiver, message, candidates) when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash receiver = $1 message = Regexp.quote($2) candidates = Proc.instance_methods.collect{|m| m.to_s} candidates |= Hash.instance_methods.collect{|m| m.to_s} select_message(receiver, message, candidates) when /^(:[^:.]*)$/ # Symbol if Symbol.respond_to?(:all_symbols) sym = $1 candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name} candidates.grep(/^#{Regexp.quote(sym)}/) else [] end when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods receiver = $1 candidates = Object.constants.collect{|m| m.to_s} candidates.grep(/^#{receiver}/).collect{|e| "::" + e} when /^([A-Z].*)::([^:.]*)$/ # Constant or class methods receiver = $1 message = Regexp.quote($2) begin candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind) candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind) rescue Exception candidates = [] end select_message(receiver, message, candidates, "::") when /^(:[^:.]+)(\.|::)([^.]*)$/ # Symbol receiver = $1 sep = $2 message = Regexp.quote($3) candidates = Symbol.instance_methods.collect{|m| m.to_s} select_message(receiver, message, candidates, sep) when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/ # Numeric receiver = $1 sep = $5 message = Regexp.quote($6) begin candidates = eval(receiver, bind).methods.collect{|m| m.to_s} rescue Exception candidates = [] end select_message(receiver, message, candidates, sep) when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/ # Numeric(0xFFFF) receiver = $1 sep = $2 message = Regexp.quote($3) begin candidates = eval(receiver, bind).methods.collect{|m| m.to_s} rescue Exception candidates = [] end select_message(receiver, message, candidates, sep) when /^(\$[^.]*)$/ # global var regmessage = Regexp.new(Regexp.quote($1)) candidates = global_variables.collect{|m| m.to_s}.grep(regmessage) when /^([^."].*)(\.|::)([^.]*)$/ # variable.func or func.func receiver = $1 sep = $2 message = Regexp.quote($3) gv = eval("global_variables", bind).collect{|m| m.to_s} lv = eval("local_variables", bind).collect{|m| m.to_s} iv = eval("instance_variables", bind).collect{|m| m.to_s} cv = eval("self.class.constants", bind).collect{|m| m.to_s} if (gv | lv | iv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver # foo.func and foo is var. OR # foo::func and foo is var. OR # foo::Const and foo is var. OR # Foo::Bar.func begin candidates = [] rec = eval(receiver, bind) if sep == "::" and rec.kind_of?(Module) candidates = rec.constants.collect{|m| m.to_s} end candidates |= rec.methods.collect{|m| m.to_s} rescue Exception candidates = [] end else # func1.func2 candidates = [] ObjectSpace.each_object(Module){|m| begin name = m.name rescue Exception name = "" end begin next if name != "IRB::Context" and /^(IRB|SLex|RubyLex|RubyToken)/ =~ name rescue Exception next end candidates.concat m.instance_methods(false).collect{|x| x.to_s} } candidates.sort! candidates.uniq! end select_message(receiver, message, candidates, sep) when /^\.([^.]*)$/ # unknown(maybe String) receiver = "" message = Regexp.quote($1) candidates = String.instance_methods(true).collect{|m| m.to_s} select_message(receiver, message, candidates) else candidates = eval("methods | private_methods | local_variables | instance_variables | self.class.constants", bind).collect{|m| m.to_s} (candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/) end } # Set of available operators in Ruby Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~] def self.select_message(receiver, message, candidates, sep = ".") candidates.grep(/^#{message}/).collect do |e| case e when /^[a-zA-Z_]/ receiver + sep + e when /^[0-9]/ when *Operators #receiver + " " + e end end end end end if Readline.respond_to?("basic_word_break_characters=") Readline.basic_word_break_characters= " \t\n`><=;|&{(" end Readline.completion_append_character = nil Readline.completion_proc = IRB::InputCompletor::CompletionProc src_encoding.rb000064400000000171147556205260007541 0ustar00# frozen_string_literal: false # DO NOT WRITE ANY MAGIC COMMENT HERE. def default_src_encoding return __ENCODING__ end context.rb000064400000030670147556205260006577 0ustar00# frozen_string_literal: false # # irb/context.rb - irb context # $Release Version: 0.9.6$ # $Revision: 57071 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "irb/workspace" require "irb/inspector" require "irb/output-method" module IRB # A class that wraps the current state of the irb session, including the # configuration of IRB.conf. class Context # Creates a new IRB context. # # The optional +input_method+ argument: # # +nil+:: uses stdin or Readline # +String+:: uses a File # +other+:: uses this as InputMethod def initialize(irb, workspace = nil, input_method = nil, output_method = nil) @irb = irb if workspace @workspace = workspace else @workspace = WorkSpace.new end @thread = Thread.current if defined? Thread # copy of default configuration @ap_name = IRB.conf[:AP_NAME] @rc = IRB.conf[:RC] @load_modules = IRB.conf[:LOAD_MODULES] @use_readline = IRB.conf[:USE_READLINE] @verbose = IRB.conf[:VERBOSE] @io = nil self.inspect_mode = IRB.conf[:INSPECT_MODE] self.math_mode = IRB.conf[:MATH_MODE] if IRB.conf[:MATH_MODE] self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER] self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER] self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY] @ignore_sigint = IRB.conf[:IGNORE_SIGINT] @ignore_eof = IRB.conf[:IGNORE_EOF] @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT] self.prompt_mode = IRB.conf[:PROMPT_MODE] if IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager) @irb_name = IRB.conf[:IRB_NAME] else @irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s end @irb_path = "(" + @irb_name + ")" case input_method when nil case use_readline? when nil if (defined?(ReadlineInputMethod) && STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY) @io = ReadlineInputMethod.new else @io = StdioInputMethod.new end when false @io = StdioInputMethod.new when true if defined?(ReadlineInputMethod) @io = ReadlineInputMethod.new else @io = StdioInputMethod.new end end when String @io = FileInputMethod.new(input_method) @irb_name = File.basename(input_method) @irb_path = input_method else @io = input_method end self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY] if output_method @output_method = output_method else @output_method = StdioOutputMethod.new end @echo = IRB.conf[:ECHO] if @echo.nil? @echo = true end self.debug_level = IRB.conf[:DEBUG_LEVEL] end # The top-level workspace, see WorkSpace#main def main @workspace.main end # The toplevel workspace, see #home_workspace attr_reader :workspace_home # WorkSpace in the current context attr_accessor :workspace # The current thread in this context attr_reader :thread # The current input method # # Can be either StdioInputMethod, ReadlineInputMethod, FileInputMethod or # other specified when the context is created. See ::new for more # information on +input_method+. attr_accessor :io # Current irb session attr_accessor :irb # A copy of the default IRB.conf[:AP_NAME] attr_accessor :ap_name # A copy of the default IRB.conf[:RC] attr_accessor :rc # A copy of the default IRB.conf[:LOAD_MODULES] attr_accessor :load_modules # Can be either name from IRB.conf[:IRB_NAME], or the number of # the current job set by JobManager, such as irb#2 attr_accessor :irb_name # Can be either the #irb_name surrounded by parenthesis, or the # +input_method+ passed to Context.new attr_accessor :irb_path # Whether +Readline+ is enabled or not. # # A copy of the default IRB.conf[:USE_READLINE] # # See #use_readline= for more information. attr_reader :use_readline # A copy of the default IRB.conf[:INSPECT_MODE] attr_reader :inspect_mode # A copy of the default IRB.conf[:PROMPT_MODE] attr_reader :prompt_mode # Standard IRB prompt # # See IRB@Customizing+the+IRB+Prompt for more information. attr_accessor :prompt_i # IRB prompt for continuated strings # # See IRB@Customizing+the+IRB+Prompt for more information. attr_accessor :prompt_s # IRB prompt for continuated statement (e.g. immediately after an +if+) # # See IRB@Customizing+the+IRB+Prompt for more information. attr_accessor :prompt_c # See IRB@Customizing+the+IRB+Prompt for more information. attr_accessor :prompt_n # Can be either the default IRB.conf[:AUTO_INDENT], or the # mode set by #prompt_mode= # # To enable auto-indentation in irb: # # IRB.conf[:AUTO_INDENT] = true # # or # # irb_context.auto_indent_mode = true # # or # # IRB.CurrentContext.auto_indent_mode = true # # See IRB@Configuration for more information. attr_accessor :auto_indent_mode # The format of the return statement, set by #prompt_mode= using the # +:RETURN+ of the +mode+ passed to set the current #prompt_mode. attr_accessor :return_format # Whether ^C (+control-c+) will be ignored or not. # # If set to +false+, ^C will quit irb. # # If set to +true+, # # * during input: cancel input then return to top level. # * during execute: abandon current execution. attr_accessor :ignore_sigint # Whether ^D (+control-d+) will be ignored or not. # # If set to +false+, ^D will quit irb. attr_accessor :ignore_eof # Whether to echo the return value to output or not. # # Uses IRB.conf[:ECHO] if available, or defaults to +true+. # # puts "hello" # # hello # #=> nil # IRB.CurrentContext.echo = false # puts "omg" # # omg attr_accessor :echo # Whether verbose messages are displayed or not. # # A copy of the default IRB.conf[:VERBOSE] attr_accessor :verbose # The debug level of irb # # See #debug_level= for more information. attr_reader :debug_level # The limit of backtrace lines displayed as top +n+ and tail +n+. # # The default value is 16. # # Can also be set using the +--back-trace-limit+ command line option. # # See IRB@Command+line+options for more command line options. attr_accessor :back_trace_limit # Alias for #use_readline alias use_readline? use_readline # Alias for #rc alias rc? rc alias ignore_sigint? ignore_sigint alias ignore_eof? ignore_eof alias echo? echo # Returns whether messages are displayed or not. def verbose? if @verbose.nil? if defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) false elsif !STDIN.tty? or @io.kind_of?(FileInputMethod) true else false end else @verbose end end # Whether #verbose? is +true+, and +input_method+ is either # StdioInputMethod or ReadlineInputMethod, see #io for more information. def prompting? verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) || (defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod))) end # The return value of the last statement evaluated. attr_reader :last_value # Sets the return value from the last statement evaluated in this context # to #last_value. def set_last_value(value) @last_value = value @workspace.evaluate self, "_ = IRB.CurrentContext.last_value" end # Sets the +mode+ of the prompt in this context. # # See IRB@Customizing+the+IRB+Prompt for more information. def prompt_mode=(mode) @prompt_mode = mode pconf = IRB.conf[:PROMPT][mode] @prompt_i = pconf[:PROMPT_I] @prompt_s = pconf[:PROMPT_S] @prompt_c = pconf[:PROMPT_C] @prompt_n = pconf[:PROMPT_N] @return_format = pconf[:RETURN] if ai = pconf.include?(:AUTO_INDENT) @auto_indent_mode = ai else @auto_indent_mode = IRB.conf[:AUTO_INDENT] end end # Whether #inspect_mode is set or not, see #inspect_mode= for more detail. def inspect? @inspect_mode.nil? or @inspect_mode end # Whether #io uses a File for the +input_method+ passed when creating the # current context, see ::new def file_input? @io.class == FileInputMethod end # Specifies the inspect mode with +opt+: # # +true+:: display +inspect+ # +false+:: display +to_s+ # +nil+:: inspect mode in non-math mode, # non-inspect mode in math mode # # See IRB::Inspector for more information. # # Can also be set using the +--inspect+ and +--noinspect+ command line # options. # # See IRB@Command+line+options for more command line options. def inspect_mode=(opt) if i = Inspector::INSPECTORS[opt] @inspect_mode = opt @inspect_method = i i.init else case opt when nil if Inspector.keys_with_inspector(Inspector::INSPECTORS[true]).include?(@inspect_mode) self.inspect_mode = false elsif Inspector.keys_with_inspector(Inspector::INSPECTORS[false]).include?(@inspect_mode) self.inspect_mode = true else puts "Can't switch inspect mode." return end when /^\s*\{.*\}\s*$/ begin inspector = eval "proc#{opt}" rescue Exception puts "Can't switch inspect mode(#{opt})." return end self.inspect_mode = inspector when Proc self.inspect_mode = IRB::Inspector(opt) when Inspector prefix = "usr%d" i = 1 while Inspector::INSPECTORS[format(prefix, i)]; i += 1; end @inspect_mode = format(prefix, i) @inspect_method = opt Inspector.def_inspector(format(prefix, i), @inspect_method) else puts "Can't switch inspect mode(#{opt})." return end end print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose? @inspect_mode end # Obsolete method. # # Can be set using the +--noreadline+ and +--readline+ command line # options. # # See IRB@Command+line+options for more command line options. def use_readline=(opt) print "This method is obsolete." print "Do nothing." end # Sets the debug level of irb # # Can also be set using the +--irb_debug+ command line option. # # See IRB@Command+line+options for more command line options. def debug_level=(value) @debug_level = value RubyLex.debug_level = value end # Whether or not debug mode is enabled, see #debug_level=. def debug? @debug_level > 0 end def evaluate(line, line_no) # :nodoc: @line_no = line_no set_last_value(@workspace.evaluate(self, line, irb_path, line_no)) end def inspect_last_value # :nodoc: @inspect_method.inspect_value(@last_value) end alias __exit__ exit # Exits the current session, see IRB.irb_exit def exit(ret = 0) IRB.irb_exit(@irb, ret) end NOPRINTING_IVARS = ["@last_value"] # :nodoc: NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc: IDNAME_IVARS = ["@prompt_mode"] # :nodoc: alias __inspect__ inspect def inspect # :nodoc: array = [] for ivar in instance_variables.sort{|e1, e2| e1 <=> e2} ivar = ivar.to_s name = ivar.sub(/^@(.*)$/, '\1') val = instance_eval(ivar) case ivar when *NOPRINTING_IVARS array.push format("conf.%s=%s", name, "...") when *NO_INSPECTING_IVARS array.push format("conf.%s=%s", name, val.to_s) when *IDNAME_IVARS array.push format("conf.%s=:%s", name, val.id2name) else array.push format("conf.%s=%s", name, val.inspect) end end array.join("\n") end alias __to_s__ to_s alias to_s inspect end end notifier.rb000064400000016274147556205260006736 0ustar00# frozen_string_literal: false # # notifier.rb - output methods used by irb # $Release Version: 0.9.6$ # $Revision: 56371 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "e2mmap" require "irb/output-method" module IRB # An output formatter used internally by the lexer. module Notifier extend Exception2MessageMapper def_exception :ErrUndefinedNotifier, "undefined notifier level: %d is specified" def_exception :ErrUnrecognizedLevel, "unrecognized notifier level: %s is specified" # Define a new Notifier output source, returning a new CompositeNotifier # with the given +prefix+ and +output_method+. # # The optional +prefix+ will be appended to all objects being inspected # during output, using the given +output_method+ as the output source. If # no +output_method+ is given, StdioOutputMethod will be used, and all # expressions will be sent directly to STDOUT without any additional # formatting. def def_notifier(prefix = "", output_method = StdioOutputMethod.new) CompositeNotifier.new(prefix, output_method) end module_function :def_notifier # An abstract class, or superclass, for CompositeNotifier and # LeveledNotifier to inherit. It provides several wrapper methods for the # OutputMethod object used by the Notifier. class AbstractNotifier # Creates a new Notifier object def initialize(prefix, base_notifier) @prefix = prefix @base_notifier = base_notifier end # The +prefix+ for this Notifier, which is appended to all objects being # inspected during output. attr_reader :prefix # A wrapper method used to determine whether notifications are enabled. # # Defaults to +true+. def notify? true end # See OutputMethod#print for more detail. def print(*opts) @base_notifier.print prefix, *opts if notify? end # See OutputMethod#printn for more detail. def printn(*opts) @base_notifier.printn prefix, *opts if notify? end # See OutputMethod#printf for more detail. def printf(format, *opts) @base_notifier.printf(prefix + format, *opts) if notify? end # See OutputMethod#puts for more detail. def puts(*objs) if notify? @base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s}) end end # Same as #ppx, except it uses the #prefix given during object # initialization. # See OutputMethod#ppx for more detail. def pp(*objs) if notify? @base_notifier.ppx @prefix, *objs end end # Same as #pp, except it concatenates the given +prefix+ with the #prefix # given during object initialization. # # See OutputMethod#ppx for more detail. def ppx(prefix, *objs) if notify? @base_notifier.ppx @prefix+prefix, *objs end end # Execute the given block if notifications are enabled. def exec_if yield(@base_notifier) if notify? end end # A class that can be used to create a group of notifier objects with the # intent of representing a leveled notification system for irb. # # This class will allow you to generate other notifiers, and assign them # the appropriate level for output. # # The Notifier class provides a class-method Notifier.def_notifier to # create a new composite notifier. Using the first composite notifier # object you create, sibling notifiers can be initialized with # #def_notifier. class CompositeNotifier < AbstractNotifier # Create a new composite notifier object with the given +prefix+, and # +base_notifier+ to use for output. def initialize(prefix, base_notifier) super @notifiers = [D_NOMSG] @level_notifier = D_NOMSG end # List of notifiers in the group attr_reader :notifiers # Creates a new LeveledNotifier in the composite #notifiers group. # # The given +prefix+ will be assigned to the notifier, and +level+ will # be used as the index of the #notifiers Array. # # This method returns the newly created instance. def def_notifier(level, prefix = "") notifier = LeveledNotifier.new(self, level, prefix) @notifiers[level] = notifier notifier end # Returns the leveled notifier for this object attr_reader :level_notifier alias level level_notifier # Sets the leveled notifier for this object. # # When the given +value+ is an instance of AbstractNotifier, # #level_notifier is set to the given object. # # When an Integer is given, #level_notifier is set to the notifier at the # index +value+ in the #notifiers Array. # # If no notifier exists at the index +value+ in the #notifiers Array, an # ErrUndefinedNotifier exception is raised. # # An ErrUnrecognizedLevel exception is raised if the given +value+ is not # found in the existing #notifiers Array, or an instance of # AbstractNotifier def level_notifier=(value) case value when AbstractNotifier @level_notifier = value when Integer l = @notifiers[value] Notifier.Raise ErrUndefinedNotifier, value unless l @level_notifier = l else Notifier.Raise ErrUnrecognizedLevel, value unless l end end alias level= level_notifier= end # A leveled notifier is comparable to the composite group from # CompositeNotifier#notifiers. class LeveledNotifier < AbstractNotifier include Comparable # Create a new leveled notifier with the given +base+, and +prefix+ to # send to AbstractNotifier.new # # The given +level+ is used to compare other leveled notifiers in the # CompositeNotifier group to determine whether or not to output # notifications. def initialize(base, level, prefix) super(prefix, base) @level = level end # The current level of this notifier object attr_reader :level # Compares the level of this notifier object with the given +other+ # notifier. # # See the Comparable module for more information. def <=>(other) @level <=> other.level end # Whether to output messages to the output method, depending on the level # of this notifier object. def notify? @base_notifier.level >= self end end # NoMsgNotifier is a LeveledNotifier that's used as the default notifier # when creating a new CompositeNotifier. # # This notifier is used as the +zero+ index, or level +0+, for # CompositeNotifier#notifiers, and will not output messages of any sort. class NoMsgNotifier < LeveledNotifier # Creates a new notifier that should not be used to output messages. def initialize @base_notifier = nil @level = 0 @prefix = "" end # Ensures notifications are ignored, see AbstractNotifier#notify? for # more information. def notify? false end end D_NOMSG = NoMsgNotifier.new # :nodoc: end end ws-for-case-2.rb000064400000000342147556205260007371 0ustar00# frozen_string_literal: false # # irb/ws-for-case-2.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # while true IRB::BINDING_QUEUE.push _ = binding end lc/help-message000064400000003613147556205260007456 0ustar00# -*- coding: utf-8 -*- # # irb/lc/help-message.rb - # $Release Version: 0.9.6$ # $Revision: 41028 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # Usage: irb.rb [options] [programfile] [arguments] -f Suppress read of ~/.irbrc -m Bc mode (load mathn, fraction or matrix are available) -d Set $DEBUG to true (same as `ruby -d') -r load-module Same as `ruby -r' -I path Specify $LOAD_PATH directory -U Same as `ruby -U` -E enc Same as `ruby -E` -w Same as `ruby -w` -W[level=2] Same as `ruby -W` --context-mode n Set n[0-3] to method to create Binding Object, when new workspace was created --echo Show result(default) --noecho Don't show result --inspect Use `inspect' for output (default except for bc mode) --noinspect Don't use inspect for output --readline Use Readline extension module --noreadline Don't use Readline extension module --prompt prompt-mode/--prompt-mode prompt-mode Switch prompt mode. Pre-defined prompt modes are `default', `simple', `xmp' and `inf-ruby' --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs. Suppresses --readline. --sample-book-mode/--simple-prompt Simple prompt mode --noprompt No prompt mode --single-irb Share self with sub-irb. --tracer Display trace for each execution of commands. --back-trace-limit n Display backtrace top n and tail n. The default value is 16. --irb_debug n Set internal debug level to n (not for popular use) --verbose Show details --noverbose Don't show details -v, --version Print the version of irb -h, --help Print help -- Separate options of irb from the list of command-line args # vim:fileencoding=utf-8 lc/error.rb000064400000001737147556205260006644 0ustar00# frozen_string_literal: false # # irb/lc/error.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "e2mmap" # :stopdoc: module IRB # exceptions extend Exception2MessageMapper def_exception :UnrecognizedSwitch, "Unrecognized switch: %s" def_exception :NotImplementedError, "Need to define `%s'" def_exception :CantReturnToNormalMode, "Can't return to normal mode." def_exception :IllegalParameter, "Invalid parameter(%s)." def_exception :IrbAlreadyDead, "Irb is already dead." def_exception :IrbSwitchedToCurrentThread, "Switched to current thread." def_exception :NoSuchJob, "No such job(%s)." def_exception :CantShiftToMultiIrbMode, "Can't shift to multi irb mode." def_exception :CantChangeBinding, "Can't change binding to (%s)." def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)." def_exception :IllegalRCGenerator, 'Define illegal RC_NAME_GENERATOR.' end # :startdoc: lc/ja/help-message000064400000004730147556205260010051 0ustar00# -*- coding: utf-8 -*- # irb/lc/ja/help-message.rb - # $Release Version: 0.9.6$ # $Revision: 41071 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # Usage: irb.rb [options] [programfile] [arguments] -f ~/.irbrc を読み込まない. -m bcモード(分数, 行列の計算ができる) -d $DEBUG をtrueにする(ruby -d と同じ) -r load-module ruby -r と同じ. -I path $LOAD_PATH に path を追加する. -U ruby -U と同じ. -E enc ruby -E と同じ. -w ruby -w と同じ. -W[level=2] ruby -W と同じ. --context-mode n 新しいワークスペースを作成した時に関連する Binding オブジェクトの作成方法を 0 から 3 のいずれかに設定する. --echo 実行結果を表示する(デフォルト). --noecho 実行結果を表示しない. --inspect 結果出力にinspectを用いる(bcモード以外はデフォルト). --noinspect 結果出力にinspectを用いない. --readline readlineライブラリを利用する. --noreadline readlineライブラリを利用しない. --prompt prompt-mode/--prompt-mode prompt-mode プロンプトモードを切替えます. 現在定義されているプ ロンプトモードは, default, simple, xmp, inf-rubyが 用意されています. --inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特 に指定がない限り, readlineライブラリは使わなくなる. --sample-book-mode/--simple-prompt 非常にシンプルなプロンプトを用いるモードです. --noprompt プロンプト表示を行なわない. --single-irb irb 中で self を実行して得られるオブジェクトをサ ブ irb と共有する. --tracer コマンド実行時にトレースを行なう. --back-trace-limit n バックトレース表示をバックトレースの頭から n, 後ろ からnだけ行なう. デフォルトは16 --irb_debug n irbのデバッグレベルをnに設定する(非推奨). --verbose 詳細なメッセージを出力する. --noverbose 詳細なメッセージを出力しない(デフォルト). -v, --version irbのバージョンを表示する. -h, --help irb のヘルプを表示する. -- 以降のコマンドライン引数をオプションとして扱わない. # vim:fileencoding=utf-8 lc/ja/error.rb000064400000002330147556205260007224 0ustar00# -*- coding: utf-8 -*- # frozen_string_literal: false # irb/lc/ja/error.rb - # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "e2mmap" # :stopdoc: module IRB # exceptions extend Exception2MessageMapper def_exception :UnrecognizedSwitch, 'スイッチ(%s)が分りません' def_exception :NotImplementedError, '`%s\'の定義が必要です' def_exception :CantReturnToNormalMode, 'Normalモードに戻れません.' def_exception :IllegalParameter, 'パラメータ(%s)が間違っています.' def_exception :IrbAlreadyDead, 'Irbは既に死んでいます.' def_exception :IrbSwitchedToCurrentThread, 'カレントスレッドに切り替わりました.' def_exception :NoSuchJob, 'そのようなジョブ(%s)はありません.' def_exception :CantShiftToMultiIrbMode, 'multi-irb modeに移れません.' def_exception :CantChangeBinding, 'バインディング(%s)に変更できません.' def_exception :UndefinedPromptMode, 'プロンプトモード(%s)は定義されていません.' def_exception :IllegalRCNameGenerator, 'RC_NAME_GENERATORが正しく定義されていません.' end # :startdoc: # vim:fileencoding=utf-8 lc/ja/encoding_aliases.rb000064400000000317147556205260011365 0ustar00# frozen_string_literal: false # :stopdoc: module IRB class Locale @@legacy_encoding_alias_map = { 'ujis' => Encoding::EUC_JP, 'euc' => Encoding::EUC_JP }.freeze end end # :startdoc: slex.rb000064400000015524147556205260006067 0ustar00# frozen_string_literal: false # # irb/slex.rb - simple lex analyzer # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # require "e2mmap" require "irb/notifier" # :stopdoc: module IRB class SLex extend Exception2MessageMapper def_exception :ErrNodeNothing, "node nothing" def_exception :ErrNodeAlreadyExists, "node already exists" DOUT = Notifier::def_notifier("SLex::") D_WARN = DOUT::def_notifier(1, "Warn: ") D_DEBUG = DOUT::def_notifier(2, "Debug: ") D_DETAIL = DOUT::def_notifier(4, "Detail: ") DOUT.level = Notifier::D_NOMSG def initialize @head = Node.new("") end def def_rule(token, preproc = nil, postproc = nil, &block) D_DETAIL.pp token postproc = block if block_given? create(token, preproc, postproc) end def def_rules(*tokens, &block) if block_given? p = block end for token in tokens def_rule(token, nil, p) end end def preproc(token, proc) node = search(token) node.preproc=proc end #$BMW%A%'%C%/(B? def postproc(token) node = search(token, proc) node.postproc=proc end def search(token) @head.search(token.split(//)) end def create(token, preproc = nil, postproc = nil) @head.create_subnode(token.split(//), preproc, postproc) end def match(token) case token when Array when String return match(token.split(//)) else return @head.match_io(token) end ret = @head.match(token) D_DETAIL.exec_if{D_DETAIL.printf "match end: %s:%s\n", ret, token.inspect} ret end def inspect format("", @head.inspect) end #---------------------------------------------------------------------- # # class Node - # #---------------------------------------------------------------------- class Node # if postproc is nil, this node is an abstract node. # if postproc is non-nil, this node is a real node. def initialize(preproc = nil, postproc = nil) @Tree = {} @preproc = preproc @postproc = postproc end attr_accessor :preproc attr_accessor :postproc def search(chrs, opt = nil) return self if chrs.empty? ch = chrs.shift if node = @Tree[ch] node.search(chrs, opt) else if opt chrs.unshift ch self.create_subnode(chrs) else SLex.fail ErrNodeNothing end end end def create_subnode(chrs, preproc = nil, postproc = nil) if chrs.empty? if @postproc D_DETAIL.pp node SLex.fail ErrNodeAlreadyExists else D_DEBUG.puts "change abstract node to real node." @preproc = preproc @postproc = postproc end return self end ch = chrs.shift if node = @Tree[ch] if chrs.empty? if node.postproc DebugLogger.pp node DebugLogger.pp self DebugLogger.pp ch DebugLogger.pp chrs SLex.fail ErrNodeAlreadyExists else D_WARN.puts "change abstract node to real node" node.preproc = preproc node.postproc = postproc end else node.create_subnode(chrs, preproc, postproc) end else if chrs.empty? node = Node.new(preproc, postproc) else node = Node.new node.create_subnode(chrs, preproc, postproc) end @Tree[ch] = node end node end # # chrs: String # character array # io must have getc()/ungetc(); and ungetc() must be # able to be called arbitrary number of times. # def match(chrs, op = "") D_DETAIL.print "match>: ", chrs, "op:", op, "\n" if chrs.empty? if @preproc.nil? || @preproc.call(op, chrs) DOUT.printf(D_DETAIL, "op1: %s\n", op) @postproc.call(op, chrs) else nil end else ch = chrs.shift if node = @Tree[ch] if ret = node.match(chrs, op+ch) return ret else chrs.unshift ch if @postproc and @preproc.nil? || @preproc.call(op, chrs) DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect) ret = @postproc.call(op, chrs) return ret else return nil end end else chrs.unshift ch if @postproc and @preproc.nil? || @preproc.call(op, chrs) DOUT.printf(D_DETAIL, "op3: %s\n", op) @postproc.call(op, chrs) return "" else return nil end end end end def match_io(io, op = "") if op == "" ch = io.getc if ch == nil return nil end else ch = io.getc_of_rests end if ch.nil? if @preproc.nil? || @preproc.call(op, io) D_DETAIL.printf("op1: %s\n", op) @postproc.call(op, io) else nil end else if node = @Tree[ch] if ret = node.match_io(io, op+ch) ret else io.ungetc ch if @postproc and @preproc.nil? || @preproc.call(op, io) DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect} @postproc.call(op, io) else nil end end else io.ungetc ch if @postproc and @preproc.nil? || @preproc.call(op, io) D_DETAIL.printf("op3: %s\n", op) @postproc.call(op, io) else nil end end end end end end end # :startdoc: if $0 == __FILE__ case $1 when "1" tr = SLex.new print "0: ", tr.inspect, "\n" tr.def_rule("=") {print "=\n"} print "1: ", tr.inspect, "\n" tr.def_rule("==") {print "==\n"} print "2: ", tr.inspect, "\n" print "case 1:\n" print tr.match("="), "\n" print "case 2:\n" print tr.match("=="), "\n" print "case 3:\n" print tr.match("=>"), "\n" when "2" tr = SLex.new print "0: ", tr.inspect, "\n" tr.def_rule("=") {print "=\n"} print "1: ", tr.inspect, "\n" tr.def_rule("==", proc{false}) {print "==\n"} print "2: ", tr.inspect, "\n" print "case 1:\n" print tr.match("="), "\n" print "case 2:\n" print tr.match("=="), "\n" print "case 3:\n" print tr.match("=>"), "\n" end exit end workspace.rb000064400000006430147556205260007106 0ustar00# frozen_string_literal: false # # irb/workspace-binding.rb - # $Release Version: 0.9.6$ # $Revision: 56037 $ # by Keiju ISHITSUKA(keiju@ruby-lang.org) # # -- # # # module IRB # :nodoc: class WorkSpace # Creates a new workspace. # # set self to main if specified, otherwise # inherit main from TOPLEVEL_BINDING. def initialize(*main) if main[0].kind_of?(Binding) @binding = main.shift elsif IRB.conf[:SINGLE_IRB] @binding = TOPLEVEL_BINDING else case IRB.conf[:CONTEXT_MODE] when 0 # binding in proc on TOPLEVEL_BINDING @binding = eval("proc{binding}.call", TOPLEVEL_BINDING, __FILE__, __LINE__) when 1 # binding in loaded file require "tempfile" f = Tempfile.open("irb-binding") f.print <IRB.conf[:__MAIN__] attr_reader :main # Evaluate the given +statements+ within the context of this workspace. def evaluate(context, statements, file = __FILE__, line = __LINE__) eval(statements, @binding, file, line) end # error message manipulator def filter_backtrace(bt) case IRB.conf[:CONTEXT_MODE] when 0 return nil if bt =~ /\(irb_local_binding\)/ when 1 if(bt =~ %r!/tmp/irb-binding! or bt =~ %r!irb/.*\.rb! or bt =~ /irb\.rb/) return nil end when 2 return nil if bt =~ /irb\/.*\.rb/ return nil if bt =~ /irb\.rb/ when 3 return nil if bt =~ /irb\/.*\.rb/ return nil if bt =~ /irb\.rb/ bt = bt.sub(/:\s*in `irb_binding'/, '') end bt end def IRB.delete_caller end end end help.rb000064400000001301147556205260006030 0ustar00# frozen_string_literal: false # # irb/help.rb - print usage module # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ishitsuka.com) # # -- # # # require 'irb/magic-file' module IRB # Outputs the irb help message, see IRB@Command+line+options. def IRB.print_usage lc = IRB.conf[:LC_MESSAGES] path = lc.find("irb/help-message") space_line = false IRB::MagicFile.open(path){|f| f.each_line do |l| if /^\s*$/ =~ l lc.puts l unless space_line space_line = true next end space_line = false l.sub!(/#.*$/, "") next if /^\s*$/ =~ l lc.puts l end } end end version.rb000064400000000432147556205260006571 0ustar00# frozen_string_literal: false # # irb/version.rb - irb version definition file # $Release Version: 0.9.6$ # $Revision: 53141 $ # by Keiju ISHITSUKA(keiju@ishitsuka.com) # # -- # # # module IRB # :nodoc: @RELEASE_VERSION = "0.9.6" @LAST_UPDATE_DATE = "09/06/30" end frame.rb000064400000003651147556205260006204 0ustar00# frozen_string_literal: false # # frame.rb - # $Release Version: 0.9$ # $Revision: 53141 $ # by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) # # -- # # # require "e2mmap" module IRB class Frame extend Exception2MessageMapper def_exception :FrameOverflow, "frame overflow" def_exception :FrameUnderflow, "frame underflow" # Default number of stack frames INIT_STACK_TIMES = 3 # Default number of frames offset CALL_STACK_OFFSET = 3 # Creates a new stack frame def initialize @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES end # Used by Kernel#set_trace_func to register each event in the call stack def trace_func(event, file, line, id, binding) case event when 'call', 'class' @frames.push binding when 'return', 'end' @frames.pop end end # Returns the +n+ number of frames on the call stack from the last frame # initialized. # # Raises FrameUnderflow if there are no frames in the given stack range. def top(n = 0) bind = @frames[-(n + CALL_STACK_OFFSET)] Fail FrameUnderflow unless bind bind end # Returns the +n+ number of frames on the call stack from the first frame # initialized. # # Raises FrameOverflow if there are no frames in the given stack range. def bottom(n = 0) bind = @frames[n] Fail FrameOverflow unless bind bind end # Convenience method for Frame#bottom def Frame.bottom(n = 0) @backtrace.bottom(n) end # Convenience method for Frame#top def Frame.top(n = 0) @backtrace.top(n) end # Returns the binding context of the caller from the last frame initialized def Frame.sender eval "self", @backtrace.top end @backtrace = Frame.new set_trace_func proc{|event, file, line, id, binding, klass| @backtrace.trace_func(event, file, line, id, binding) } end end irb.rd.ja000064400000033627147565622620006272 0ustar00irb -- interactive ruby $Release Version: 0.9.5 $ $Revision: 40043 $ by Keiju ISHITSUKA(keiju@ruby-lang.org) =begin = irbとは? irbはinteractive rubyの略です. rubyの式を標準入力から簡単に入力/実行する ためのツールです. = 起動 % irb で行ないます. = 使い方 irbの使い方は, Rubyさえ知っていればいたって簡単です. 基本的には irb と いうコマンドを実行するだけです. irbを実行すると, 以下のようなプロンプ トが表れてきます. 後は, rubyの式を入れて下さい. 式が完結した時点で実行 されます. dim% irb irb(main):001:0> 1+2 3 irb(main):002:0> class Foo irb(main):003:1> def foo irb(main):004:2> print 1 irb(main):005:2> end irb(main):006:1> end nil irb(main):007:0> また, irbはReadlineモジュールにも対応しています. Readlineモジュールが インストールされている時には, それを使うのが標準の動作になります. = コマンドオプション irb.rb [options] file_name opts options: -f ~/.irbrc を読み込まない. -m bcモード(分数, 行列の計算ができる) -d $DEBUG をtrueにする(ruby -d と同じ) -Kc ruby -Kcと同じ -r load-module ruby -r と同じ. --verbose これから実行する行を表示する(デフォルト) --noverbose これから実行する行を表示しない --echo 実行結果を表示する(デフォルト) --noecho 実行結果を表示しない --inspect 結果出力にinspectを用いる(bcモード以外はデフォルト). --noinspect 結果出力にinspectを用いない. --readline readlineライブラリを利用する. --noreadline readlineライブラリを利用しない. デフォルトの動作は, inf-ruby-mode以外でreadlineライブラリを利用しよう とする. --prompt prompt-mode --prompt-mode prompt-mode プロンプトモードを切替えます. 現在定義されているプ ロンプトモードは, default, simple, xmp, inf-rubyが 用意されています. デフォルトはdefaultプロンプトモー ドになっています. --inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特 に指定がない限り, readlineライブラリは使わなくなる. --simple-prompt 非常にシンプルなプロンプトを用いるモードです. --noprompt プロンプト表示を行なわない. --tracer コマンド実行時にトレースを行なう. --back-trace-limit n バックトレース表示をバックトレースの頭から n, 後ろ からnだけ行なう. デフォルトは16 --irb_debug n irbのデバッグデバッグレベルをnに設定する(利用しな い方が無難でしょう). -v, --version irbのバージョンを表示する = コンフィギュレーション irb起動時に``~/.irbrc''を読み込みます. もし存在しない場合は, ``.irbrc'', ``irb.rc'', ``_irbrc'', ``$irbrc''の順にloadを試みます. オプションを設定する代わりに, 以下のコマンドでもデフォルトの動作を設定 できます. IRB.conf[:IRB_NAME]="irb" IRB.conf[:MATH_MODE]=false IRB.conf[:USE_TRACER]=false IRB.conf[:USE_LOADER]=false IRB.conf[:IGNORE_SIGINT]=true IRB.conf[:IGNORE_EOF]=false IRB.conf[:INSPECT_MODE]=nil IRB.conf[:IRB_RC] = nil IRB.conf[:BACK_TRACE_LIMIT]=16 IRB.conf[:USE_LOADER] = false IRB.conf[:USE_READLINE] = nil IRB.conf[:USE_TRACER] = false IRB.conf[:IGNORE_SIGINT] = true IRB.conf[:IGNORE_EOF] = false IRB.conf[:PROMPT_MODE] = :DEFAULT IRB.conf[:PROMPT] = {...} IRB.conf[:DEBUG_LEVEL]=0 IRB.conf[:VERBOSE]=true == プロンプトの設定 プロンプトをカスタマイズしたい時には, IRB.conf[:PROMPT] を用います. 例えば, .irbrcの中で下のような式を記述します: IRB.conf[:PROMPT][:MY_PROMPT] = { # プロンプトモードの名前 :PROMPT_I => nil, # 通常のプロンプト :PROMPT_N => nil, # 継続行のプロンプト :PROMPT_S => nil, # 文字列などの継続行のプロンプト :PROMPT_C => nil, # 式が継続している時のプロンプト :RETURN => " ==>%s\n" # リターン時のプロンプト } プロンプトモードを指定したい時には, irb --prompt my-prompt でそのプロンプトモードで起動されます. または, .irbrcに下式を記述しても OKです. IRB.conf[:PROMPT_MODE] = :MY_PROMPT PROMPT_I, PROMPT_N, PROMPT_S, PROMPT_Cは, フォーマットを指定します. %N 起動しているコマンド名が出力される. %m mainオブジェクト(self)がto_sで出力される. %M mainオブジェクト(self)がinspectされて出力される. %l 文字列中のタイプを表す(", ', /, ], `]'は%wの中の時) %NNi インデントのレベルを表す. NNは数字が入りprintfの%NNdと同じ. 省 略可能 %NNn 行番号を表します. %% % 例えば, デフォルトのプロンプトモードは: IRB.conf[:PROMPT_MODE][:DEFAULT] = { :PROMPT_I => "%N(%m):%03n:%i> ", :PROMPT_N => "%N(%m):%03n:%i> ", :PROMPT_S => "%N(%m):%03n:%i%l ", :PROMPT_C => "%N(%m):%03n:%i* ", :RETURN => "%s\n" } となっています. RETURNは, 現在のところprintf形式です. 将来仕様が変わるかも知れません. == サブirbの設定 コマンドラインオプションおよびIRB.confは(サブ)irb起動時のデフォルトの 設定を決めるもので, `5. コマンド'にあるconfで個別の(サブ)irbの設定がで きるようになっています. IRB.conf[:IRB_RC]にprocが設定されていると, サブirbを起動する時にその procをirbのコンテキストを引数として呼び出します. これによって個別のサ ブirbごとに設定を変えることができるようになります. = コマンド irb拡張コマンドは, 簡単な名前と頭に`irb_'をつけた名前と両方定義されて います. これは, 簡単な名前がoverrideされた時のためです. --- exit, quit, irb_exit 終了する. サブirbの場合, そのサブirbを終了する. --- conf, irb_context irbの現在の設定を表示する. 設定の変更は, confにメッセージを送るこ とによって行なえる. --- conf.eval_history = N 実行結果のヒストリ機能の設定. nnは整数かnilで nn>0 であればその数だけヒストリにためる。nn==0の時は 無制限に記憶する、nilだとヒストリ機能はやめる(デフォルト). --- Conf.back_trace_limit バックトレース表示をバックトレースの頭からn, 後ろからnだけ行なう. デフォルトは16 --- conf.debug_level = N irb用のデバッグレベルの設定 --- conf.ignore_eof = true/false ^Dが入力された時の動作を設定する. trueの時は^Dを無視する, falseの 時はirbを終了する. --- conf.ignore_sigint= true/false ^Cが入力された時の動作を設定する. false時は, irbを終了する. trueの 時の動作は以下のようになる: 入力中: これまで入力したものをキャンセルしトップレベルに戻る. 実行中: 実行を中止する. --- conf.inf_ruby_mode = true/false inf-ruby-mode用のプロンプト表示を行なう. デフォルトはfalse. --- conf.inspect_mode = true/false/nil インスペクトモードを設定する. true: インスペクトして表示する. false: 通常のprintで表示する. nil: 通常モードであれば, inspect modeとなり, mathモードの時は, non inspect modeとなる. --- conf.math_mode 参照のみ. bcモード(分数, 行列の計算ができます)かどうか? --- conf.use_loader = true/false load/require時にirbのfile読み込み機能を用いるモードのスイッチ(デフォ ルトは用いない). このモードはIRB全体に反映される. --- conf.prompt_c ifの直後など, 行が継続している時のプロンプト. --- conf.prompt_i 通常のプロンプト. --- conf.prompt_s 文字列中などを表すプロンプト. --- conf.rc ~/.irbrcを読み込んだかどうか? --- conf.use_prompt = true/false プロンプト表示するかどうか? デフォルトではプロンプトを表示する. --- conf.use_readline = true/false/nil readlineを使うかどうか? true: readlineを使う. false: readlineを使わない. nil: (デフォルト)inf-ruby-mode以外でreadlineライブラリを利用しよ うとする. # #--- conf.verbose=T/F # irbからいろいろなメッセージを出力するか? --- cws, chws, irb_cws, irb_chws, irb_change_workspace [obj] objをselfとする. objが省略されたときは, home workspace, すなわち irbを起動したときのmain objectをselfとする. --- pushws, irb_pushws, irb_push_workspace [obj] UNIXシェルコマンドのpushdと同様. --- popws, irb_popws, irb_pop_workspace UNIXシェルコマンドのpopdと同様. --- irb [obj] サブirbを立ちあげる. objが指定された時は, そのobjをselfとする. --- jobs, irb_jobs サブirbのリスト --- fg n, irb_fg n 指定したサブirbにスイッチする. nは, 次のものを指定する. irb番号 スレッド irbオブジェクト self(irb objで起動した時のobj) --- kill n, irb_kill n サブirbをkillする. nはfgと同じ. --- source, irb_source path UNIXシェルコマンドのsourceと似ている. 現在の環境上でpath内のスクリ プトを評価する. --- irb_load path, prev Rubyのloadのirb版. = システム変数 --- _ 前の計算の実行結果を覚えている(ローカル変数). --- __ 実行結果の履歴を覚えている. __[line_no]で、その行で実行した結果を得ることができる. line_noが負の 時には、最新の結果から-line_no前の結果を得ることができる. = 使用例 以下のような感じです. dim% ruby irb.rb irb(main):001:0> irb # サブirbの立ちあげ irb#1(main):001:0> jobs # サブirbのリスト #0->irb on main (# : stop) #1->irb#1 on main (# : running) nil irb#1(main):002:0> fg 0 # jobのスイッチ nil irb(main):002:0> class Foo;end nil irb(main):003:0> irb Foo # Fooをコンテキストしてirb # 立ちあげ irb#2(Foo):001:0> def foo # Foo#fooの定義 irb#2(Foo):002:1> print 1 irb#2(Foo):003:1> end nil irb#2(Foo):004:0> fg 0 # jobをスイッチ nil irb(main):004:0> jobs # jobのリスト #0->irb on main (# : running) #1->irb#1 on main (# : stop) #2->irb#2 on Foo (# : stop) nil irb(main):005:0> Foo.instance_methods # Foo#fooがちゃんと定義さ # れている ["foo"] irb(main):006:0> fg 2 # jobをスイッチ nil irb#2(Foo):005:0> def bar # Foo#barを定義 irb#2(Foo):006:1> print "bar" irb#2(Foo):007:1> end nil irb#2(Foo):010:0> Foo.instance_methods ["bar", "foo"] irb#2(Foo):011:0> fg 0 nil irb(main):007:0> f = Foo.new # irb(main):008:0> irb f # Fooのインスタンスでirbを # 立ちあげる. irb#3(#):001:0> jobs #0->irb on main (# : stop) #1->irb#1 on main (# : stop) #2->irb#2 on Foo (# : stop) #3->irb#3 on # (# : running) nil irb#3(#):002:0> foo # f.fooの実行 nil irb#3(#):003:0> bar # f.barの実行 barnil irb#3(#):004:0> kill 1, 2, 3# jobのkill nil irb(main):009:0> jobs #0->irb on main (# : running) nil irb(main):010:0> exit # 終了 dim% = 使用上の制限 irbは, 評価できる時点(式が閉じた時点)での逐次実行を行ないます. したがっ て, rubyを直接使った時と, 若干異なる動作を行なう場合があります. 現在明らかになっている問題点を説明します. == ローカル変数の宣言 rubyでは, 以下のプログラムはエラーになります. eval "foo = 0" foo -- -:2: undefined local variable or method `foo' for # (NameError) --- NameError ところが, irbを用いると >> eval "foo = 0" => 0 >> foo => 0 となり, エラーを起こしません. これは, rubyが最初にスクリプト全体をコン パイルしてローカル変数を決定するからです. それに対し, irbは実行可能に なる(式が閉じる)と自動的に評価しているからです. 上記の例では, evel "foo = 0" を行なった時点で評価を行ない, その時点で変数が定義されるため, 次式で 変数fooは定義されているからです. このようなrubyとirbの動作の違いを解決したい場合は, begin...endで括って バッチ的に実行して下さい: >> begin ?> eval "foo = 0" >> foo >> end NameError: undefined local variable or method `foo' for # (irb):3 (irb_local_binding):1:in `eval' == ヒアドキュメント 現在のところヒアドキュメントの実装は不完全です. == シンボル シンボルであるかどうかの判断を間違えることがあります. 具体的には式が完了 しているのに継続行と見なすことがあります. =end % Begin Emacs Environment % Local Variables: % mode: text % comment-column: 0 % comment-start: "%" % comment-end: "\n" % End: % irb-tools.rd.ja000064400000011420147565622620007413 0ustar00irb関連おまけコマンドとライブラリ $Release Version: 0.7.1 $ $Revision: 47689 $ by Keiju ISHITSUKA(Nihon Rational Co.,Ltd.) =begin :コマンド: * rtags -- ruby tags command :関数ライブラリ: * xmp -- irb version of gotoken xmp-function :クラスライブラリ: * frame.rb -- frame tracer * completion.rb -- irb completor = rtags rtagsはemacs及びvi用の, TAGファイルをつくるコマンドです. == 使い方 rtags [-vi] file.... カレントディレクトリにemacs用のTAGSファイルができます. -viオプションを つけた時にはvi用のtagsファイルを作成します. emacsの場合, 通常のetags.elがそのまま使えます. 検索可能なのは, * クラス * メソッド * 特異メソッド * alias * attrで宣言されたアクセサ(パラメータがシンボルか文字列リテラルに限る) * attr_XXXで宣言されたアクセサ(パラメータがシンボルか文字列リテラルに限る) です. Cなどで使っているのと違うのは, コンプリーションに関する部分で, 関数名は, 関数名( クラスは, ::クラス名::....::クラス名 メソッドは, ::クラス名::....::クラス名#メソッド名 特異メソッド(クラスメソッド)は ::クラス名::....::クラス名.メソッド名 でコンプリーションを行なうところです. = xmp.rb ごとけんxmpの上位互換バージョンです. ただ, 非常に重いのでごとけんxmpで は対応できない時に, 使用すると良いでしょう. == 使い方 === 関数として使う. require "irb/xmp" xmp <1 foo ==>1 === XMPインスタンスを用いる. この場合は, XMPがコンテキスト情報を持つので, 変数の値などを保持してい ます. require "irb/xmp" xmp = XMP.new xmp.puts <1 foo ==>1 foo ==>1 == コンテキストに関して XMPメソッド群のコンテキストは, 呼び出す前のコンテキストで評価されます. 明示的にコンテキストを指定するとそのコンテキストで評価します. 例: xmp "foo", an_binding :注: マルチスレッドには対応していません. = frame.rb 現在実行中のフレーム情報を取り扱うためのクラスです. * IRB::Frame.top(n = 0) 上からn番目のコンテキストを取り出します. nは0が最上位になります. * IRB::Frame.bottom(n = 0) 下からn番目のコンテキストを取り出します. nは0が最下位になります. * IRB::Frame.sender センダになっているオブジェクトを取り出します. センダとは, そのメソッ ドを呼び出した側のselfのことです. :注: set_trace_funcを用いてRubyの実行をトレースしています. マルチスレッドに は対応していません. = completion.rb irbのcompletion機能を提供するものです. == 使い方 % irb -r irb/completion とするか, ~/.irbrc 中に require "irb/completion" を入れてください. irb実行中に require "irb/completion" してもよいです. irb実行中に (TAB) を押すとコンプレーションします. トップレベルで(TAB)を押すとすべての構文要素, クラス, メソッドの候補がで ます. 候補が唯一ならば完全に補完します. irb(main):001:0> in in inspect instance_eval include install_alias_method instance_of? initialize install_aliases instance_variables irb(main):001:0> inspect "main" irb(main):002:0> foo = Object.new # ((|変数名.|))の後に(TAB)を押すと, そのオブジェクトのメソッド一覧がでま す. irb(main):003:0> foo. foo.== foo.frozen? foo.protected_methods foo.=== foo.hash foo.public_methods foo.=~ foo.id foo.respond_to? foo.__id__ foo.inspect foo.send foo.__send__ foo.instance_eval foo.singleton_methods foo.class foo.instance_of? foo.taint foo.clone foo.instance_variables foo.tainted? foo.display foo.is_a? foo.to_a foo.dup foo.kind_of? foo.to_s foo.eql? foo.method foo.type foo.equal? foo.methods foo.untaint foo.extend foo.nil? foo.freeze foo.private_methods =end % Begin Emacs Environment % Local Variables: % mode: text % comment-column: 0 % comment-start: "%" % comment-end: "\n" % End: %