in case the tests call ::reset_defaults, ensure we reset them to amended (test friendly) values
taken from irb
Pry is a powerful alternative to the standard IRB shell for Ruby. It features syntax highlighting, a flexible plugin architecture, runtime invocation and source and documentation browsing.
Pry can be started similar to other command line utilities by simply running the following command:
pry
Once inside Pry you can invoke the help message:
help
This will show a list of available commands and their usage. For more information about Pry you can refer to the following resources:
the IRC channel, which is pry on the Freenode network
Convert the given object into an instance of `Pry::Code`, if it isn't already one.
@param [Code, Method, UnboundMethod, Proc, Pry::Method, String, Array,
IO] obj
# File lib/pry/code.rb, line 11 def Code(obj) case obj when Code obj when ::Method, UnboundMethod, Proc, Pry::Method Code.from_method(obj) else Code.new(obj) end end
If the given object is a `Pry::Method`, return it unaltered. If it's anything else, return it wrapped in a `Pry::Method` instance.
# File lib/pry/method.rb, line 7 def Method(obj) if obj.is_a? Pry::Method obj else Pry::Method.new(obj) end end
If the given object is a `Pry::WrappedModule`, return it unaltered. If it's anything else, return it wrapped in a `Pry::WrappedModule` instance.
# File lib/pry/wrapped_module.rb, line 7 def WrappedModule(obj) if obj.is_a? Pry::WrappedModule obj else Pry::WrappedModule.new(obj) end end
# File lib/pry/pry_class.rb, line 264 def self.auto_resize! ver = Readline::VERSION if ver[/edit/] warn <<-EOT Readline version #{ver} detected - will not auto_resize! correctly. For the fix, use GNU Readline instead: https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X EOT return end trap :WINCH do begin Readline.set_screen_size *Terminal.size! rescue => e warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}" end begin Readline.refresh_line rescue => e warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}" end end end
Return a `Binding` object for `target` or return `target` if it is already a `Binding`. In the case where `target` is top-level then return `TOPLEVEL_BINDING` @param [Object] target The object to get a `Binding` object for. @return [Binding] The `Binding` object.
# File lib/pry/pry_class.rb, line 428 def self.binding_for(target) if Binding === target target else if TOPLEVEL_BINDING.eval('self') == target TOPLEVEL_BINDING else target.__binding__ end end end
# File lib/pry/pry_class.rb, line 461 def self.critical_section(&block) @critical_section = @critical_section.to_i + 1 yield ensure @critical_section -= 1 end
@return [Hash] Pry's `Thread.current` hash
# File lib/pry/pry_class.rb, line 12 def self.current Thread.current[:__pry__] ||= {} end
# File lib/pry/pry_class.rb, line 251 def self.default_editor_for_platform return ENV['VISUAL'] if ENV['VISUAL'] and not ENV['VISUAL'].empty? return ENV['EDITOR'] if ENV['EDITOR'] and not ENV['EDITOR'].empty? if Helpers::BaseHelpers.windows? 'notepad' else %w(editor nano vi).detect do |editor| system("which #{editor} > /dev/null 2>&1") end end end
convenience method
# File lib/pry/pry_class.rb, line 21 def self.delegate_accessors(delagatee, *names) def_delegators delagatee, *names def_delegators delagatee, *names.map { |v| "#{v}=" } end
To avoid mass-confusion, we change the default colour of "white" to "blue" enabling global legibility
# File lib/pry/pry_class.rb, line 397 def self.fix_coderay_colors to_fix = if (CodeRay::Encoders::Terminal::TOKEN_COLORS rescue nil) # CodeRay 1.0.0 CodeRay::Encoders::Terminal::TOKEN_COLORS else # CodeRay 0.9 begin require 'coderay/encoders/term' CodeRay::Encoders::Term::TOKEN_COLORS rescue end end to_fix[:comment] = "0;34" if to_fix end
# File lib/pry/pry_class.rb, line 457 def self.in_critical_section? @critical_section.to_i > 0 end
Basic initialization.
# File lib/pry/pry_class.rb, line 414 def self.init @plugin_manager ||= PluginManager.new self.config ||= Config.new self.history ||= History.new reset_defaults locate_plugins end
@return [Boolean] Whether this is the first time a Pry session has
been started since loading the Pry class.
# File lib/pry/pry_class.rb, line 216 def self.initial_session? @initial_session end
Do basic setup for initial session. Including: loading .pryrc, loading plugins, loading requires, and loading history.
# File lib/pry/pry_class.rb, line 109 def self.initial_session_setup return if !initial_session? # note these have to be loaded here rather than in pry_instance as # we only want them loaded once per entire Pry lifetime. load_rc if Pry.config.should_load_rc load_local_rc if Pry.config.should_load_local_rc load_plugins if Pry.config.should_load_plugins load_requires if Pry.config.should_load_requires load_history if Pry.config.history.should_load load_traps if Pry.config.should_trap_interrupts @initial_session = false end
Load the given file in the context of `::toplevel_binding` @param [String] file_name The unexpanded file path.
# File lib/pry/pry_class.rb, line 71 def self.load_file_at_toplevel(file_name) full_name = File.expand_path(file_name) begin toplevel_binding.eval(File.read(full_name), full_name) if File.exists?(full_name) rescue RescuableException => e puts "Error loading #{file_name}: #{e}\n#{e.backtrace.first}" end end
Execute the file through the REPL loop, non-interactively. @param [String] file_name File name to load through the REPL.
# File lib/pry/pry_class.rb, line 178 def self.load_file_through_repl(file_name) require "pry/repl_file_loader" REPLFileLoader.new(file_name).load end
Load Readline history if required.
# File lib/pry/pry_class.rb, line 205 def self.load_history Pry.history.load end
Load the local RC file (./.pryrc)
# File lib/pry/pry_class.rb, line 87 def self.load_local_rc unless File.expand_path(HOME_RC_FILE) == File.expand_path(LOCAL_RC_FILE) load_file_at_toplevel(LOCAL_RC_FILE) end end
Load the rc files given in the `Pry::RC_FILES` array. This method can also be used to reload the files if they have changed.
# File lib/pry/pry_class.rb, line 82 def self.load_rc load_file_at_toplevel(HOME_RC_FILE) end
Load any Ruby files specified with the -r flag on the command line.
# File lib/pry/pry_class.rb, line 94 def self.load_requires Pry.config.requires.each do |file| require file end end
Trap interrupts on jruby, and make them behave like MRI so we can catch them.
# File lib/pry/pry_class.rb, line 102 def self.load_traps trap('INT'){ raise Interrupt } end
Create a new `Pry` object. @param [Hash] options The optional configuration parameters. @option options [readline] :input The object to use for input. @option options [puts] :output The object to use for output. @option options [Pry::CommandBase] :commands The object to use for commands. @option options [Hash] :hooks The defined hook Procs @option options [Array<Proc>] :prompt The array of Procs to use for the prompts. @option options [Proc] :print The Proc to use for the 'print' @option options [Boolean] :quiet If true, omit the whereami banner when starting.
component of the REPL. (see print.rb)
# File lib/pry/pry_instance.rb, line 83 def initialize(options={}) refresh(options) @binding_stack = [] @indent = Pry::Indent.new @command_state = {} end
# File lib/pry.rb, line 21 def self.output_with_default_format(output, value, options = {}) stringified = begin value.pretty_inspect rescue RescuableException nil end unless String === stringified # Read the class name off of the singleton class to provide a default # inspect. klass = (class << value; self; end).ancestors.first stringified = "#<#{klass}:0x#{value.__id__.to_s(16)}>" end nonce = rand(0x100000000).to_s(16) # whatever stringified.gsub!(/#</, "%<#{nonce}") # Don't recolorize output with color (for cucumber, looksee, etc.) [Issue #751] colorized = if stringified =~ /\e\[/ stringified else Helpers::BaseHelpers.colorize_code(stringified) end # avoid colour-leak from CodeRay and any of the users' previous output colorized = colorized.sub(/(\n*)\z/, "\e[0m\\1") if Pry.color result = colorized.gsub(/%<(.*?)#{nonce}/, '#<\1') result = "=> #{result}"if options[:hashrocket] Helpers::BaseHelpers.stagger_output(result, output) end
# File lib/pry/test/helper.rb, line 7 def reset_defaults orig_reset_defaults Pry.color = false Pry.pager = false Pry.config.should_load_rc = false Pry.config.should_load_local_rc= false Pry.config.should_load_plugins = false Pry.config.history.should_load = false Pry.config.history.should_save = false Pry.config.auto_indent = false Pry.config.hooks = Pry::Hooks.new Pry.config.collision_warning = false end
Run a Pry command from outside a session. The commands available are those referenced by `#commands` (the default command set). @param [String] command_string The Pry command (including arguments,
if any).
@param [Hash] options Optional named parameters. @return [Object] The return value of the Pry command. @option options [Object, Binding] :context The object context to run the
command under. Defaults to `TOPLEVEL_BINDING` (main).
@option options [Boolean] :show_output Whether to show command
output. Defaults to true.
@example Run at top-level with no output.
Pry.run_command "ls"
@example Run under Pry class, returning only public methods.
Pry.run_command "ls -m", :context => Pry
@example Display command output.
Pry.run_command "ls -av", :show_output => true
# File lib/pry/pry_class.rb, line 236 def self.run_command(command_string, options={}) options = { :context => TOPLEVEL_BINDING, :show_output => true, :output => Pry.output, :commands => Pry.commands }.merge!(options) output = options[:show_output] ? options[:output] : StringIO.new Pry.new(:output => output, :input => StringIO.new("#{command_string}\nexit-all\n"), :commands => options[:commands], :prompt => proc {""}, :hooks => Pry::Hooks.new).repl(options[:context]) end
Save new lines of Readline history if required.
# File lib/pry/pry_class.rb, line 210 def self.save_history Pry.history.save end
# File lib/pry/pry_class.rb, line 288 def self.set_config_defaults config.input = Readline config.output = $stdout config.commands = Pry::Commands config.prompt_name = DEFAULT_PROMPT_NAME config.prompt = DEFAULT_PROMPT config.print = DEFAULT_PRINT config.exception_handler = DEFAULT_EXCEPTION_HANDLER config.exception_whitelist = DEFAULT_EXCEPTION_WHITELIST config.default_window_size = 5 config.hooks = DEFAULT_HOOKS config.input_stack = [] config.color = Helpers::BaseHelpers.use_ansi_codes? config.pager = true config.system = DEFAULT_SYSTEM config.editor = default_editor_for_platform config.should_load_rc = true config.should_load_local_rc = true config.should_trap_interrupts = Helpers::BaseHelpers.jruby? config.disable_auto_reload = false config.command_prefix = "" config.auto_indent = Helpers::BaseHelpers.use_ansi_codes? config.correct_indent = true config.collision_warning = false config.output_prefix = "=> " if defined?(Bond) && Readline::VERSION !~ /editline/ config.completer = Pry::BondCompleter else config.completer = Pry::InputCompleter end config.gist ||= OpenStruct.new config.gist.inspecter = proc(&:pretty_inspect) config.should_load_plugins = true config.requires ||= [] config.should_load_requires = true config.history ||= OpenStruct.new config.history.should_save = true config.history.should_load = true config.history.file = File.expand_path("~/.pry_history") rescue nil if config.history.file.nil? config.should_load_rc = false config.history.should_save = false config.history.should_load = false end config.control_d_handler = DEFAULT_CONTROL_D_HANDLER config.memory_size = 100 config.extra_sticky_locals = {} config.ls ||= OpenStruct.new({ :heading_color => :bright_blue, :public_method_color => :default, :private_method_color => :blue, :protected_method_color => :blue, :method_missing_color => :bright_red, :local_var_color => :yellow, :pry_var_color => :default, # e.g. _, _pry_, _file_ :instance_var_color => :blue, # e.g. @foo :class_var_color => :bright_blue, # e.g. @@foo :global_var_color => :default, # e.g. $CODERAY_DEBUG, $eventmachine_library :builtin_global_color => :cyan, # e.g. $stdin, $-w, $PID :pseudo_global_color => :cyan, # e.g. $~, $1..$9, $LAST_MATCH_INFO :constant_color => :default, # e.g. VERSION, ARGF :class_constant_color => :blue, # e.g. Object, Kernel :exception_constant_color => :magenta, # e.g. Exception, RuntimeError :unloaded_constant_color => :yellow, # Any constant that is still in .autoload? state # What should separate items listed by ls? (TODO: we should allow a columnar layout) :separator => " ", # Any methods defined on these classes, or modules included into these classes, will not # be shown by ls unless the -v flag is used. # A user of Rails may wih to add ActiveRecord::Base to the list. # add the following to your .pryrc: # Pry.config.ls.ceiling << ActiveRecord::Base if defined? ActiveRecordBase :ceiling => [Object, Module, Class] }) end
Start a Pry REPL. This method also loads the ~/.pryrc and ./.pryrc as necessary first time it is invoked. @param [Object, Binding] target The receiver of the Pry session @param [Hash] options @option options (see Pry#initialize) @example
Pry.start(Object.new, :input => MyInput.new)
# File lib/pry/pry_class.rb, line 133 def self.start(target=nil, options={}) return if ENV['DISABLE_PRY'] if in_critical_section? output.puts "ERROR: Pry started inside Pry." output.puts "This can happen if you have a binding.pry inside a #to_s or #inspect function." return end target = Pry.binding_for(target || toplevel_binding) initial_session_setup # create the Pry instance to manage the session pry_instance = new(options) # save backtrace pry_instance.backtrace = caller # if Pry was started via binding.pry, elide that from the backtrace. pry_instance.backtrace.shift if pry_instance.backtrace.first =~ /pry.*core_extensions.*pry/ # yield the binding_stack to the hook for modification pry_instance.exec_hook(:when_started, target, options, pry_instance) if !pry_instance.binding_stack.empty? head = pry_instance.binding_stack.pop else head = target end # Clear the line before starting Pry. This fixes the issue discussed here: # https://github.com/pry/pry/issues/566 if Pry.config.auto_indent Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G" end # Enter the matrix pry_instance.repl(head) rescue Pry::TooSafeException puts "ERROR: Pry cannot work with $SAFE > 0" raise end
An inspector that clips the output to `max_length` chars. In case of > `max_length` chars the `#<Object...> notation is used. @param obj The object to view. @param max_length The maximum number of chars before clipping occurs. @return [String] The string representation of `obj`.
# File lib/pry/pry_class.rb, line 188 def self.view_clip(obj, max_length = 60) if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max_length obj.name.to_s elsif TOPLEVEL_BINDING.eval('self') == obj # special case for 'main' object :) obj.to_s elsif [String, Numeric, Symbol, nil, true, false].any? { |v| v === obj } && obj.inspect.length <= max_length obj.inspect else "#<#{obj.class}>"#:%x>"# % (obj.object_id << 1) end rescue RescuableException "unknown" end
Add a sticky local to this Pry instance. A sticky local is a local that persists between all bindings in a session. @param [Symbol] name The name of the sticky local. @yield The block that defines the content of the local. The local
will be refreshed at each tick of the repl loop.
# File lib/pry/pry_instance.rb, line 178 def add_sticky_local(name, &block) sticky_locals[name] = block end
The currently active `Binding`. @return [Binding] The currently active `Binding` for the session.
# File lib/pry/pry_instance.rb, line 118 def current_context binding_stack.last end
# File lib/pry/pry_instance.rb, line 323 def evaluate_ruby(code, target = binding_stack.last) target = Pry.binding_for(target) inject_sticky_locals(target) exec_hook :before_eval, code, self result = target.eval(code, Pry.eval_path, Pry.current_line) set_last_result(result, target, code) ensure update_input_history(code) exec_hook :after_eval, result, self end
Execute the specified hook. @param [Symbol] name The hook name to execute @param [*Object] args The arguments to pass to the hook @return [Object, Exception] The return value of the hook or the exception raised
If executing a hook raises an exception, we log that and then continue sucessfully. To debug such errors, use the global variable $pry_hook_error, which is set as a result.
# File lib/pry/pry_instance.rb, line 494 def exec_hook(name, *args, &block) e_before = hooks.errors.size hooks.exec_hook(name, *args, &block).tap do hooks.errors[e_before..-1].each do |e| output.puts "#{name} hook failed: #{e.class}: #{e.message}" output.puts "#{e.backtrace.first}" output.puts "(see _pry_.hooks.errors to debug)" end end end
FIXME: This is a hack to alert people of the new API. @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
# File lib/pry/pry_instance.rb, line 64 def hooks=(v) if v.is_a?(Hash) warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks" @hooks = Pry::Hooks.from_hash(v) else @hooks = v end end
Injects a local variable into the provided binding. @param [String] name The name of the local to inject. @param [Object] value The value to set the local to. @param [Binding] b The binding to set the local on. @return [Object] The value the local was set to.
# File lib/pry/pry_instance.rb, line 147 def inject_local(name, value, b) Pry.current[:pry_local] = value.is_a?(Proc) ? value.call : value b.eval("#{name} = ::Pry.current[:pry_local]") ensure Pry.current[:pry_local] = nil end
Inject all the sticky locals into the `target` binding. @param [Binding] target
# File lib/pry/pry_instance.rb, line 167 def inject_sticky_locals(target) sticky_locals.each_pair do |name, value| inject_local(name, value, target) end end
Set the last exception for a session. @param [Exception] ex
# File lib/pry/pry_instance.rb, line 519 def last_exception=(ex) class << ex attr_accessor :file, :line, :bt_index def bt_source_location_for(index) backtrace[index] =~ /(.*):(\d+)/ [$1, $2.to_i] end def inc_bt_index @bt_index = (@bt_index + 1) % backtrace.size end end ex.bt_index = 0 ex.file, ex.line = ex.bt_source_location_for(0) @last_result_is_exception = true @output_array << ex @last_exception = ex end
@return [Boolean] True if the last result is an exception that was raised,
as opposed to simply an instance of Exception (like the result of Exception.new)
# File lib/pry/pry_instance.rb, line 555 def last_result_is_exception? @last_result_is_exception end
@return [Integer] The maximum amount of objects remembered by the inp and
out arrays. Defaults to 100.
# File lib/pry/pry_instance.rb, line 156 def memory_size @output_array.max_size end
# File lib/pry/pry_instance.rb, line 160 def memory_size=(size) @input_array = Pry::HistoryArray.new(size) @output_array = Pry::HistoryArray.new(size) end
Pops the current prompt off of the prompt stack. If the prompt you are popping is the last prompt, it will not be popped. Use this to restore the previous prompt. @return [Array<Proc>] Prompt being popped. @example
prompt1 = [ proc { '>' }, proc { '>>' } ] prompt2 = [ proc { '$' }, proc { '>' } ] pry = Pry.new :prompt => prompt1 pry.push_prompt(prompt2) pry.pop_prompt # => prompt2 pry.pop_prompt # => prompt1 pry.pop_prompt # => prompt1
# File lib/pry/pry_instance.rb, line 718 def pop_prompt prompt_stack.size > 1 ? prompt_stack.pop : prompt end
If the given line is a valid command, process it in the context of the current `eval_string` and context. This method should not need to be invoked directly. @param [String] val The line to process. @param [String] eval_string The cumulative lines of input. @param [Binding] target The target of the Pry session. @return [Boolean] `true` if `val` is a command, `false` otherwise
# File lib/pry/pry_instance.rb, line 441 def process_command(val, eval_string = '', target = binding_stack.last) val = val.chomp result = commands.process_line(val, { :target => target, :output => output, :eval_string => eval_string, :pry_instance => self }) # set a temporary (just so we can inject the value we want into eval_string) Pry.current[:pry_cmd_result] = result # note that `result` wraps the result of command processing; if a # command was matched and invoked then `result.command?` returns true, # otherwise it returns false. if result.command? if !result.void_command? # the command that was invoked was non-void (had a return value) and so we make # the value of the current expression equal to the return value # of the command. eval_string.replace "::Pry.current[:pry_cmd_result].retval\n" end true else false end end
The current prompt. This is the prompt at the top of the prompt stack.
@example
self.prompt = Pry::SIMPLE_PROMPT self.prompt # => Pry::SIMPLE_PROMPT
@return [Array<Proc>] Current prompt.
# File lib/pry/pry_instance.rb, line 130 def prompt prompt_stack.last end
# File lib/pry/pry_instance.rb, line 134 def prompt=(new_prompt) if prompt_stack.empty? push_prompt new_prompt else prompt_stack[-1] = new_prompt end end
Pushes the current prompt onto a stack that it can be restored from later. Use this if you wish to temporarily change the prompt. @param [Array<Proc>] new_prompt @return [Array<Proc>] new_prompt @example
new_prompt = [ proc { '>' }, proc { '>>' } ] push_prompt(new_prompt) # => new_prompt
# File lib/pry/pry_instance.rb, line 702 def push_prompt(new_prompt) prompt_stack.push new_prompt end
Perform a read. If no parameter is given, default to top-level (main). This is a multi-line read; so the read continues until a valid Ruby expression is received. Pry commands are also accepted here and operate on the target. @param [Object, Binding] target The receiver of the read. @param [String] eval_string Optionally Prime `eval_string` with a start value. @return [String] The Ruby expression. @example
Pry.new.r(Object.new)
# File lib/pry/pry_instance.rb, line 294 def r(target=TOPLEVEL_BINDING, eval_string="") target = Pry.binding_for(target) @suppress_output = false loop do begin # eval_string will probably be mutated by this method retrieve_line(eval_string, target) rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e Pry.last_internal_error = e output.puts "Error: #{e.message}" end begin break if Pry::Code.complete_expression?(eval_string) rescue SyntaxError => e exception_handler.call(output, e.extend(UserError), self) eval_string = "" end end if eval_string =~ /;\Z/ || eval_string.empty? || eval_string =~ /\A *#.*\n\z/ @suppress_output = true end exec_hook :after_read, eval_string, self eval_string end
# File lib/pry/pry_instance.rb, line 761 def raise_up(*args); raise_up_common(false, *args); end
# File lib/pry/pry_instance.rb, line 762 def raise_up!(*args); raise_up_common(true, *args); end
Raise an exception out of Pry.
See Kernel#raise for documentation of parameters. See rb_make_exception for the inbuilt implementation.
This is necessary so that the raise-up command can tell the difference between an exception the user has decided to raise, and a mistake in specifying that exception.
(i.e. raise-up RunThymeError.new should not be the same as
raise-up NameError, "unititialized constant RunThymeError")
# File lib/pry/pry_instance.rb, line 734 def raise_up_common(force, *args) exception = if args == [] last_exception || RuntimeError.new elsif args.length == 1 && args.first.is_a?(String) RuntimeError.new(args.first) elsif args.length > 3 raise ArgumentError, "wrong number of arguments" elsif !args.first.respond_to?(:exception) raise TypeError, "exception class/object expected" elsif args.length === 1 args.first.exception else args.first.exception(args[1]) end raise TypeError, "exception object expected" unless exception.is_a? Exception exception.set_backtrace(args.length === 3 ? args[2] : caller(1)) if force || binding_stack.one? binding_stack.clear throw :raise_up, exception else binding_stack.pop raise exception end end
Perform a read-eval If no parameter is given, default to top-level (main). @param [Object, Binding] target The receiver of the read-eval-print @return [Object] The result of the eval or an `Exception` object in case of
error. In the latter case, you can check whether the exception was raised or is just the result of the expression using #last_result_is_exception?
@example
Pry.new.re(Object.new)
# File lib/pry/pry_instance.rb, line 269 def re(target=TOPLEVEL_BINDING) target = Pry.binding_for(target) # It's not actually redundant to inject them continually as we may have # moved into the scope of a new Binding (e.g the user typed `cd`). inject_sticky_locals(target) code = r(target) evaluate_ruby(code, target) rescue RescuableException => e self.last_exception = e e end
Returns the next line of input to be used by the pry instance. This method should not need to be invoked directly. @param [String] current_prompt The prompt to use for input. @return [String] The next line of input.
# File lib/pry/pry_instance.rb, line 608 def readline(current_prompt="> ", completion_proc=nil) handle_read_errors do if defined? Coolline and input.is_a? Coolline input.completion_proc = proc do |cool| completions = completion_proc.call cool.completed_word completions.compact end elsif input.respond_to? :completion_proc= input.completion_proc = completion_proc end if input == Readline if !$stdout.tty? && $stdin.tty? && !Pry::Helpers::BaseHelpers.windows? Readline.output = File.open('/dev/tty', 'w') end input.readline(current_prompt, false) # false since we'll add it manually elsif defined? Coolline and input.is_a? Coolline input.readline(current_prompt) else if input.method(:readline).arity == 1 input.readline(current_prompt) else input.readline end end end end
Refresh the Pry instance settings from the Pry class. Allows options to be specified to override settings from Pry class. @param [Hash] options The options to override Pry class settings
for this instance.
# File lib/pry/pry_instance.rb, line 95 def refresh(options={}) defaults = {} attributes = [ :input, :output, :commands, :print, :quiet, :exception_handler, :hooks, :custom_completions, :prompt, :memory_size, :extra_sticky_locals ] attributes.each do |attribute| defaults[attribute] = Pry.send attribute end defaults[:input_stack] = Pry.input_stack.dup defaults.merge!(options).each do |key, value| send("#{key}=", value) if respond_to?("#{key}=") end true end
Perform a read-eval-print. If no parameter is given, default to top-level (main). @param [Object, Binding] target The receiver of the read-eval-print @example
Pry.new.rep(Object.new)
# File lib/pry/pry_instance.rb, line 252 def rep(target=TOPLEVEL_BINDING) target = Pry.binding_for(target) result = re(target) Pry.critical_section do show_result(result) end end
Start a read-eval-print-loop. If no parameter is given, default to top-level (main). @param [Object, Binding] target The receiver of the Pry session @return [Object] The target of the Pry session or an explictly given
return value. If given return value is `nil` or no return value is specified then `target` will be returned.
@example
Pry.new.repl(Object.new)
# File lib/pry/pry_instance.rb, line 224 def repl(target=TOPLEVEL_BINDING) target = Pry.binding_for(target) repl_prologue(target) break_data = nil exception = catch(:raise_up) do break_data = catch(:breakout) do loop do throw(:breakout) if binding_stack.empty? rep(binding_stack.last) end end exception = false end raise exception if exception break_data ensure repl_epilogue(target) end
Clean-up after the repl session. @param [Binding] target The target binding for the session.
# File lib/pry/pry_instance.rb, line 209 def repl_epilogue(target) exec_hook :after_session, output, target, self binding_stack.pop Pry.save_history if Pry.config.history.should_save end
Initialize the repl session. @param [Binding] target The target binding for the session.
# File lib/pry/pry_instance.rb, line 198 def repl_prologue(target) exec_hook :before_session, output, target, self set_last_result(nil, target) @input_array << nil # add empty input so _in_ and _out_ match binding_stack.push target end
Read and process a line of input -- check for ^D, determine which prompt to use, rewrite the indentation if `::config.auto_indent` is enabled, and, if the line is a command, process it and alter the eval_string accordingly. This method should not need to be invoked directly.
@param [String] eval_string The cumulative lines of input. @param [Binding] target The target of the session. @return [String] The line received.
# File lib/pry/pry_instance.rb, line 372 def retrieve_line(eval_string, target) @indent.reset if eval_string.empty? current_prompt = select_prompt(eval_string, target) completion_proc = Pry.config.completer.build_completion_proc(target, self, instance_eval(&custom_completions)) safe_completion_proc = proc{ |*a| Pry.critical_section{ completion_proc.call(*a) } } indentation = Pry.config.auto_indent ? @indent.current_prefix : '' begin val = readline("#{current_prompt}#{indentation}", safe_completion_proc) # Handle <Ctrl+C> like Bash, empty the current input buffer but do not quit. # This is only for ruby-1.9; other versions of ruby do not let you send Interrupt # from within Readline. rescue Interrupt output.puts "" eval_string.replace("") return end # invoke handler if we receive EOF character (^D) if !val output.puts "" Pry.config.control_d_handler.call(eval_string, self) return end # Change the eval_string into the input encoding (Issue 284) # TODO: This wouldn't be necessary if the eval_string was constructed from # input strings only. if should_force_encoding?(eval_string, val) eval_string.force_encoding(val.encoding) end if Pry.config.auto_indent && !input.is_a?(StringIO) original_val = "#{indentation}#{val}" indented_val = @indent.indent(val) if output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent output.print @indent.correct_indentation(current_prompt, indented_val, original_val.length - indented_val.length) output.flush end else indented_val = val end # Check this before processing the line, because a command might change # Pry's input. interactive = !input.is_a?(StringIO) begin if !process_command(val, eval_string, target) eval_string << "#{indented_val.chomp}\n" unless val.empty? end ensure Pry.history << indented_val if interactive end end
Run the specified command. @param [String] val The command (and its params) to execute. @param [String] eval_string The current input buffer. @param [Binding] target The binding to use.. @return [Pry::Command::VOID_VALUE] @example
pry_instance.run_command("ls -m")
# File lib/pry/pry_instance.rb, line 476 def run_command(val, eval_string = "", target = binding_stack.last) commands.process_line(val, :eval_string => eval_string, :target => target, :pry_instance => self, :output => output ) Pry::Command::VOID_VALUE end
Returns the appropriate prompt to use. This method should not need to be invoked directly. @param [String] eval_string The current input buffer. @param [Binding] target The target Binding of the Pry session. @return [String] The prompt.
# File lib/pry/pry_instance.rb, line 649 def select_prompt(eval_string, target) target_self = target.eval('self') open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last : @indent.stack.last c = OpenStruct.new( :object => target_self, :nesting_level => binding_stack.size - 1, :open_token => open_token, :session_line => Pry.history.session_line_count + 1, :history_line => Pry.history.history_line_count + 1, :expr_number => input_array.count, :_pry_ => self, :binding_stack => binding_stack, :input_array => input_array, :eval_string => eval_string, :cont => !eval_string.empty?) Pry.critical_section do # If input buffer is empty then use normal prompt if eval_string.empty? generate_prompt(Array(prompt).first, c) # Otherwise use the wait prompt (indicating multi-line expression) else generate_prompt(Array(prompt).last, c) end end end
Set the last result of an eval. This method should not need to be invoked directly. @param [Object] result The result. @param [Binding] target The binding to set `_` on. @param [String] code The code that was run.
# File lib/pry/pry_instance.rb, line 510 def set_last_result(result, target, code="") @last_result_is_exception = false @output_array << result self.last_result = result unless code =~ /\A\s*\z/ end
Whether the print proc should be invoked. Currently only invoked if the output is not suppressed. @return [Boolean] Whether the print proc should be invoked.
# File lib/pry/pry_instance.rb, line 640 def should_print? !@suppress_output end
Output the result or pass to an exception handler (if result is an exception).
# File lib/pry/pry_instance.rb, line 336 def show_result(result) if last_result_is_exception? exception_handler.call(output, result, self) elsif should_print? print.call(output, result) else # nothin' end rescue RescuableException => e # Being uber-paranoid here, given that this exception arose because we couldn't # serialize something in the user's program, let's not assume we can serialize # the exception either. begin output.puts "(pry) output error: #{e.inspect}" rescue RescuableException => e if last_result_is_exception? output.puts "(pry) output error: failed to show exception" else output.puts "(pry) output error: failed to show result" end end end
@return [Hash] The currently defined sticky locals.
# File lib/pry/pry_instance.rb, line 183 def sticky_locals @sticky_locals ||= { :_in_ => proc { @input_array }, :_out_ => proc { @output_array }, :_pry_ => self, :_ex_ => proc { last_exception }, :_file_ => proc { last_file }, :_dir_ => proc { last_dir }, :_ => proc { last_result }, :__ => proc { @output_array[-2] } }.merge(extra_sticky_locals) end
Update Pry's internal state after evalling code. This method should not need to be invoked directly. @param [String] code The code we just eval'd
# File lib/pry/pry_instance.rb, line 543 def update_input_history(code) # Always push to the @input_array as the @output_array is always pushed to. @input_array << code if code Pry.line_buffer.push(*code.each_line) Pry.current_line += code.each_line.count end end