pry-0.9.12.6/0000755000004100000410000000000012272154173012615 5ustar www-datawww-datapry-0.9.12.6/Rakefile0000644000004100000410000000605312272154172014265 0ustar www-datawww-datarequire 'rake/clean' require 'rubygems/package_task' $:.unshift 'lib' require 'pry/version' CLOBBER.include('**/*~', '**/*#*', '**/*.log') CLEAN.include('**/*#*', '**/*#*.*', '**/*_flymake*.*', '**/*_flymake', '**/*.rbc', '**/.#*.*') def check_dependencies require 'bundler' Bundler.definition.missing_specs eval('nil', TOPLEVEL_BINDING, '
') # workaround for issue #395 rescue LoadError # if Bundler isn't installed, we'll just assume your setup is ok. rescue Bundler::GemNotFound raise RuntimeError, "You're missing one or more required gems. Run `bundle install` first." end desc "Set up and run tests" task :default => [:test] unless [].respond_to? :shuffle! class Array def shuffle! # TODO: fill this in if anyone cares self end end end def run_specs paths quiet = ENV['VERBOSE'] ? '' : '-q' exec "bacon -Ispec -rubygems #{quiet} #{paths.join ' '}" end desc "Run tests" task :test do check_dependencies unless ENV['SKIP_DEP_CHECK'] paths = if explicit_list = ENV['run'] explicit_list.split(',') else Dir['spec/**/*_spec.rb'].shuffle! end run_specs paths end task :spec => :test task :recspec do all = Dir['spec/**/*_spec.rb'].sort_by{|path| File.mtime(path)}.reverse warn "Running all, sorting by mtime: #{all[0..2].join(' ')} ...etc." run_specs all end desc "Run pry" task :pry do check_dependencies unless ENV['SKIP_DEP_CHECK'] load 'bin/pry' end desc "Show pry version" task :version do puts "Pry version: #{Pry::VERSION}" end desc "Profile pry's startup time" task :profile do require 'profile' require 'pry' Pry.start(TOPLEVEL_BINDING, :input => StringIO.new('exit')) end def modify_base_gemspec eval(File.read('pry.gemspec')).tap { |s| yield s } end namespace :ruby do spec = modify_base_gemspec do |s| s.platform = Gem::Platform::RUBY end Gem::PackageTask.new(spec) do |pkg| pkg.need_zip = false pkg.need_tar = false end end namespace :jruby do spec = modify_base_gemspec do |s| s.add_dependency('spoon', '~> 0.0') s.platform = 'java' end Gem::PackageTask.new(spec) do |pkg| pkg.need_zip = false pkg.need_tar = false end end [:mingw32, :mswin32].each do |v| namespace v do spec = modify_base_gemspec do |s| s.add_dependency('win32console', '~> 1.3') s.platform = "i386-#{v}" end Gem::PackageTask.new(spec) do |pkg| pkg.need_zip = false pkg.need_tar = false end end end desc "build all platform gems at once" task :gems => [:clean, :rmgems, 'ruby:gem', 'mswin32:gem', 'mingw32:gem', 'jruby:gem'] desc "remove all platform gems" task :rmgems => ['ruby:clobber_package'] task :rm_gems => :rmgems task :rm_pkgs => :rmgems desc "reinstall gem" task :reinstall => :gems do sh "gem uninstall pry" rescue nil sh "gem install #{File.dirname(__FILE__)}/pkg/pry-#{Pry::VERSION}.gem" end task :install => :reinstall desc "build and push latest gems" task :pushgems => :gems do chdir("#{File.dirname(__FILE__)}/pkg") do Dir["*.gem"].each do |gemfile| sh "gem push #{gemfile}" end end end pry-0.9.12.6/CHANGELOG0000644000004100000410000006514112272154172014035 0ustar www-datawww-data10/05/2013 version 0.9.12.2 minor fix * reload-code (with no args) should reload 'current file', issue #920 21/04/2013 version 0.9.12.1 HOTFIX * Fixes #890, workaround for jruby crash related to http://jira.codehaus.org/browse/JRUBY-7114 * note this fix is just applied to the 0.9.12 tag, not master. However, master has this fix applied too. 12/02/2013 version 0.9.12 Bug fixes: * Fix major bug where commands broke due to slop looking at ARGV instead of command parameters (#828) * Fix bug where pager broke in some situations (#845) * Fix broken rendering of some docs (#795) * silence warnings during failed tab-completion attempts * fix broken prompt when prompt is colored (#822 / #823) * added reload-method alias for reload-code (for backwards compat) * Reopen Readline.output if it is not a tty (see 1538bc0990) Features: * added pry --gem (see 19bfc13aa) * show-source now works on commands created with create_command * add -m (method) -c (class) and -f (file) switches to 'whereami' command * show-source now falls back to superclass if can't find class code (displays warning) * show-source/show-doc now indicate when -a option is available. 20/01/2013 version 0.9.11.4 * fixed pager bug (wouldn't render color codes in some circumstances) * added Pry.last_internal_error, useful for devs debugging commands 17/01/2013 version 0.9.11.3 * fix Pry.run_command * improve `ls` output * add :requires_gem => "jist" to 'gist' command (so deps can be installed via install-command) * improve help for 'edit' command 16/01/2013 version 0.9.11.2 * minor bug fix for gist on windows, rescuing Jist::ClipboardError rather than letting the scary error spill out to users and potentially have them think the gist didnt post. 16/01/2013 version 0.9.11.1 * fixed minor bug in 'gist' command where i neglected to remove a call to a non-existent method (no_arg) which was called when `gist` is invoked with no parameters 16/01/2013 version 0.9.11 dependency changes: * upgrade the slop gem to version ~> 3.4 * new optional dependency: Bond (you'll need to perform `gem install bond`). It enables autocompletion if you use Readline. Does not support work for Editline (more info: https://github.com/pry/pry/wiki/FAQ#wiki-readline). Big thanks to cldwalker. new features: * #738 basic Ruby 2.0 support * #732 JRuby 1.7.0+ support * new reload-code command, using it you can reload code for methods, classes, commands, objects and so on. e.g reload-code MyCLass, reload-code my_method, reload-code my_obj * added bond tabcompletion, much more powerful than standard tab completion. However, it requires a real 'readline' to work, so will not work on standard osx setup (since it uses Editline) * show-source can now extract source for classes, methods, procs, pry commands, and arbitrary objects (it shows the source for the class of the object). As a result, show-command is now deprecated * gist/play/save-file now infer object type without requiring flags, e.g play MyClass, play my_file.rb, play my_method * edit command can now edit most things, including: files, methods, classes, commands. As a result the 'edit-method' command is now deprecatd. e.g edit my_file.rb, edit my_method, edit MyClass * removed "edit-method", now merged with 'edit' * amend-line and play now properly indent code added to input buffer. * #674 added support for require switches chaining (`pry -rubygems -r./a.rb`) * #695 added ability to customize the name displayed in the prompt * #716 added `--patch` switch for `edit --ex` command * #736 respect the `$PAGER` environment variable * #497 added `disable-pry` command * removed "show-command" command; use "show-source" command instead * exec switch chaining (`pry -e ':one' -e ':two'`) * added two new hooks: "before_eval" and "after_eval" * added tabcompletion for "show-source", "show-doc" commands and "Array#" cases * immediately require gems after gem-install * added `-l` switch for `ls` command (displays local variables) * added "gem-open" command * added "fix-indent" command * added subcommands API * exposed the test API for plugin writers (d1489a) * tablifed ls output * added `--no-line-numbers` switch for "whereami" command * added `--lines` switch for "play" command bug fixes: * #652 find-method uses single escape instead of double * #657 fixed blank string delimiters * #622 fixed "unwanted 'binding_impl_method' local now exists in scratch bindings" * #645 fixed "edit-method -p changes constant lookup" * #682 fixed ".pryrc" loading twice when invoked from `$HOME` directory * #675 fixed pry not remembering initial "pwd" * #717 fixed multiline object coloring * #719 fixed "show-method" not supporting `String::new` notation * #754 fixed "whereami" command not showing correct line numbers * #751 fixed buggy Cucumber AST output * #787 fixed `while/until do` loops indentation * #526 fixed buggy `--no-plugins` switch of pry * #774 ensure all errors go to the error handler * fixed ".pryrc" loading with wrong `__FILE__` * fixed bug when pager doesn't work if "less" is not available on system * fixed "Control-D" press in nested REPL * many small improvements of unclear error messages and formatting of documentation 14/07/2012 version 0.9.10 dependency changes: * #561 upgrade the slop gem to version 3 * #590 move to the jist gem from gist. * upgrade method_source to 0.8 new features: * #572 add --hist, -o and -k flags to gist command * #584 support show-source/doc on methods defined in class-eval * #585 support show-source/doc on gem methods defined in C * #596 add --disable-plugin and --select-plugin options * #597 allow "cd -" to switch between bindings * #612 add Pry.config.should_load_local_rc to turn off ./.pryrc * allow running a file of pry input with pry * support colours in "ri" command * add before_eval hook * prompt now gets a lot more data when proc arity is 1 bug fixes &c. * #554 removed the "req" command * #567 fix rendering bugs when starting pry * #568 fix Array#pretty_print on Jruby * #575 fix "edit" on windows * #576 fix "find-method" in the presence of badly behaved objects * #580 fix "whereami" in erb files on rails * #632 raise fewer exceptions while tab completing * #605 dont immediately quite pry when an error happens in readline * #606 support for ansicon to give jruby windows users colour * #613 massive speed improvements to show-source for modules * #620 improve whereami command when not in a binding.pry * #622 support embedded documents (=begin ... =end) * #627 support editing files with spaces in the name * changed __binding_impl__ to __pry__ * support for absolute paths in $EDITOR * fix "cat" command on files with unknown extensions * many many internal refactorings and tidyings 09/05/2012 version 0.9.9.6 fixes #558 * #558 has been a thorn in our side for long enough, hopefully this properly fixes it (though im not too confident :P) 09/05/2012 version 0.9.9.5 minor bugfix * fixed ZeroDivisionError in correct_indentation, bug #558 * fix double highlighting in rdoc, bug #562 * autocreate configuration for plugins, bug #548 26/4/2012 version 0.9.9.4 major bugfix * fixed `NoMethodError: undefined method `winsize' for #>`, bug #549 * fixes for jruby * breakage on `exit` syntax error, fixes, #550 * heredoc content no longer auto-indented 19/4/2012 version 0.9.9.3 major doc bugfix * show-doc would fail on some core classes, i.e `show-doc Bignum`. This is now fixed and show allow a wider range of core documentation to be viewed directly in Pry. 18/4/2012 version 0.9.9.2 minor bugfix * make correct_indentation's auto-colorization respect Pry.color 18/4/2012 version 0.9.9.1 very minor release * cleared up confusion in show-source/show-doc docs that -a switch applies to classes as well as modules 18/4/2012 version 0.9.9 MAJOR NEW FEATURES * lines of input are syntax highlighted upon 'enter' keypress * show-source command can now show class/module sourcecode (use -a to see all monkeypatches). Hard dependency on ruby18_source_location gem in MRI 1.8 * show-doc command can show class/module docs (use -a to see docs for all monkeypatches) Hard dependency on ruby18_source_location gem in MRI 1.8. * new `find-method` command, performs a recursive search in a namespace for the existence of methods. Can find methods whose names match a regex or methods which contain provided CODE! This command is like a ruby-aware 'grep', very cool (thanks swarley) * pry-coolline now works properly with Pry (https://github.com/pry/pry-coolline) * alias_command method now much more powerful, e.g: alias_command "lM", "ls -M" * `whereami` is now more intelligent, automatically showing entire sourcecode of current method if current context is a method (thanks robgleeson). * new `raise-up` command. Allows you to raise an exception that will bubble out of pry (ending the session) and escape into enclosing program. remaining items: * fixed windows crashing bug when paging * lines ending with \ are incomplete (kudos to fowl) * `edit-method -n` no longer blocks (thanks misfo)s * show instance methods of modules by default in ls * docs for REPL defined methods can now be displayed using show-doc * autoload ruby18_source_location on mri18, when available (https://github.com/conradirwin/ruby18_source_location) * tab completion should work on first line now (historic bug fixed) * :quiet => true option added to `Pry.start`, turns off whereami * another easter egg added * show unloaded constants in yellow for ls * improved documentation for Pry.config options * improved auto indentation * JRuby: heuristics used to clean up 'ls' output (less internal methods polluting output) 6/3/2012 version 0.9.8.4 major bugfix * ~/.pry_history wasnt being created (if it did not exist)! FIXED * `hist --save` saved colors! FIXED * added Pry#add_sticky_local API for adding sticky locals to individual pry instances 2/3/2012 version 0.9.8.3 minor update * various tweaks to improve rbx support * commands now support optional block arguments * much improved help command * updated method_source dependencya * added wtf command * jruby should now work in windows (though without color) 9/2/2012 version 0.9.8.2 bugfix * fixed bugs related to --super * upgraded slop dependency * added edit -c (edit current line) * edit now respects Pry.config.disable_autoreload option 30/1/2012 version 0.9.8.1 bugfix * fixed broken --no-plugins option * Ensure ARGV is not mutated during option parsing. * Use a more rbx-friendly test for unicodeness * Use rbx-{18,19}mode as indicated http://about.travis-ci.org/docs/user/languages/ruby/ * Don't explode in gem-list [Fixes #453, #454] * Check for command-name collision on assignment [Fixes #450] 25/1/2012 version 0.9.8 MAJOR NEW FEATURES - upgraded command api, https://github.com/pry/pry/wiki/Custom-commands - added a system of hooks for customizing pry behaviour - changed syntax checking to use eval() for improved accuracy - added save-file command - added gist command (removed gist-method, new gist command is more general) complete CHANGELOG: * CommandError's no longer cause the current input to be disgarded * Better syntax highlighting for rbx code code * added cat --in to show pry input history * prefixed temporary file names with 'pry' * show-doc now supports -l and -b options (line numbers) * play now supports -i and -d options * moved UserCommandAPI command-set to pry-developer_tools plugin * added :when_started event for hooks, called in Pry.start * added a man page * added rename method to Pry::CommandSet (commands can be renamed) * added CommandSet#{before_command,after_command} for enhancing builtin commands * added checking for namespace collisions with pry commands, set Pry.config.collision_warning * work around namespace collisions by ensuring lines starting with a space are executed as * ruby.work around namespace collisions by prensuring lines starting with a space are executed as ruby * added handlers for Ctrl+C (SIGINT) on jruby, these are now caught as in other ruby versions * removed dependency on ruby_parser * prevented colours leaking across the pry prompt * fixed edge cases in Pry::Method, for methods with crazy names and methods that have been 'undef'd * refactored history handling code for clarity and correctness * added Pry::WrappedModule as a counterpart to Pry::Method * made a trailing , cause pry to wait for further input * removed gist-method command, added gist command * added pry-backtrace command to show history of current session * fixed whereami within 'super' methods * replaced inline version guards by Pry::Helpers::BaseHelpers.{rbx?,jruby?,windows?} etc. * removed the CommandProcessor, its functionality is part of the new Command class * changed cd .. at the top level so it doesn't quit pry. * changed edit-command to no-longer need a command set argument * fixed empty lines so that they don't replace _ by nil * fixed SyntaxErrors at the REPL level so they don't replace _ex_. 5/11/2011 version 0.9.7.4 hotfix * ls -M now works in modules (bugfix) * added exception msg for bad cd object/path * no longer die when encounter exceptions in .pryrc * baked in CoolLine support * Pry.config.input in .pryrc now respected 28/10/2011 version 0.9.7.3 hotfix-hotfix ;) * really fixed indentation for 'super if' and friends * Fixed indentation for tmux * added Pry.config.correct_indent option (to toggle whether indentation * corrected optional param behaviour for method signatures: e.g Signature meth(param1=?, param2=?) 27/10/2011 version 0.9.7.2 hotfix * fixed indentation for 'super if' and 'ensure', 'next if', etc * refactored Pry#run_command so it can accept an eval_string parameter (so amend-line and so on can work with it) * changed ^D so it no longer resets indent level automatically 26/10/2011 version 0.9.7.1 hotfix * fixed gem dependecy issues 25/10/2011 version 0.9.7 MAJOR NEW FEATURES: - upgraded ls command to have a more intuitive interface - added automatic indentation (thanks YorickPeterse!) - added Pry::Method wrapper class to encapsulate method-related functionality complete CHANGELOG: * fixed syntax highlighting for object literals * fixed ActiveSupport method-naming conflict with "in?" * added --super option to edit-method, show-method, and friends - making it easier to operate on superclass methods * officially added edit --in to open previous expressions in an editor * whereami now works for REPL-defined code * started using JRuby parser for input validation in JRuby (thanks pangloss!) * fixed bug where ~/.pryrc could be loaded more than once (thanks kelseyjudson!) * added parse_options! helper to pull option parsing out of commands * Pry now respects the terminal's input encoding * moved some requires out of the startup process for improved speed * added input_array info to DEFAULT_PROMPT, e.g [1] pry(main)> * added --no-history option to pry binary (prevent history being LOADED, history will still be saved) 27/9/2011 version 0.9.6.2 HOTFIX release * downgrading to CodeRay 0.9.8 due to problems with 1.0 and rails (autoloading problem) see #280 on pry and #6 on CodeRay * also added (as a minor feature) cirwin's implementation of edit --in * added early break/exit for objectpath errors (the 'cd 34/@hello/bad_path/23') 19/9/2011 version 0.9.6 * restored previous behavior of command-line switches (allowing "-rfilename") * removed -p option (--play) from edit command * `edit` with no arguments now edits the current or most recent expression * `edit` auto-reloads .rb files (need to specify -n to suppress) * added -p option (--patch) to edit-method command, which allows monkeypatching methods without touching the original file * edit-method can now edit REPL-defined methods * cat --ex now works on exceptions in REPL-defined code * play -m now uses eval_string.replace() * play -m --open uses show-input to show play'd code * added "unindent" helper to make adding help to commands easier * local ./.pryrc now loaded after ~/.pryrc if it exists * cat --ex N and edit --ex N now can navigate through backtrace, where cat --ex (with no args) moves throuh successive levels of the backtrace automatically with state stored on the exceptino object itself * new option Pry.config.exception_window_size determines window size for cat --ex * input_stack now implemented - pushing objects onto a pry instance's input_stack causes the instance to read from those objects in turn as it encounters EOF on the previous object. On finishing the input_stack the input object for the pry instance is set back to Pry.config.input, if this fails, pry breaks out of the REPL (throw(:breakout)) with an error message * Pry.config.system() defines how pry runs system commands * now injecting target_self method into command scope * play now performs 'show-input' always unless eval_string contains a valid expression (i.e it's about to be eval'd) * play and hist --replay now push the current input object onto the input_stack before redirecting input to a StringIO (works much better with pry-remote now) 8/9/2011 version 0.9.5 MAJOR NEW FEATURES: - JRuby support, including show-method/edit-method and editor integration on both 1.8 and 1.9 versions - extended cd syntax: cd ../@x/y - play command now works much better with _in_ array (this is a very powerful feature, esp with Pry::NAV_PROMPT) - history saving/loading is now lightning fast - 'edit' (entered by itself) now opens current lines in input buffer in an editor, and evals on exit - 'edit' command is also, in general more intelligent - ls output no longer in array format, and colors can be configured, e.g: Pry.config.ls.ivar_color = :bright_blue - new switch-to command for moving around the binding stack without exiting out of sessions - more sophisticated prompts, Pry::NAV_PROMPT to ease deep spelunking of code - major bug fix for windows systems - much better support for huge objects, should no longer hang pry (see #245) - cat --ex and edit --ex now work better complete CHANGELOG: * tempfile should end in .rb (for edit -t) * ls output should not be in array format * fix history saving (should not save all of Readline::HISTORY, but only what changed) * prevent blank lines going to Readline::HISTORY (thanks cirwin!) * ensure that cat --ex emulates the `whereami` format - includes line numbers and formatted the same, etc * fixed bug #200 ( https://github.com/pry/pry/issues/200 )- string interpolation bug (thanks to ryanf) * show-doc and stat now display method visibility (update WIKI) * got rid of warnings caused by stricter ruby 1.9.3 rules * remove interpolation of command names and fix interpolation error messag (update WIKI) (thanks ryanf!) * 'nested sessions' now use binding stacks (so each instance manages its own collection of bindings without spawning other instances) * 'cd ..' just pops a binding off the binding_stack with special behaviour when only one binding in stack - it breaks out of the repl loop * added switch-to command (like jump-to but doesnt unwind the stack) * show-method and show-doc now accept multiple method names * control_d hook added (Pry.config.control_d_handler) * behaviour of ^d is now to break out of current expr if in multi-line expr, or break out of current context if nested, or break out of pry repl loop if at top-level * can no longer interpolate command name itself e.g #{x}-#{y} where x = "show" and y = "doc" * ^C no longer captured * got rid of Pry.active_instance, Pry.last_exception and friends. * also special locals now shared among bindings in a pry instance (i.e _ex_ (and friends) re-injected into new binding entered with 'cd') * renamed inp and out to _in_ and _out_ (to avoid collisions with actual locals in debugging scope) * added third parameter to prompts, the pry instance itself (_pry) see https://github.com/pry/pry/issues/233 for why it's important * cd behaviour when no args performs the same as `cd /` * commands with keep_retval can now return nil (to suppress output now return 'void' instead) * Pry::CommandProcessor::Result introduced * Pry.view_clip() modified to be more robust and properly display Class#name * edit command when invoked with no args now works like edit -t * when edit is invoked (with no args or with -t) inside a multi-line expression input buffer, it dumps that buffer into a temp file and takes you to it * got rid of Pry#null_input? since all that was needed was eval_string.empty? * cd command now supports complex syntax: cd ../@y/y/../z * JRuby is no longer a 2nd class citizen, almost full JRuby support, passing 100% tests * added Pry::NAV_PROMPT (great new navigation prompt, per robgleeson) and Pry::SIMPLE_PRINT for simple (IRB-style) print output (just using inspect) * _pry_ now passed as 3rd parameter to :before_session hook * ls colors now configurable via Pry.config.ls.local_var_color = :bright_red etc * ls separator configurable via, e.g Pry.config.ls.separator = " " * Pry.view_clip() now only calls inspect on a few immediates, otherwise uses the #<> syntax, which has been truncated further to exclude teh mem address, again related to #245 27/7/2011 version 0.9.3 * cat --ex (cats 5 lines above and below line in file where exception was raised) * edit --ex (edits line in file where exception was raised) * edit -t (opens a temporary file and evals it in current context when closed) * `pry -r` requires now happen after plugin loading (so as not to interfere with * new Pry.config.disable_auto_reload option, for turning off auto reloading by edit-method and related (thanks ryanf) * add better error messages for `cd` command * fixed exotic object regression - BasicObject.new etc now return "=> unknown" * added reload-method command (reloads the associated file of a method) * converted: import => import-set, version => pry-version, install => install-command * Pry.config.command_prefix support (thanks ryanf!) * fixed indentation for simple-prompt * hist command now excludes last line of input (the command invocation itself) * hist now has `history` alias * missing plugins no longer raise exception, just print a warning to $stderr * fixed jedit editor support 21/6/2011 version 0.9.2 * fixed string interpolation bug (caused valid ruby code not to execute, sorry!) * fixed `ls` command, so it can properly display members of Object and classes, and BasicObject, etc * added a few git related commands to experimental command set, blame and diff 17/6/2011 version 0.9.0 * plugin system * regex commands * show-method works on methods defined in REPL * new command system/API * rubinius core support * more backports to ruby 1.8 * inp/out special locals * _ex_ backtrace navigation object (_ex_.line, _ex_.file) * readline history saving/loading * prompt stack * more hooks * amend-line * play * show-input * edit * much more comprehensive test suite * support for new and old rubygems API * changed -s behaviour of ls (now excludes Object methods) * removed eval-file, lls, lcd, and a few other commands 26/3/2011 version 0.7.6.1 * added slightly better support for YARD * now @param and @return tags are colored green and markdown `code` is syntax highlighted using coderay 26/3/2011 version 0.7.6 * `whereami` command now accepts parameter AROUND, to display AROUND lines on eitherside of invocation line. * made it so `whereami` is invoked even if no method exists in current context (i.e in rspec tests) * added rubinius support for `whereami` invocation in HOOKS by checking for __unknown__.rb rather than just
15/3/2011 version 0.7.0 * add pry-doc support with syntax highlighting for docs * add 'mj' option to ls (restrict to singleton methods) * add _ex_ local to hold last exception raised in an exception 6/3/2011 version 0.6.8 * add whereami command, a la the `ir_b` gem * make whereami run at the start of every session * make .pryrc be loaded by run-time pry sessions 4/3/2011 version 0.6.7 * color support * --simple-prompt for pry commandline * -I mode for pry commandline * --color mode for pry commandline * clean up requires (put them all in one place) * simple-prompt command and toggle-color commandd. 28/2/2011 version 0.6.3 * Using MethodSource 0.3.4 so 1.8 show-method support provided * `Set` class added to list of classes that are inspected 26/2/2011 version 0.6.1 * !@ command alias for exit_all * `cd /` for breaking out to pry top level (jump-to 0) * made `-e` option work in a more effective way for `pry` command line invocation * exit and exit-all commands now accept a parameter, this parameter becomes the return value of repl() * `command` method from CommandBase now accepts a :keep_retval arg that determines if command value is returned to pry session or just `nil` (`nil` was old behaviour) * tests for new :keep_retval and exit-all/exit behaviour; :keep_retval will remain undocumented. 22/2/2011 version 0.5.8 * Added -c (context) option to show-doc, show-methods and eval-file * Fixed up ordering issue of -c and -r parameters to command line pry 21/2/2011 version 0.5.7 * Added pry executable, auto-loads .pryrc in user's home directory, if it exists. 19/2/2011 version 0.5.5 * Added Pry.run_command * More useful error messages * Easter eggs (game and cohen-poem) 17/2/2011 version 0.5.0 * Use clipped version of Pry.view() for large objects * Exit Pry session on ^d * Use Shellwords for breaking up parameters to pry commands * Use OptionParser to parse options for default pry commands * Add version command * Refactor 'status' command: add current method info * Add meth_name_from_binding utility lambda to commands.rb * Add -M, -m, -v(erbose), -a(ll), -s(uper), -l(ocals), -i(ivars), -k(klass vars), etc options to ls * add -M(instance method) options to show-method and show-doc * add --help option to most commands * Get rid of ls_method and ls_imethods (subsumed by more powerful ls) * Get rid of show_idoc and show_imethod * Add special eval-file command that evals target file in current context 27/1/2011 version 0.4.5 * fixed show_method (though fragile as it references __binding_impl__ directly, making a name change to that method difficult 27/1/2011 version 0.4.4 * oops, added examples/ directory 26/1/2011 version 0.4.3 * added alias_command and desc methods to Pry::CommandBase * changed behaviour of ls_methods and ls_imethods to return sorted lists of methods 23/1/2011 version 0.4.1 * made it so a 'def meth;end' in an object Pry session defines singleton methods, not methods on the class (except in the case of immediates) * reorganized documentation, moving customization to a separate wiki file * storing wiki in a nested git repo, as github wiki pages have their own repo * added more tests for new method definition behaviour 21/1/2011 version 0.4.0 * added command API * added many new commands, i.e ls_methods and friends * modified other commands * now accepts greater customization, can modify: input, output, hooks, prompt, print object * added tab completion (even completes commands) * added extensive tests * added examples * many more changes 9/12/2010 version 0.1.3 * Got rid of rubygems dependency, refactored some code. 8/12/2010 version 0.1.2 * now rescuing SyntaxError as well as Racc::Parser error in valid_expression? 8/12/2010 version 0.1.0 * release! pry-0.9.12.6/bin/0000755000004100000410000000000012272154172013364 5ustar www-datawww-datapry-0.9.12.6/bin/pry0000755000004100000410000000034312272154172014124 0ustar www-datawww-data#!/usr/bin/env ruby # (C) John Mair (banisterfiend) # MIT license $0 = 'pry' begin require 'pry' rescue LoadError require 'rubygems' require 'pry' end # Process command line options and run Pry Pry::CLI.parse_options pry-0.9.12.6/Gemfile0000644000004100000410000000031512272154172014106 0ustar www-datawww-datasource 'https://rubygems.org' gemspec group :development do gem 'jist' end if RbConfig::CONFIG['ruby_install_name'] == 'rbx' gem 'rubysl-singleton' gem 'rubysl-prettyprint' gem 'rb-readline' end pry-0.9.12.6/wiki/0000755000004100000410000000000012272154173013560 5ustar www-datawww-datapry-0.9.12.6/wiki/Home.md0000644000004100000410000000037312272154173014775 0ustar www-datawww-dataFurther documentation on Pry can be found here: * [Customizing Pry](https://github.com/banister/pry/wiki/Customizing-pry) * [Blog post: Turning IRB on its head with Pry](http://banisterfiend.wordpress.com/2011/01/27/turning-irb-on-its-head-with-pry/)pry-0.9.12.6/wiki/Customizing-pry.md0000644000004100000410000003207612272154173017235 0ustar www-datawww-dataCustomizing Pry --------------- Pry supports customization of the input, the output, the commands, the hooks, the prompt, and the 'print' object (the "P" in REPL). Global customization, which applies to all Pry sessions, is done through invoking class accessors on the `Pry` class, the accessors are: * `Pry.input=` * `Pry.output=` * `Pry.commands=` * `Pry.hooks=` * `Pry.prompt=` * `Pry.print=` Local customization (applied to a single Pry session) is done by passing config hash options to `Pry.start()` or to `Pry.new()`; also the same accessors as described above for the `Pry` class exist for a Pry instance so that customization can occur at runtime. ### Input For input Pry accepts any object that implements the `readline` method. This includes `IO` objects, `StringIO`, `Readline`, `File` and custom objects. Pry initially defaults to using `Readline` for input. #### Example: Setting global input Setting Pry's global input causes all subsequent Pry instances to use this input by default: Pry.input = StringIO.new("@x = 10\nexit") Object.pry Object.instance_variable_get(:@x) #=> 10 The above will execute the code in the `StringIO` non-interactively. It gets all the input it needs from the `StringIO` and then exits the Pry session. Note it is important to end the session with 'exit' if you are running non-interactively or the Pry session will hang as it loops indefinitely awaiting new input. #### Example: Setting input for a specific session The settings for a specific session override the global settings (discussed above). There are two ways to set input for a specific pry session: At the point the session is started, or within the session itself (at runtime): ##### At session start Pry.start(Object, :input => StringIO.new("@x = 10\nexit")) Object.instance_variable_get(:@x) #=> 10 ##### At runtime If you want to set the input object within the session itself you use the special `_pry_` local variable which represents the Pry instance managing the current session; inside the session we type: _pry_.input = StringIO.new("@x = 10\nexit") Note we can also set the input object for the parent Pry session (if the current session is nested) like so: _pry_.parent.input = StringIO.new("@x = 10\nexit") ### Output For output Pry accepts any object that implements the `puts` method. This includes `IO` objects, `StringIO`, `File` and custom objects. Pry initially defaults to using `$stdout` for output. #### Example: Setting global output Setting Pry's global output causes all subsequent Pry instances to use this output by default: Pry.output = StringIO.new #### Example: Setting output for a specific session As per Input, given above, we set the local output as follows: ##### At session start Pry.start(Object, :output => StringIO.new("@x = 10\nexit")) ##### At runtime _pry_.output = StringIO.new ### Commands Pry commands are not methods; they are commands that are intercepted and executed before a Ruby eval takes place. Pry comes with a default command set (`Pry::Commands`), but these commands can be augmented or overriden by user-specified ones. The Pry command API is quite sophisticated supporting features such as: command set inheritance, importing of specific commands from another command set, deletion of commands, calling of commands within other commands, and so on. A valid Pry command object must inherit from `Pry::CommandBase` (or one of its subclasses) and use the special command API: #### Example: Defining a command object and setting it globally class MyCommands < Pry::CommandBase command "greet", "Greet the user." do |name, age| output.puts "Hello #{name.capitalize}, how does it feel being #{age}?" end end Pry.commands = MyCommands Then inside a pry session: pry(main)> greet john 9 Hello John, how does it feel being 9? => nil #### Example: Using a command object in a specific session As in the case of `input` and `output`: ##### At session start: Pry.start(self, :commands => MyCommands) ##### At runtime: _pry_.commands = MyCommands #### The command API The command API is defined by the `Pry::CommandBase` class (hence why all commands must inherit from it or a subclass). The API works as follows: ##### `command` method The `command` method defines a new command, its parameter is the name of the command and an optional second parameter is a description of the command. The associated block defines the action to be performed. The number of parameters in the block determine the number of parameters that will be sent to the command (from the Pry prompt) when it is invoked. Note that all parameters that are received will be strings; if a parameter is not received it will be set to `nil`. command "hello" do |x, y, z| puts "hello there #{x}, #{y}, and #{z}!" end Command aliases can also be defined - simply use an array of strings for the command name - all these strings will be valid names for the command. command ["ls", "dir"], "show a list of local vars" do output.puts target.eval("local_variables") end ##### `delete` method The `delete` method deletes a command or a group of commands. It can be useful when inheriting from another command set and you wish to keep only a portion of the inherited commands. class MyCommands < Pry::Commands delete "show_method", "show_imethod" end ##### `import_from` method The `import_from` method enables you to specifically select which commands will be copied across from another command set, useful when you only want a small number of commands and so inheriting and then deleting would be inefficient. The first parameter to `import_from` is the class to import from and the other paramters are the names of the commands to import: class MyCommands < Pry::CommandBase import_from Pry::Commands, "ls", "status", "!" end ##### `run` method The `run` command invokes one command from within another. The first parameter is the name of the command to invoke and the remainder of the parameters will be passed on to the command being invoked: class MyCommands < Pry::Commands command "ls_with_hello" do output.puts "hello!" run "ls" end end ##### `alias_command` method The `alias_command` method creates an alias of a command. The first parameter is the name of the new command, the second parameter is the name of the command to be aliased; an optional third parameter is the description to use for the alias. If no description is provided then the description of the original command is used. class MyCommands < Pry::Commands alias_command "help2", "help", "An alias of help" end ##### `desc` method The `desc` method is used to give a command a new description. The first parameter is the name of the command, the second parameter is the description. class MyCommands < Pry::Commands desc "ls", "a new description" end #### Utility methods for commands All commands can access the special `output` and `target` methods. The `output` method returns the `output` object for the active pry session. Ensuring that your commands invoke `puts` on this rather than using the top-level `puts` will ensure that all your session output goes to the same place. The `target` method returns the `Binding` object the Pry session is currently active on - useful when your commands need to manipulate or examine the state of the object. E.g, the "ls" command is implemented as follows command "ls" do output.puts target.eval("local_variables + instance_variables").inspect end #### The opts hash These are miscellaneous variables that may be useful to your commands: * `opts[:val]` - The line of input that invoked the command. * `opts[:eval_string]` - The cumulative lines of input for multi-line input. * `opts[:nesting]` - Lowlevel session nesting information. * `opts[:commands]` - Lowlevel data of all Pry commands. (see commands.rb for examples of how some of these options are used) #### The `help` command The `Pry::CommandBase` class automatically defines a `help` command for you. Typing `help` in a Pry session will show a list of commands to the user followed by their descriptions. Passing a parameter to `help` with the command name will just return the description of that specific command. If a description is left out it will automatically be given the description "No description.". If the description is explicitly set to `""` then this command will not be displayed in `help`. ### Hooks Currently Pry supports just two hooks: `before_session` and `after_session`. These hooks are invoked before a Pry session starts and after a session ends respectively. The default hooks used are stored in the `Pry::DEFAULT_HOOKS` and just output the text `"Beginning Pry session for "` and `"Ending Pry session for "`. #### Example: Setting global hooks All subsequent Pry instances will use these hooks as default: Pry.hooks = { :before_session => proc { |out, obj| out.puts "Opened #{obj}" }, :after_session => proc { |out, obj| out.puts "Closed #{obj}" } } 5.pry Inside the session: Opened 5 pry(5)> exit Closed 5 Note that the `before_session` and `after_session` procs receive the current session's output object and session receiver as parameters. #### Example: Setting hooks for a specific session Like all the other customization options, the global default (as explained above) can be overriden for a specific session, either at session start or during runtime. ##### At session start Pry.start(self, :hooks => { :before_session => proc { puts "hello world!" }, :after_session => proc { puts "goodbye world!" } }) ##### At runtime _pry_.hooks = { :before_session => proc { puts "puts "hello world!" } } ### Prompts The Pry prompt is used by `Readline` and other input objects that accept a prompt. Pry can accept two prompt-types for every prompt; the 'main prompt' and the 'wait prompt'. The main prompt is always used for the first line of input; the wait prompt is used in multi-line input to indicate that the current expression is incomplete and more lines of input are required. The default Prompt used by Pry is stored in the `Pry::DEFAULT_PROMPT` constant. A valid Pry prompt is either a single `Proc` object or a two element array of `Proc` objects. When an array is used the first element is the 'main prompt' and the last element is the 'wait prompt'. When a single `Proc` object is used it will be used for both the main prompt and the wait prompt. #### Example: Setting global prompt The prompt `Proc` objects are passed the receiver of the Pry session and the nesting level of that session as parameters (they can simply ignore these if they do not need them). # Using one proc for both main and wait prompts Pry.prompt = proc { |obj, nest_level| "#{obj}:#{nest_level}> " } # Alternatively, provide two procs; one for main and one for wait Pry.prompt = [ proc { "ENTER INPUT> " }, proc { "MORE INPUT REQUIRED!* " }] #### Example: Setting the prompt for a specific session ##### At session start Pry.start(self, :prompt => [proc { "ENTER INPUT> " }, proc { "MORE INPUT REQUIRED!* " }]) ##### At runtime _pry_.prompt = [proc { "ENTER INPUT> " }, proc { "MORE INPUT REQUIRED!* " }] ### Print The Print phase of Pry's READ-EVAL-PRINT-LOOP can be customized. The default action is stored in the `Pry::DEFAULT_PRINT` constant and it simply outputs the value of the current expression preceded by a `=>` (or the first line of the backtrace if the value is an `Exception` object.) The print object should be a `Proc` and the parameters passed to the `Proc` are the output object for the current session and the 'value' returned by the current expression. #### Example: Setting global print object Let's define a print object that displays the full backtrace of any exception and precedes the output of a value by the text `"Output is: "`: Pry.print = proc do |output, value| case value when Exception output.puts value.backtrace else output.puts "Output is: #{value}" end end #### Example: Setting the print object for a specific session ##### At session start Pry.start(self, :print => proc do |output, value| case value when Exception output.puts value.backtrace else output.puts "Output is: #{value.inspect}" end end) ##### At runtime _pry_.print = proc do |output, value| case value when Exception output.puts value.backtrace else output.puts "Output is: #{value.inspect}" end end [Back to front page of documentation](http://rdoc.info/github/banister/pry/master/file/README.markdown) pry-0.9.12.6/CONTRIBUTORS0000644000004100000410000000210612272154172014473 0ustar www-datawww-data 1068 John Mair 372 Conrad Irwin 215 Ryan Fitzgerald 108 Kyrylo Silin 92 Rob Gleeson 54 Mon ouïe 51 Lee Jarvis 47 ☈king 40 Jordon Bedwell 28 Yorick Peterse 18 David Palm 18 Robert Gleeson 15 epitron 12 Andrew Vos 11 Reginald Tan 10 Matt Carey 8 Eero Saynatkari 8 Trey Lawrence 6 Jason Laster 3 misfo 3 fowlmouth 3 Darrick Wiebe 2 Kelsey Judson 2 Ben Langfeld 2 Bram Swenson 2 Erik Michaels-Ober 2 Ingrid 2 Vít Ondruch 2 Xavier Shay 2 Jonathan Soeder 2 Eric Christopherson 2 robgleeson 1 Ben Pickles 1 Zeh Rizzatti 1 shirmung 1 sonnym 1 Shawn Anderson 1 Joe Peduto 1 Greg Stearns 1 Jonathan Jackson 1 Jordan Running 1 Gosha Arinich 1 Josh Cheek 1 Kirill Lashuk 1 Gerbert Olivé 1 Larry Gilbert 1 Lars Haugseth 1 Loic Nageleisen 1 Matthew Carey 1 Michael Bensoussan 1 Renato Mascarenhas 1 Havenwood 1 Sherin C 1 Sonali Sridhar 1 Tim Pope pry-0.9.12.6/spec/0000755000004100000410000000000012272154173013547 5ustar www-datawww-datapry-0.9.12.6/spec/completion_spec.rb0000644000004100000410000001252012272154173017257 0ustar www-datawww-datarequire 'helper' def new_completer(bind, pry=nil) Pry::InputCompleter.build_completion_proc(Pry.binding_for(bind), pry) end def completer_test(bind, pry=nil, assert_flag=true) completer = new_completer(bind, pry) test = proc {|symbol| completer.call(symbol[0..-2]).include?(symbol).should == assert_flag} return proc {|*symbols| symbols.each(&test) } end Pry.require_readline if defined?(Bond) && Readline::VERSION !~ /editline/i describe 'bond-based completion' do it 'should pull in Bond by default' do Pry.config.completer.should == Pry::BondCompleter end end end describe Pry::InputCompleter do before do # The AMQP gem has some classes like this: # pry(main)> AMQP::Protocol::Test::ContentOk.name # => :content_ok module SymbolyName def self.name; :symboly_name; end end $default_completer = Pry.config.completer Pry.config.completer = Pry::InputCompleter end after do Pry.config.completer = $default_completer Object.remove_const :SymbolyName end # another jruby hack :(( if !Pry::Helpers::BaseHelpers.jruby? it "should not crash if there's a Module that has a symbolic name." do completer = Pry::InputCompleter.build_completion_proc(Pry.binding_for(Object.new)) lambda{ completer.call "a.to_s." }.should.not.raise Exception end end it 'should take parenthesis and other characters into account for symbols' do b = Pry.binding_for(Object.new) completer = Pry::InputCompleter.build_completion_proc(b) lambda { completer.call(":class)") }.should.not.raise(RegexpError) end it 'should complete instance variables' do object = Class.new.new # set variables in appropriate scope object.instance_variable_set(:'@name', 'Pry') object.class.send(:class_variable_set, :'@@number', 10) # check to see if variables are in scope object.instance_variables. map { |v| v.to_sym }. include?(:'@name').should == true object.class.class_variables. map { |v| v.to_sym }. include?(:'@@number').should == true # Complete instance variables. b = Pry.binding_for(object) completer_test(b).call('@name', '@name.downcase') # Complete class variables. b = Pry.binding_for(object.class) completer_test(b).call('@@number', '@@number.class') end it 'should complete for stdlib symbols' do o = Object.new # Regexp completer_test(o).call('/foo/.extend') # Array completer_test(o).call('[1].push') # Hash completer_test(o).call('{"a" => "b"}.keys') # Proc completer_test(o).call('{2}.call') # Symbol completer_test(o).call(':symbol.to_s') # Absolute Constant completer_test(o).call('::IndexError') end it 'should complete for target symbols' do o = Object.new # Constant module Mod Con = 'Constant' module Mod2 end end completer_test(Mod).call('Con') # Constants or Class Methods completer_test(o).call('Mod::Con') # Symbol foo = :symbol completer_test(o).call(':symbol') # Variables class << o attr_accessor :foo end o.foo = 'bar' completer_test(binding).call('o.foo') # trailing slash new_completer(Mod).call('Mod2/').include?('Mod2/').should == true end it 'should complete for arbitrary scopes' do module Bar @barvar = :bar end module Baz @bar = Bar @bazvar = :baz Con = :constant end pry = Pry.new() stack = pry.binding_stack stack.push(Pry.binding_for(Baz)) stack.push(Pry.binding_for(Bar)) b = Pry.binding_for(Bar) completer_test(b, pry).call("../@bazvar") completer_test(b, pry).call('/Con') end it 'should complete for stdlib symbols' do o = Object.new # Regexp completer_test(o).call('/foo/.extend') # Array completer_test(o).call('[1].push') # Hash completer_test(o).call('{"a" => "b"}.keys') # Proc completer_test(o).call('{2}.call') # Symbol completer_test(o).call(':symbol.to_s') # Absolute Constant completer_test(o).call('::IndexError') end it 'should complete for target symbols' do o = Object.new # Constant module Mod Con = 'Constant' module Mod2 end end completer_test(Mod).call('Con') # Constants or Class Methods completer_test(o).call('Mod::Con') # Symbol foo = :symbol completer_test(o).call(':symbol') # Variables class << o attr_accessor :foo end o.foo = 'bar' completer_test(binding).call('o.foo') # trailing slash new_completer(Mod).call('Mod2/').include?('Mod2/').should == true end it 'should complete for arbitrary scopes' do module Bar @barvar = :bar end module Baz @bar = Bar @bazvar = :baz Con = :constant end pry = Pry.new() stack = pry.binding_stack stack.push(Pry.binding_for(Baz)) stack.push(Pry.binding_for(Bar)) b = Pry.binding_for(Bar) completer_test(b, pry).call("../@bazvar") completer_test(b, pry).call('/Con') end it 'should not return nil in its output' do pry = Pry.new new_completer(binding, pry).call("pry.").should.not.include nil end it "does not raise when complete file paths" do should.not.raise(Pry::CommandError) { new_completer(binding, Pry.new).call("cat lib/p") } end end pry-0.9.12.6/spec/documentation_helper_spec.rb0000644000004100000410000000421412272154173021317 0ustar www-datawww-datarequire 'helper' describe Pry::Helpers::DocumentationHelpers do before do @helper = Pry::Helpers::DocumentationHelpers end describe "get_comment_content" do it "should strip off the hash and unindent" do @helper.get_comment_content(" # hello\n # world\n").should == "hello\nworld\n" end it "should strip out leading lines of hashes" do @helper.get_comment_content("###############\n#hello\n#world\n").should == "hello\nworld\n" end it "should remove shebangs" do @helper.get_comment_content("#!/usr/bin/env ruby\n# This is a program\n").should == "This is a program\n" end it "should unindent past separators" do @helper.get_comment_content(" # Copyright Me \n #--\n # So there.\n").should == "Copyright Me \n--\nSo there.\n" end end describe "process_rdoc" do before do Pry.color = true end after do Pry.color = false end it "should syntax highlight indented code" do @helper.process_rdoc(" 4 + 4\n").should.not == " 4 + 4\n" end it "should highlight words surrounded by +s" do @helper.process_rdoc("the +parameter+").should =~ /the \e.*parameter\e.*/ end it "should syntax highlight things in backticks" do @helper.process_rdoc("for `Example`").should =~ /for `\e.*Example\e.*`/ end it "should emphasise em tags" do @helper.process_rdoc("for science").should == "for \e[1mscience\e[0m" end it "should emphasise italic tags" do @helper.process_rdoc("for science").should == "for \e[1mscience\e[0m" end it "should syntax highlight code in " do @helper.process_rdoc("for Example").should =~ /for \e.*Example\e.*/ end it "should not double-highlight backticks inside indented code" do @helper.process_rdoc(" `echo 5`").should =~ /echo 5/ end it "should not remove ++" do @helper.process_rdoc("--\n comment in a bubble\n++").should =~ /\+\+/ end it "should do nothing if Pry.color is false" do Pry.color = false @helper.process_rdoc(" 4 + 4\n").should == " 4 + 4\n" end end endpry-0.9.12.6/spec/pry_defaults_spec.rb0000644000004100000410000003257712272154173017625 0ustar www-datawww-datarequire 'helper' version = 1 describe "test Pry defaults" do before do @str_output = StringIO.new end after do Pry.reset_defaults Pry.color = false end describe "input" do after do Pry.reset_defaults Pry.color = false end it 'should set the input default, and the default should be overridable' do Pry.input = InputTester.new("5") Pry.output = @str_output Pry.new.rep @str_output.string.should =~ /5/ Pry.new(:input => InputTester.new("6")).rep @str_output.string.should =~ /6/ end it 'should pass in the prompt if readline arity is 1' do Pry.prompt = proc { "A" } arity_one_input = Class.new do attr_accessor :prompt def readline(prompt) @prompt = prompt "exit-all" end end.new Pry.start(self, :input => arity_one_input, :output => StringIO.new) arity_one_input.prompt.should == Pry.prompt.call end it 'should not pass in the prompt if the arity is 0' do Pry.prompt = proc { "A" } arity_zero_input = Class.new do def readline "exit-all" end end.new lambda { Pry.start(self, :input => arity_zero_input, :output => StringIO.new) }.should.not.raise Exception end it 'should not pass in the prompt if the arity is -1' do Pry.prompt = proc { "A" } arity_multi_input = Class.new do attr_accessor :prompt def readline(*args) @prompt = args.first "exit-all" end end.new Pry.start(self, :input => arity_multi_input, :output => StringIO.new) arity_multi_input.prompt.should == nil end end it 'should set the output default, and the default should be overridable' do Pry.input = InputTester.new("5", "6", "7") Pry.output = @str_output Pry.new.rep @str_output.string.should =~ /5/ Pry.new.rep @str_output.string.should =~ /5\n.*6/ @str_output = StringIO.new Pry.new(:output => @str_output).rep @str_output.string.should.not =~ /5\n.*6/ @str_output.string.should =~ /7/ end it "should set the print default, and the default should be overridable" do new_print = proc { |out, value| out.puts "=> LOL" } Pry.print = new_print Pry.new.print.should == Pry.print Pry.new(:input => InputTester.new("\"test\""), :output => @str_output).rep @str_output.string.should == "=> LOL\n" @str_output = StringIO.new Pry.new(:input => InputTester.new("\"test\""), :output => @str_output, :print => proc { |out, value| out.puts value.reverse }).rep @str_output.string.should == "tset\n" Pry.new.print.should == Pry.print @str_output = StringIO.new Pry.new(:input => InputTester.new("\"test\""), :output => @str_output).rep @str_output.string.should == "=> LOL\n" end describe "pry return values" do it 'should return nil' do Pry.start(self, :input => StringIO.new("exit-all"), :output => StringIO.new).should == nil end it 'should return the parameter given to exit-all' do Pry.start(self, :input => StringIO.new("exit-all 10"), :output => StringIO.new).should == 10 end it 'should return the parameter (multi word string) given to exit-all' do Pry.start(self, :input => StringIO.new("exit-all \"john mair\""), :output => StringIO.new).should == "john mair" end it 'should return the parameter (function call) given to exit-all' do Pry.start(self, :input => StringIO.new("exit-all 'abc'.reverse"), :output => StringIO.new).should == 'cba' end it 'should return the parameter (self) given to exit-all' do Pry.start("carl", :input => StringIO.new("exit-all self"), :output => StringIO.new).should == "carl" end end describe "prompts" do before do @empty_input_buffer = "" @non_empty_input_buffer = "def hello" @context = Pry.binding_for(0) end it 'should set the prompt default, and the default should be overridable (single prompt)' do new_prompt = proc { "test prompt> " } Pry.prompt = new_prompt Pry.new.prompt.should == Pry.prompt Pry.new.select_prompt(@empty_input_buffer, @context).should == "test prompt> " Pry.new.select_prompt(@non_empty_input_buffer, @context).should == "test prompt> " new_prompt = proc { "A" } pry_tester = Pry.new(:prompt => new_prompt) pry_tester.prompt.should == new_prompt pry_tester.select_prompt(@empty_input_buffer, @context).should == "A" pry_tester.select_prompt(@non_empty_input_buffer, @context).should == "A" Pry.new.prompt.should == Pry.prompt Pry.new.select_prompt(@empty_input_buffer, @context).should == "test prompt> " Pry.new.select_prompt(@non_empty_input_buffer, @context).should == "test prompt> " end it 'should set the prompt default, and the default should be overridable (multi prompt)' do new_prompt = [proc { "test prompt> " }, proc { "test prompt* " }] Pry.prompt = new_prompt Pry.new.prompt.should == Pry.prompt Pry.new.select_prompt(@empty_input_buffer, @context).should == "test prompt> " Pry.new.select_prompt(@non_empty_input_buffer, @context).should == "test prompt* " new_prompt = [proc { "A" }, proc { "B" }] pry_tester = Pry.new(:prompt => new_prompt) pry_tester.prompt.should == new_prompt pry_tester.select_prompt(@empty_input_buffer, @context).should == "A" pry_tester.select_prompt(@non_empty_input_buffer, @context).should == "B" Pry.new.prompt.should == Pry.prompt Pry.new.select_prompt(@empty_input_buffer, @context).should == "test prompt> " Pry.new.select_prompt(@non_empty_input_buffer, @context).should == "test prompt* " end describe 'storing and restoring the prompt' do before do make = lambda do |name,i| prompt = [ proc { "#{i}>" } , proc { "#{i+1}>" } ] (class << prompt; self; end).send(:define_method, :inspect) { "" } prompt end @a , @b , @c = make[:a,0] , make[:b,1] , make[:c,2] @pry = Pry.new :prompt => @a end it 'should have a prompt stack' do @pry.push_prompt @b @pry.push_prompt @c @pry.prompt.should == @c @pry.pop_prompt @pry.prompt.should == @b @pry.pop_prompt @pry.prompt.should == @a end it 'should restore overridden prompts when returning from file-mode' do pry = Pry.new :input => InputTester.new('shell-mode', 'shell-mode'), :prompt => [ proc { 'P>' } ] * 2 pry.select_prompt(@empty_input_buffer, @context).should == "P>" pry.re pry.select_prompt(@empty_input_buffer, @context).should =~ /\Apry .* \$ \z/ pry.re pry.select_prompt(@empty_input_buffer, @context).should == "P>" end it '#pop_prompt should return the popped prompt' do @pry.push_prompt @b @pry.push_prompt @c @pry.pop_prompt.should == @c @pry.pop_prompt.should == @b end it 'should not pop the last prompt' do @pry.push_prompt @b @pry.pop_prompt.should == @b @pry.pop_prompt.should == @a @pry.pop_prompt.should == @a @pry.prompt.should == @a end describe '#prompt= should replace the current prompt with the new prompt' do it 'when only one prompt on the stack' do @pry.prompt = @b @pry.prompt.should == @b @pry.pop_prompt.should == @b @pry.pop_prompt.should == @b end it 'when several prompts on the stack' do @pry.push_prompt @b @pry.prompt = @c @pry.pop_prompt.should == @c @pry.pop_prompt.should == @a end end end end describe "view_clip used for displaying an object in a truncated format" do VC_MAX_LENGTH = 60 describe "given an object with an #inspect string" do it "returns the #<> format of the object (never use inspect)" do o = Object.new def o.inspect; "a" * VC_MAX_LENGTH; end Pry.view_clip(o, VC_MAX_LENGTH).should =~ /# format of the special-cased immediate object if #inspect is longer than maximum" do o = "o" * (VC_MAX_LENGTH + 1) Pry.view_clip(o, VC_MAX_LENGTH).should =~ /# format of the object (never use inspect)" do o = Object.new def o.inspect; "a" * VC_MAX_LENGTH; end Pry.view_clip(o, VC_MAX_LENGTH).should =~ /# format" do o = Object.new def o.inspect; "a" * (VC_MAX_LENGTH + 1); end Pry.view_clip(o, VC_MAX_LENGTH).should =~ /# format" do c, m = Class.new, Module.new Pry.view_clip(c, VC_MAX_LENGTH).should =~ /# format" do c, m = Class.new, Module.new def c.name; "a" * (VC_MAX_LENGTH + 1); end def m.name; "a" * (VC_MAX_LENGTH + 1); end Pry.view_clip(c, VC_MAX_LENGTH).should =~ /# format" do c, m = Class.new, Module.new def c.name; "a" * VC_MAX_LENGTH; end def m.name; "a" * VC_MAX_LENGTH; end Pry.view_clip(c, VC_MAX_LENGTH).should == c.name Pry.view_clip(m, VC_MAX_LENGTH).should == m.name end end end end end describe 'quiet' do it 'should show whereami by default' do Pry.start(binding, :input => InputTester.new("1", "exit-all"), :output => @str_output, :hooks => Pry::DEFAULT_HOOKS) @str_output.string.should =~ /[w]hereami by default/ end it 'should hide whereami if quiet is set' do Pry.new(:input => InputTester.new("exit-all"), :output => @str_output, :quiet => true, :hooks => Pry::DEFAULT_HOOKS) @str_output.string.should == "" end end describe 'toplevel_binding' do it 'should be devoid of local variables' do pry_eval(Pry.toplevel_binding, "ls -l").should.not =~ /version/ end it 'should have self the same as TOPLEVEL_BINDING' do Pry.toplevel_binding.eval('self').should.equal? TOPLEVEL_BINDING.eval('self') end # https://github.com/rubinius/rubinius/issues/1779 unless Pry::Helpers::BaseHelpers.rbx? it 'should define private methods on Object' do TOPLEVEL_BINDING.eval 'def gooey_fooey; end' method(:gooey_fooey).owner.should == Object Pry::Method(method(:gooey_fooey)).visibility.should == :private end end end it 'should set the hooks default, and the default should be overridable' do Pry.input = InputTester.new("exit-all") Pry.hooks = Pry::Hooks.new. add_hook(:before_session, :my_name) { |out,_,_| out.puts "HELLO" }. add_hook(:after_session, :my_name) { |out,_,_| out.puts "BYE" } Pry.new(:output => @str_output).repl @str_output.string.should =~ /HELLO/ @str_output.string.should =~ /BYE/ Pry.input.rewind @str_output = StringIO.new Pry.new(:output => @str_output, :hooks => Pry::Hooks.new. add_hook( :before_session, :my_name) { |out,_,_| out.puts "MORNING" }. add_hook(:after_session, :my_name) { |out,_,_| out.puts "EVENING" } ).repl @str_output.string.should =~ /MORNING/ @str_output.string.should =~ /EVENING/ # try below with just defining one hook Pry.input.rewind @str_output = StringIO.new Pry.new(:output => @str_output, :hooks => Pry::Hooks.new. add_hook(:before_session, :my_name) { |out,_,_| out.puts "OPEN" } ).repl @str_output.string.should =~ /OPEN/ Pry.input.rewind @str_output = StringIO.new Pry.new(:output => @str_output, :hooks => Pry::Hooks.new. add_hook(:after_session, :my_name) { |out,_,_| out.puts "CLOSE" } ).repl @str_output.string.should =~ /CLOSE/ Pry.reset_defaults Pry.color = false end end pry-0.9.12.6/spec/prompt_spec.rb0000644000004100000410000000373012272154173016432 0ustar www-datawww-datarequire 'helper' describe "Prompts" do describe "one-parameter prompt proc" do it 'should get full config object' do config = nil redirect_pry_io(InputTester.new("exit-all")) do Pry.start(self, :prompt => proc { |v| config = v }) end config.is_a?(OpenStruct).should == true end it 'should get full config object, when using a proc array' do config1 = nil redirect_pry_io(InputTester.new("exit-all")) do Pry.start(self, :prompt => [proc { |v| config1 = v }, proc { |v| config2 = v }]) end config1.is_a?(OpenStruct).should == true end it 'should receive correct data in the config object' do config = nil redirect_pry_io(InputTester.new("def hello", "exit-all")) do Pry.start(self, :prompt => proc { |v| config = v }) end config.eval_string.should =~ /def hello/ config.nesting_level.should == 0 config.expr_number.should == 1 config.cont.should == true config._pry_.is_a?(Pry).should == true config.object.should == self end end describe "BACKWARDS COMPATIBILITY: 3 parameter prompt proc" do it 'should get 3 parameters' do o = n = p = nil redirect_pry_io(InputTester.new("exit-all")) do Pry.start(:test, :prompt => proc { |obj, nesting, _pry_| o, n, p = obj, nesting, _pry_ }) end o.should == :test n.should == 0 p.is_a?(Pry).should == true end it 'should get 3 parameters, when using proc array' do o1 = n1 = p1 = nil redirect_pry_io(InputTester.new("exit-all")) do Pry.start(:test, :prompt => [proc { |obj, nesting, _pry_| o1, n1, p1 = obj, nesting, _pry_ }, proc { |obj, nesting, _pry_| o2, n2, p2 = obj, nesting, _pry_ }]) end o1.should == :test n1.should == 0 p1.is_a?(Pry).should == true end end end pry-0.9.12.6/spec/helper.rb0000644000004100000410000000164712272154173015363 0ustar www-datawww-dataunless Object.const_defined? 'Pry' $:.unshift File.expand_path '../../lib', __FILE__ require 'pry' end require 'mocha/api' require 'pry/test/helper' require 'helpers/bacon' require 'helpers/mock_pry' class Module public :remove_const public :remove_method end # turn warnings off (esp for Pry::Hooks which will generate warnings # in tests) $VERBOSE = nil Pad = OpenStruct.new def Pad.clear @table = {} end # to help with tracking down bugs that cause an infinite loop in the test suite if ENV["SET_TRACE_FUNC"] require 'set_trace' if Pry::Helpers::BaseHelpers.rbx? set_trace_func proc { |event, file, line, id, binding, classname| STDERR.printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname } end puts "Ruby v#{RUBY_VERSION} (#{defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"}), Pry v#{Pry::VERSION}, method_source v#{MethodSource::VERSION}, CodeRay v#{CodeRay::VERSION}, Slop v#{Slop::VERSION}" pry-0.9.12.6/spec/pry_spec.rb0000644000004100000410000004051312272154173015723 0ustar www-datawww-datarequire 'helper' describe Pry do before do @str_output = StringIO.new end if RUBY_VERSION =~ /1.9/ describe "Exotic object support" do # regression test for exotic object support it "Should not error when return value is a BasicObject instance" do lambda do redirect_pry_io(InputTester.new("BasicObject.new", "exit-all"), StringIO.new) do Pry.start end end.should.not.raise NoMethodError end end end describe 'DISABLE_PRY' do before do ENV['DISABLE_PRY'] = 'true' end after do ENV.delete 'DISABLE_PRY' end it 'should not binding.pry' do binding.pry.should == nil end it 'should not Pry.start' do Pry.start.should == nil end end describe "Pry.critical_section" do it "should prevent Pry being called" do output = StringIO.new Pry.output = output Pry.critical_section do Pry.start end output.string.should =~ /Pry started inside Pry/ end end describe "Pry.binding_for" do # regression test for burg's bug (see git history) it "Should not error when object doesn't have a valid == method" do o = Object.new def o.==(other) raise end lambda { Pry.binding_for(o) }.should.not.raise Exception end it "should not leak local variables" do [Object.new, Array, 3].each do |obj| Pry.binding_for(obj).eval("local_variables").should.be.empty end end end describe "open a Pry session on an object" do describe "rep" do before do class Hello end end after do Object.send(:remove_const, :Hello) end # bug fix for https://github.com/banister/pry/issues/93 it 'should not leak pry constants into Object namespace' do input_string = "Command" o = Object.new pry_tester = Pry.new(:input => StringIO.new(input_string), :output => @str_output, :exception_handler => proc { |_, exception, _pry_| @excep = exception }, :print => proc {} ).rep(o) @excep.is_a?(NameError).should == true end if defined?(BasicObject) it 'should be able to operate inside the BasicObject class' do redirect_pry_io(InputTester.new(":foo", "Pad.obj = _", "exit-all")) do BasicObject.pry end Pad.obj.should == :foo end end it 'should set an ivar on an object' do input_string = "@x = 10" input = InputTester.new(input_string) o = Object.new pry_tester = Pry.new(:input => input, :output => StringIO.new) pry_tester.rep(o) o.instance_variable_get(:@x).should == 10 end it 'should display error if Pry instance runs out of input' do redirect_pry_io(StringIO.new, @str_output) do Pry.new.repl end @str_output.string.should =~ /Error: Pry ran out of things to read/ end it 'should make self evaluate to the receiver of the rep session' do o = :john pry_tester = Pry.new(:input => InputTester.new("self"), :output => @str_output) pry_tester.rep(o) @str_output.string.should =~ /:john/ end it 'should work with multi-line input' do o = Object.new pry_tester = Pry.new(:input => InputTester.new("x = ", "1 + 4"), :output => @str_output) pry_tester.rep(o) @str_output.string.should =~ /5/ end it 'should define a nested class under Hello and not on top-level or Pry' do pry_tester = Pry.new(:input => InputTester.new("class Nested", "end"), :output => StringIO.new) pry_tester.rep(Hello) Hello.const_defined?(:Nested).should == true end it 'should suppress output if input ends in a ";" and is an Exception object (single line)' do o = Object.new pry_tester = Pry.new(:input => InputTester.new("Exception.new;"), :output => @str_output) pry_tester.rep(o) @str_output.string.should == "" end it 'should suppress output if input ends in a ";" (single line)' do o = Object.new pry_tester = Pry.new(:input => InputTester.new("x = 5;"), :output => @str_output) pry_tester.rep(o) @str_output.string.should == "" end it 'should suppress output if input ends in a ";" (multi-line)' do o = Object.new pry_tester = Pry.new(:input => InputTester.new("def self.blah", ":test", "end;"), :output => @str_output) pry_tester.rep(o) @str_output.string.should == "" end it 'should be able to evaluate exceptions normally' do o = Exception.new was_called = false pry_tester = Pry.new(:input => InputTester.new("self"), :output => @str_output, :exception_handler => proc { was_called = true }) pry_tester.rep(o) was_called.should == false end it 'should notice when exceptions are raised' do o = Exception.new was_called = false pry_tester = Pry.new(:input => InputTester.new("raise self"), :output => @str_output, :exception_handler => proc { was_called = true }) pry_tester.rep(o) was_called.should == true end it 'should not try to catch intended exceptions' do lambda { mock_pry("raise SystemExit") }.should.raise SystemExit # SIGTERM lambda { mock_pry("raise SignalException.new(15)") }.should.raise SignalException end end describe "repl" do describe "basic functionality" do it 'should set an ivar on an object and exit the repl' do input_strings = ["@x = 10", "exit-all"] input = InputTester.new(*input_strings) o = Object.new pry_tester = Pry.start(o, :input => input, :output => StringIO.new) o.instance_variable_get(:@x).should == 10 end it 'should preserve newlines correctly with multi-line input' do input_strings = ['@s = <<-END', '1', '', '', '2', 'END'] input = InputTester.new(*input_strings) o = Object.new pry_tester = Pry.start(o, :input => input, :output => StringIO.new) o.instance_variable_get(:@s).should == "1\n\n\n2\n" end end describe "complete_expression?" do it "should not mutate the input!" do clean = "puts <<-FOO\nhi\nFOO\n" a = clean.dup Pry::Code.complete_expression?(a) a.should == clean end end describe "history arrays" do it 'sets _ to the last result' do res = [] input = InputTester.new *[":foo", "self << _", "42", "self << _"] pry = Pry.new(:input => input, :output => StringIO.new) pry.repl(res) res.should == [:foo, 42] end it 'sets out to an array with the result' do res = {} input = InputTester.new *[":foo", "42", "self[:res] = _out_"] pry = Pry.new(:input => input, :output => StringIO.new) pry.repl(res) res[:res].should.be.kind_of Pry::HistoryArray res[:res][1..2].should == [:foo, 42] end it 'sets _in_ to an array with the entered lines' do res = {} input = InputTester.new *[":foo", "42", "self[:res] = _in_"] pry = Pry.new(:input => input, :output => StringIO.new) pry.repl(res) res[:res].should.be.kind_of Pry::HistoryArray res[:res][1..2].should == [":foo\n", "42\n"] end it 'uses 100 as the size of _in_ and _out_' do res = [] input = InputTester.new *["self << _out_.max_size << _in_.max_size"] pry = Pry.new(:input => input, :output => StringIO.new) pry.repl(res) res.should == [100, 100] end it 'can change the size of the history arrays' do res = [] input = InputTester.new *["self << _out_.max_size << _in_.max_size"] pry = Pry.new(:input => input, :output => StringIO.new, :memory_size => 1000) pry.repl(res) res.should == [1000, 1000] end it 'store exceptions' do res = [] input = InputTester.new *["foo!","self << _in_[-1] << _out_[-1]"] pry = Pry.new(:input => input, :output => StringIO.new, :memory_size => 1000) pry.repl(res) res.first.should == "foo!\n" res.last.should.be.kind_of NoMethodError end end describe "last_result" do it "should be set to the most recent value" do pry_eval("2", "_ + 82").should == 84 end # This test needs mock_pry because the command retvals work by # replacing the eval_string, so _ won't be modified without Pry doing # a REPL loop. it "should be set to the result of a command with :keep_retval" do Pry::Commands.block_command '++', '', :keep_retval => true do |a| a.to_i + 1 end mock_pry('++ 86', '++ #{_}').should =~ /88/ end it "should be preserved over an empty line" do pry_eval("2 + 2", " ", "\t", " ", "_ + 92").should == 96 end it "should be preserved when evalling a command without :keep_retval" do pry_eval("2 + 2", "ls -l", "_ + 96").should == 100 end end describe "test loading rc files" do before do Pry::HOME_RC_FILE.replace "spec/fixtures/testrc" Pry::LOCAL_RC_FILE.replace "spec/fixtures/testrc/../testrc" Pry.instance_variable_set(:@initial_session, true) end after do Pry::HOME_RC_FILE.replace "~/.pryrc" Pry::LOCAL_RC_FILE.replace "./.pryrc" Pry.config.should_load_rc = false Object.remove_const(:TEST_RC) if defined?(TEST_RC) end it "should never run the rc file twice" do Pry.config.should_load_rc = true Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) TEST_RC.should == [0] Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) TEST_RC.should == [0] end it "should not load the pryrc if it cannot expand ENV[HOME]" do old_home = ENV['HOME'] old_rc = Pry.config.should_load_rc ENV['HOME'] = nil Pry.config.should_load_rc = true lambda { Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) }.should.not.raise ENV['HOME'] = old_home Pry.config.should_load_rc = old_rc end it "should not run the rc file at all if Pry.config.should_load_rc is false" do Pry.config.should_load_rc = false Pry.start(self, :input => StringIO.new("exit-all\n"), :output => StringIO.new) Object.const_defined?(:TEST_RC).should == false end it "should not load the rc file if #repl method invoked" do Pry.config.should_load_rc = true Pry.new(:input => StringIO.new("exit-all\n"), :output => StringIO.new).repl(self) Object.const_defined?(:TEST_RC).should == false Pry.config.should_load_rc = false end describe "that raise exceptions" do before do Pry::HOME_RC_FILE = "spec/fixtures/testrcbad" Pry.config.should_load_rc = true Pry.config.should_load_local_rc = false putsed = nil # YUCK! horrible hack to get round the fact that output is not configured # at the point this message is printed. (class << Pry; self; end).send(:define_method, :puts) { |str| putsed = str } @doing_it = lambda{ Pry.start(self, :input => StringIO.new("Object::TEST_AFTER_RAISE=1\nexit-all\n"), :output => StringIO.new) putsed } end after do Object.remove_const(:TEST_BEFORE_RAISE) Object.remove_const(:TEST_AFTER_RAISE) (class << Pry; undef_method :puts; end) end it "should not raise exceptions" do @doing_it.should.not.raise end it "should continue to run pry" do @doing_it[] Object.const_defined?(:TEST_BEFORE_RAISE).should == true Object.const_defined?(:TEST_AFTER_RAISE).should == true end it "should output an error" do @doing_it.call.split("\n").first.should == "Error loading spec/fixtures/testrcbad: messin with ya" end end end describe "nesting" do after do Pry.reset_defaults Pry.color = false end it 'should nest properly' do Pry.input = InputTester.new("cd 1", "cd 2", "cd 3", "\"nest:\#\{(_pry_.binding_stack.size - 1)\}\"", "exit-all") Pry.output = @str_output o = Object.new pry_tester = o.pry @str_output.string.should =~ /nest:3/ end end describe "defining methods" do it 'should define a method on the singleton class of an object when performing "def meth;end" inside the object' do [Object.new, {}, []].each do |val| str_input = StringIO.new("def hello;end") Pry.new(:input => str_input, :output => StringIO.new).rep(val) val.methods(false).map(&:to_sym).include?(:hello).should == true end end it 'should define an instance method on the module when performing "def meth;end" inside the module' do str_input = StringIO.new("def hello;end") hello = Module.new Pry.new(:input => str_input, :output => StringIO.new).rep(hello) hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true end it 'should define an instance method on the class when performing "def meth;end" inside the class' do str_input = StringIO.new("def hello;end") hello = Class.new Pry.new(:input => str_input, :output => StringIO.new).rep(hello) hello.instance_methods(false).map(&:to_sym).include?(:hello).should == true end it 'should define a method on the class of an object when performing "def meth;end" inside an immediate value or Numeric' do # should include float in here, but test fails for some reason # on 1.8.7, no idea why! [:test, 0, true, false, nil].each do |val| str_input = StringIO.new("def hello;end") Pry.new(:input => str_input, :output => StringIO.new).rep(val) val.class.instance_methods(false).map(&:to_sym).include?(:hello).should == true end end end describe "Object#pry" do after do Pry.reset_defaults Pry.color = false end it "should start a pry session on the receiver (first form)" do Pry.input = InputTester.new("self", "exit-all") str_output = StringIO.new Pry.output = str_output 20.pry str_output.string.should =~ /20/ end it "should start a pry session on the receiver (second form)" do Pry.input = InputTester.new("self", "exit-all") str_output = StringIO.new Pry.output = str_output pry 20 str_output.string.should =~ /20/ end it "should raise if more than two arguments are passed to Object#pry" do lambda { pry(20, :quiet, :input => Readline) }.should.raise ArgumentError end end describe "Pry.binding_for" do it 'should return TOPLEVEL_BINDING if parameter self is main' do _main_ = lambda { TOPLEVEL_BINDING.eval('self') } Pry.binding_for(_main_.call).is_a?(Binding).should == true Pry.binding_for(_main_.call).should == TOPLEVEL_BINDING Pry.binding_for(_main_.call).should == Pry.binding_for(_main_.call) end end end end describe 'setting custom options' do it 'should not raise for unrecognized options' do should.not.raise?(NoMethodError) { instance = Pry.new(:custom_option => 'custom value') } end end end pry-0.9.12.6/spec/pry_history_spec.rb0000644000004100000410000000461312272154173017505 0ustar www-datawww-datarequire 'helper' require 'tempfile' describe Pry do before do Pry.history.clear @saved_history = "1\n2\n3\n" Pry.history.loader = proc do |&blk| @saved_history.lines.each { |l| blk.call(l) } end Pry.history.saver = proc do |lines| @saved_history << lines.map { |l| "#{l}\n" }.join end Pry.load_history end after do Pry.history.clear Pry.history.restore_default_behavior end describe '#push' do it "should not record duplicated lines" do Pry.history << '3' Pry.history << '_ += 1' Pry.history << '_ += 1' Pry.history.to_a.grep('_ += 1').count.should == 1 end it "should not record empty lines" do c = Pry.history.to_a.count Pry.history << '' Pry.history.to_a.count.should == c end end describe ".load_history" do it "should read the contents of the file" do Pry.history.to_a[-2..-1].should == %w(2 3) end end describe ".save_history" do it "should include a trailing newline" do Pry.history << "4" Pry.save_history @saved_history.should =~ /4\n\z/ end it "should not change anything if history is not changed" do @saved_history = "4\n5\n6\n" Pry.save_history @saved_history.should == "4\n5\n6\n" end it "should append new lines to the file" do Pry.history << "4" Pry.save_history @saved_history.should == "1\n2\n3\n4\n" end it "should not clobber lines written by other Pry's in the meantime" do Pry.history << "5" @saved_history << "4\n" Pry.save_history Pry.history.to_a[-3..-1].should == ["2", "3", "5"] @saved_history.should == "1\n2\n3\n4\n5\n" end it "should not delete lines from the file if this session's history was cleared" do Pry.history.clear Pry.save_history @saved_history.should == "1\n2\n3\n" end it "should save new lines that are added after the history was cleared" do Pry.history.clear Pry.history << "4" Pry.save_history @saved_history.should =~ /1\n2\n3\n4\n/ end it "should only append new lines the second time it is saved" do Pry.history << "4" Pry.save_history @saved_history << "5\n" Pry.history << "6" Pry.save_history Pry.history.to_a[-4..-1].should == ["2", "3", "4", "6"] @saved_history.should == "1\n2\n3\n4\n5\n6\n" end end end pry-0.9.12.6/spec/exception_whitelist_spec.rb0000644000004100000410000000133612272154173021203 0ustar www-datawww-datarequire 'helper' describe "Pry.config.exception_whitelist" do before do @str_output = StringIO.new end it 'should rescue all exceptions NOT specified on whitelist' do Pry.config.exception_whitelist.include?(NameError).should == false lambda { Pry.start(self, :input => StringIO.new("raise NameError\nexit"), :output => @str_output) }.should.not.raise NameError end it 'should NOT rescue exceptions specified on whitelist' do old_whitelist = Pry.config.exception_whitelist Pry.config.exception_whitelist = [NameError] lambda { Pry.start(self, :input => StringIO.new("raise NameError"), :output => @str_output) }.should.raise NameError Pry.config.exception_whitelist = old_whitelist end end pry-0.9.12.6/spec/code_object_spec.rb0000644000004100000410000001710712272154172017353 0ustar www-datawww-datarequire 'helper' describe Pry::CodeObject do describe "basic lookups" do before do @obj = Object.new def @obj.ziggy "a flight of scarlet pigeons thunders round my thoughts" end class ClassyWassy def piggy binding end end @p = Pry.new @p.binding_stack = [binding] end after do Object.remove_const(:ClassyWassy) end it 'should lookup methods' do m = Pry::CodeObject.lookup("@obj.ziggy", @p) m.is_a?(Pry::Method).should == true m.name.to_sym.should == :ziggy end it 'should lookup modules' do m = Pry::CodeObject.lookup("ClassyWassy", @p) m.is_a?(Pry::WrappedModule).should == true m.source.should =~ /piggy/ end it 'should lookup procs' do my_proc = proc { :hello } @p.binding_stack = [binding] m = Pry::CodeObject.lookup("my_proc", @p) m.is_a?(Pry::Method).should == true m.source.should =~ /hello/ end describe 'commands lookup' do before do @p = Pry.new @p.binding_stack = [binding] end it 'should return command class' do @p.commands.command "jeremy-jones" do "lobster" end m = Pry::CodeObject.lookup("jeremy-jones", @p) (m <= Pry::Command).should == true m.source.should =~ /lobster/ end describe "class commands" do before do class LobsterLady < Pry::ClassCommand match "lobster-lady" description "nada." def process "lobster" end end end after do Object.remove_const(:LobsterLady) end it 'should return Pry::ClassCommand class when looking up class command' do Pry.commands.add_command(LobsterLady) m = Pry::CodeObject.lookup("lobster-lady", @p) (m <= Pry::ClassCommand).should == true m.source.should =~ /class LobsterLady/ Pry.commands.delete("lobster-lady") end it 'should return Pry::WrappedModule when looking up command class directly (as a class, not as a command)' do Pry.commands.add_command(LobsterLady) m = Pry::CodeObject.lookup("LobsterLady", @p) m.is_a?(Pry::WrappedModule).should == true m.source.should =~ /class LobsterLady/ Pry.commands.delete("lobster-lady") end end it 'looks up commands by :listing name as well' do @p.commands.command /jeremy-.*/, "", :listing => "jeremy-baby" do "lobster" end m = Pry::CodeObject.lookup("jeremy-baby", @p) (m <= Pry::Command).should == true m.source.should =~ /lobster/ end it 'finds nothing when passing nil as the first argument' do Pry::CodeObject.lookup(nil, @p).should == nil end end it 'should lookup instance methods defined on classes accessed via local variable' do o = Class.new do def princess_bubblegum "mathematic!" end end @p.binding_stack = [binding] m = Pry::CodeObject.lookup("o#princess_bubblegum", @p) m.is_a?(Pry::Method).should == true m.source.should =~ /mathematic!/ end it 'should lookup class methods defined on classes accessed via local variable' do o = Class.new do def self.finn "4 realzies" end end @p.binding_stack = [binding] m = Pry::CodeObject.lookup("o.finn", @p) m.is_a?(Pry::Method).should == true m.source.should =~ /4 realzies/ end it 'should lookup the class of an object (when given a variable)' do moddy = ClassyWassy.new @p.binding_stack = [binding] m = Pry::CodeObject.lookup("moddy", @p) m.is_a?(Pry::WrappedModule).should == true m.source.should =~ /piggy/ end describe "inferring object from binding when lookup str is empty/nil" do before do @b1 = Pry.binding_for(ClassyWassy) @b2 = Pry.binding_for(ClassyWassy.new) end describe "infer module objects" do it 'should infer module object when binding self is a module' do ["", nil].each do |v| @p.binding_stack = [@b1] m = Pry::CodeObject.lookup(v, @p) m.is_a?(Pry::WrappedModule).should == true m.name.should =~ /ClassyWassy/ end end it 'should infer module object when binding self is an instance' do ["", nil].each do |v| @p.binding_stack = [@b2] m = Pry::CodeObject.lookup(v, @p) m.is_a?(Pry::WrappedModule).should == true m.name.should =~ /ClassyWassy/ end end end describe "infer method objects" do it 'should infer method object from binding when inside method context' do b = ClassyWassy.new.piggy ["", nil].each do |v| @p.binding_stack = [b] m = Pry::CodeObject.lookup(v, @p) m.is_a?(Pry::Method).should == true m.name.should =~ /piggy/ end end end end end describe "lookups with :super" do before do class MyClassyWassy; end class CuteSubclass < MyClassyWassy; end @p = Pry.new @p.binding_stack = [binding] end after do Object.remove_const(:MyClassyWassy) Object.remove_const(:CuteSubclass) end it 'should lookup original class with :super => 0' do m = Pry::CodeObject.lookup("CuteSubclass", @p, :super => 0) m.is_a?(Pry::WrappedModule).should == true m.wrapped.should == CuteSubclass end it 'should lookup immediate super class with :super => 1' do m = Pry::CodeObject.lookup("CuteSubclass", @p, :super => 1) m.is_a?(Pry::WrappedModule).should == true m.wrapped.should == MyClassyWassy end it 'should ignore :super parameter for commands' do p = Pry.new p.commands.command "jeremy-jones" do "lobster" end p.binding_stack = [binding] m = Pry::CodeObject.lookup("jeremy-jones", p, :super => 10) m.source.should =~ /lobster/ end end describe "precedence" do before do class ClassyWassy class Puff def tiggy end end def Puff end def piggy end end Object.class_eval do def ClassyWassy :ducky end end @p = Pry.new @p.binding_stack = [binding] end after do Object.remove_const(:ClassyWassy) Object.remove_method(:ClassyWassy) end it 'should look up methods before classes (at top-level)' do m = Pry::CodeObject.lookup("ClassyWassy", @p) m.is_a?(Pry::Method).should == true m.source.should =~ /ducky/ end it 'should look up classes before methods when namespaced' do m = Pry::CodeObject.lookup("ClassyWassy::Puff", @p) m.is_a?(Pry::WrappedModule).should == true m.source.should =~ /tiggy/ end it 'should look up locals before methods' do b = Pry.binding_for(ClassyWassy) b.eval("piggy = Puff.new") @p.binding_stack = [b] o = Pry::CodeObject.lookup("piggy", @p) o.is_a?(Pry::WrappedModule).should == true end # actually locals are never looked up (via co.default_lookup) when they're classes, it # just falls through to co.method_or_class it 'should look up classes before locals' do c = ClassyWassy @p.binding_stack = [binding] o = Pry::CodeObject.lookup("c", @p) o.is_a?(Pry::WrappedModule).should == true o.wrapped.should == ClassyWassy end end end pry-0.9.12.6/spec/history_array_spec.rb0000644000004100000410000000310712272154173020006 0ustar www-datawww-datarequire 'helper' describe Pry::HistoryArray do before do @array = Pry::HistoryArray.new 10 @populated = @array.dup << 1 << 2 << 3 << 4 end it 'should have a maximum size specifed at creation time' do @array.max_size.should == 10 end it 'should be able to be added objects to' do @populated.size.should == 4 @populated.to_a.should == [1, 2, 3, 4] end it 'should be able to access single elements' do @populated[2].should == 3 end it 'should be able to access negative indices' do @populated[-1].should == 4 end it 'should be able to access ranges' do @populated[1..2].should == [2, 3] end it 'should be able to access ranges starting from a negative index' do @populated[-2..3].should == [3, 4] end it 'should be able to access ranges ending at a negative index' do @populated[2..-1].should == [3, 4] end it 'should be able to access ranges using only negative indices' do @populated[-2..-1].should == [3, 4] end it 'should be able to use range where end is excluded' do @populated[-2...-1].should == [3] end it 'should be able to access slices using a size' do @populated[-3, 2].should == [2, 3] end it 'should remove older entries' do 11.times { |n| @array << n } @array[0].should == nil @array[1].should == 1 @array[10].should == 10 end it 'should not be larger than specified maximum size' do 12.times { |n| @array << n } @array.entries.compact.size.should == 10 end it 'should pop!' do @populated.pop! @populated.to_a.should == [1, 2, 3] end end pry-0.9.12.6/spec/commands/0000755000004100000410000000000012272154173015350 5ustar www-datawww-datapry-0.9.12.6/spec/commands/whereami_spec.rb0000644000004100000410000001251512272154173020514 0ustar www-datawww-datarequire 'helper' describe "whereami" do it 'should work with methods that have been undefined' do class Cor def blimey! Cor.send :undef_method, :blimey! Pad.binding = binding end end Cor.new.blimey! # using [.] so the regex doesn't match itself pry_eval(Pad.binding, 'whereami').should =~ /self[.]blimey!/ Object.remove_const(:Cor) end it 'should work in objects with no method methods' do class Cor def blimey! pry_eval(binding, 'whereami').should =~ /Cor[#]blimey!/ end def method; "moo"; end end Cor.new.blimey! Object.remove_const(:Cor) end it 'should properly set _file_, _line_ and _dir_' do class Cor def blimey! pry_eval(binding, 'whereami', '_file_'). should == File.expand_path(__FILE__) end end Cor.new.blimey! Object.remove_const(:Cor) end if defined?(BasicObject) it 'should work in BasicObjects' do cor = Class.new(BasicObject) do def blimey! ::Kernel.binding # omnom end end.new.blimey! pry_eval(cor, 'whereami').should =~ /::Kernel.binding [#] omnom/ end end it 'should show description and correct code when __LINE__ and __FILE__ are outside @method.source_location' do class Cor def blimey! eval <<-END, binding, "spec/fixtures/example.erb", 1 pry_eval(binding, 'whereami') END end end Cor.instance_method(:blimey!).source.should =~ /pry_eval/ Cor.new.blimey!.should =~ /Cor#blimey!.*Look at me/m Object.remove_const(:Cor) end it 'should show description and correct code when @method.source_location would raise an error' do class Cor eval <<-END, binding, "spec/fixtures/example.erb", 1 def blimey! pry_eval(binding, 'whereami') end END end lambda{ Cor.instance_method(:blimey!).source }.should.raise(MethodSource::SourceNotFoundError) Cor.new.blimey!.should =~ /Cor#blimey!.*Look at me/m Object.remove_const(:Cor) end # Now that we use stagger_output (paging output) we no longer get # the "From: " line, as we output everything in one go (not separate output.puts) # and so the user just gets a single `Error: Cannot open # "not.found.file.erb" for reading.` # which is good enough IMO. Unfortunately we can't test for it # though, as we don't hook stdout. # # it 'should display a description and error if reading the file goes wrong' do # class Cor # def blimey! # eval <<-END, binding, "not.found.file.erb", 7 # Pad.tester = pry_tester(binding) # Pad.tester.eval('whereami') # END # end # end # proc { Cor.new.blimey! }.should.raise(MethodSource::SourceNotFoundError) # Pad.tester.last_output.should =~ # /From: not.found.file.erb @ line 7 Cor#blimey!:/ # Object.remove_const(:Cor) # end it 'should show code window (not just method source) if parameter passed to whereami' do class Cor def blimey! pry_eval(binding, 'whereami 3').should =~ /class Cor/ end end Cor.new.blimey! Object.remove_const(:Cor) end it 'should show entire method when -m option used' do old_size, Pry.config.default_window_size = Pry.config.default_window_size, 1 old_cutoff, Pry::Command::Whereami.method_size_cutoff = Pry::Command::Whereami.method_size_cutoff, 1 class Cor def blimey! 1 2 pry_eval(binding, 'whereami -m').should =~ /def blimey/ end end Pry::Command::Whereami.method_size_cutoff, Pry.config.default_window_size = old_cutoff, old_size Cor.new.blimey! Object.remove_const(:Cor) end it 'should show entire file when -f option used' do class Cor def blimey! 1 2 pry_eval(binding, 'whereami -f').should =~ /show entire file when -f option used/ end end Cor.new.blimey! Object.remove_const(:Cor) end it 'should show class when -c option used, and locate correct candidate' do require 'fixtures/whereami_helper' class Cor def blimey! 1 2 out = pry_eval(binding, 'whereami -c') out.should =~ /class Cor/ out.should =~ /blimey/ end end Cor.new.blimey! Object.remove_const(:Cor) end it 'should not show line numbers or marker when -n switch is used' do class Cor def blimey! out = pry_eval(binding, 'whereami -n') out.should =~ /^\s*def/ out.should.not =~ /\=\>/ end end Cor.new.blimey! Object.remove_const(:Cor) end it 'should use Pry.config.default_window_size for window size when outside a method context' do old_size, Pry.config.default_window_size = Pry.config.default_window_size, 1 :litella :pig out = pry_eval(binding, 'whereami') :punk :sanders out.should.not =~ /:litella/ out.should =~ /:pig/ out.should =~ /:punk/ out.should.not =~ /:sanders/ Pry.config.default_window_size = old_size end it "should work at the top level" do pry_eval(Pry.toplevel_binding, 'whereami').should =~ /At the top level/ end it "should work inside a class" do pry_eval(Pry, 'whereami').should =~ /Inside Pry/ end it "should work inside an object" do pry_eval(Object.new, 'whereami').should =~ /Inside # "foo" do; end pry_eval('help foo').should =~ /Test listing/ end it 'should display help for a command with a spaces in its name' do @set.command "cmd with spaces", "desc of a cmd with spaces" do; end pry_eval('help "cmd with spaces"').should =~ /desc of a cmd with spaces/ end it 'should display help for all commands with a description' do @set.command /bar(.*)/, "Test listing", :listing => "foo" do; end @set.command "b", "description for b", :listing => "foo" do; end @set.command "c" do;end @set.command "d", "" do;end output = pry_eval('help') output.should =~ /Test listing/ output.should =~ /description for b/ output.should =~ /No description/ end it "should sort the output of the 'help' command" do @set.command 'faa', "Fooerizes" do; end @set.command 'gaa', "Gooerizes" do; end @set.command 'maa', "Mooerizes" do; end @set.command 'baa', "Booerizes" do; end doc = pry_eval('help') order = [doc.index("baa"), doc.index("faa"), doc.index("gaa"), doc.index("maa")] order.should == order.sort end end pry-0.9.12.6/spec/commands/gist_spec.rb0000644000004100000410000000413012272154172017652 0ustar www-datawww-data# These tests are out of date. # THey need to be updated for the new 'gist' API, but im too sleepy to # do that now. require 'helper' describe 'gist' do it 'has a dependency on the jist gem' do Pry::Command::Gist.command_options[:requires_gem].should == "jist" end end # before do # Pad.jist_calls = {} # end # # In absence of normal mocking, just monkeysmash these with no undoing after. # module Jist # class << self # def login!; Pad.jist_calls[:login!] = true end # def gist(*args) # Pad.jist_calls[:gist_args] = args # {'html_url' => 'http://gist.blahblah'} # end # def copy(content); Pad.jist_calls[:copy_args] = content end # end # end # module Pry::Gist # # a) The actual require fails for jruby for some odd reason. # # b) 100% of jist should be stubbed by the above, so this ensures that. # def self.require_jist; 'nope' end # end # it 'nominally logs in' do # pry_eval 'gist --login' # Pad.jist_calls[:login!].should.not.be.nil # end # EXAMPLE_REPL_METHOD = <<-EOT # # docdoc # def my_method # # line 1 # 'line 2' # line 3 # Line.four # end # EOT # RANDOM_COUPLE_OF_LINES = %w(a=1 b=2) # run_case = proc do |sym| # actual_command = Pry::Gist.example_code(sym) # pry_eval EXAMPLE_REPL_METHOD, RANDOM_COUPLE_OF_LINES, actual_command # end # it 'deduces filenames' do # Pry::Gist::INVOCATIONS.keys.each do |e| # run_case.call(e) # if Pad.jist_calls[:gist_args] # text, args = Pad.jist_calls[:gist_args] # args[:filename].should.not == '(pry)' # end # Pad.jist_calls[:copy_args].should.not.be.nil # end # end # it 'equates aliae' do # run_case.call(:clipit).should == run_case.call(:cliponly) # run_case.call(:jist).should == run_case.call(:class) # end # it 'has a reasonable --help' do # help = pry_eval('gist --help') # Pry::Gist::INVOCATIONS.keys.each do |e| # help.should.include? Pry::Gist.example_code(e) # help.should.include? Pry::Gist.example_description(e) # end # end # end pry-0.9.12.6/spec/commands/exit_all_spec.rb0000644000004100000410000000161212272154172020507 0ustar www-datawww-datarequire 'helper' describe "exit-all" do it 'should break out of the repl loop of Pry instance and return nil' do pry_tester(0).simulate_repl do |t| t.eval 'exit-all' end.should == nil end it 'should break out of the repl loop of Pry instance wth a user specified value' do pry_tester(0).simulate_repl do |t| t.eval "exit-all 'message'" end.should == 'message' end it 'should break of the repl loop even if multiple bindings still on stack' do pry_tester(0).simulate_repl do |t| t.eval 'cd 1', 'cd 2', "exit-all 'message'" end.should == 'message' end it 'binding_stack should be empty after breaking out of the repl loop' do t = pry_tester(0) do def binding_stack @pry.binding_stack end end t.simulate_repl do |t| t.eval 'cd 1', 'cd 2', 'exit-all' end t.binding_stack.empty?.should == true end end pry-0.9.12.6/spec/commands/raise_up_spec.rb0000644000004100000410000000351612272154173020523 0ustar www-datawww-datarequire 'helper' describe "raise-up" do before do @self = "Pad.self = self" @inner = "Pad.inner = self" @outer = "Pad.outer = self" end after do Pad.clear end it "should raise the exception with raise-up" do redirect_pry_io(InputTester.new("raise NoMethodError", "raise-up NoMethodError")) do lambda { Pry.new.repl(0) }.should.raise NoMethodError end end it "should raise an unamed exception with raise-up" do redirect_pry_io(InputTester.new("raise 'stop'","raise-up 'noreally'")) do lambda { Pry.new.repl(0) }.should.raise RuntimeError, "noreally" end end it "should eat the exception at the last new pry instance on raise-up" do redirect_pry_io(InputTester.new(":inner.pry", "raise NoMethodError", @inner, "raise-up NoMethodError", @outer, "exit-all")) do Pry.start(:outer) end Pad.inner.should == :inner Pad.outer.should == :outer end it "should raise the most recently raised exception" do lambda { mock_pry("raise NameError, 'homographery'","raise-up") }.should.raise NameError, 'homographery' end it "should allow you to cd up and (eventually) out" do redirect_pry_io(InputTester.new("cd :inner", "raise NoMethodError", @inner, "deep = :deep", "cd deep","Pad.deep = self", "raise-up NoMethodError", "raise-up", @outer, "raise-up", "exit-all")) do lambda { Pry.start(:outer) }.should.raise NoMethodError end Pad.deep.should == :deep Pad.inner.should == :inner Pad.outer.should == :outer end it "should jump immediately out of nested contexts with !" do lambda { mock_pry("cd 1", "cd 2", "cd 3", "raise-up! 'fancy that...'") }.should.raise RuntimeError, 'fancy that...' end end pry-0.9.12.6/spec/commands/show_doc_spec.rb0000644000004100000410000003631612272154173020525 0ustar www-datawww-datarequire 'helper' require "fixtures/show_source_doc_examples" if !PryTestHelpers.mri18_and_no_real_source_location? describe "show-doc" do before do @o = Object.new # sample doc def @o.sample_method :sample end end it 'should output a method\'s documentation' do pry_eval(binding, "show-doc @o.sample_method").should =~ /sample doc/ end it 'should output a method\'s documentation with line numbers' do pry_eval(binding, "show-doc @o.sample_method -l").should =~ /\d: sample doc/ end it 'should output a method\'s documentation with line numbers (base one)' do pry_eval(binding, "show-doc @o.sample_method -b").should =~ /1: sample doc/ end it 'should output a method\'s documentation if inside method without needing to use method name' do # sample comment def @o.sample pry_eval(binding, 'show-doc').should =~ /sample comment/ end @o.sample end it "should be able to find super methods" do b = Class.new{ # daddy initialize! def initialize(*args) ;end } c = Class.new(b){ # classy initialize! def initialize(*args); end } d = Class.new(c){ # grungy initialize?? def initialize(*args, &block); end } o = d.new # instancey initialize! def o.initialize; end t = pry_tester(binding) t.eval("show-doc o.initialize").should =~ /instancey initialize/ t.eval("show-doc --super o.initialize").should =~ /grungy initialize/ t.eval("show-doc o.initialize -ss").should =~ /classy initialize/ t.eval("show-doc o.initialize -sss").should =~ /daddy initialize/ end describe "rdoc highlighting" do it "should syntax highlight code in rdoc" do c = Class.new{ # This can initialize your class: # # a = c.new :foo # # @param foo def initialize(foo); end } begin t = pry_tester(binding) t.eval("show-doc c#initialize").should =~ /c.new :foo/ Pry.config.color = true # I don't want the test to rely on which colour codes are there, just to # assert that "something" is being colourized. t.eval("show-doc c#initialize").should.not =~ /c.new :foo/ ensure Pry.config.color = false end end it "should syntax highlight `code` in rdoc" do c = Class.new{ # After initializing your class with `c.new(:foo)`, go have fun! # # @param foo def initialize(foo); end } begin t = pry_tester(binding) t.eval("show-doc c#initialize").should =~ /c.new\(:foo\)/ Pry.config.color = true # I don't want the test to rely on which colour codes are there, just to # assert that "something" is being colourized. t.eval("show-doc c#initialize").should.not =~ /c.new\(:foo\)/ ensure Pry.config.color = false end end it "should not syntax highlight `` inside code" do c = Class.new{ # Convert aligned output (from many shell commands) into nested arrays: # # a = decolumnize `ls -l $HOME` # # @param output def decolumnize(output); end } begin t = pry_tester(binding) Pry.config.color = true t.eval("show-doc c#decolumnize").should =~ /ls -l \$HOME/ t.eval("show-doc c#decolumnize").should.not =~ /`ls -l \$HOME`/ ensure Pry.config.color = false end end end describe "on sourcable objects" do it "should show documentation for object" do # this is a documentation hello = proc { puts 'hello world!' } mock_pry(binding, "show-doc hello").should =~ /this is a documentation/ end end describe "on modules" do before do # god this is boring1 class ShowSourceTestClass def alpha end end # god this is boring2 module ShowSourceTestModule def alpha end end # god this is boring3 ShowSourceTestClassWeirdSyntax = Class.new do def beta end end # god this is boring4 ShowSourceTestModuleWeirdSyntax = Module.new do def beta end end end after do Object.remove_const :ShowSourceTestClass Object.remove_const :ShowSourceTestClassWeirdSyntax Object.remove_const :ShowSourceTestModule Object.remove_const :ShowSourceTestModuleWeirdSyntax end describe "basic functionality, should show docs for top-level module definitions" do it 'should show docs for a class' do pry_eval("show-doc ShowSourceTestClass").should =~ /god this is boring1/ end it 'should show docs for a module' do pry_eval("show-doc ShowSourceTestModule").should =~ /god this is boring2/ end it 'should show docs for a class when Const = Class.new syntax is used' do pry_eval("show-doc ShowSourceTestClassWeirdSyntax").should =~ /god this is boring3/ end it 'should show docs for a module when Const = Module.new syntax is used' do pry_eval("show-doc ShowSourceTestModuleWeirdSyntax").should =~ /god this is boring4/ end end if !Pry::Helpers::BaseHelpers.mri_18? describe "in REPL" do it 'should find class defined in repl' do t = pry_tester t.eval <<-RUBY # hello tobina class TobinaMyDog def woof end end RUBY t.eval('show-doc TobinaMyDog').should =~ /hello tobina/ Object.remove_const :TobinaMyDog end end end it 'should lookup module name with respect to current context' do constant_scope(:AlphaClass, :BetaClass) do # top-level beta class BetaClass def alpha end end class AlphaClass # nested beta class BetaClass def beta end end end pry_eval(AlphaClass, "show-doc BetaClass").should =~ /nested beta/ end end it 'should look up nested modules' do constant_scope(:AlphaClass) do class AlphaClass # nested beta class BetaClass def beta end end end pry_eval("show-doc AlphaClass::BetaClass").should =~ /nested beta/ end end describe "show-doc -a" do it 'should show the docs for all monkeypatches defined in different files' do # local monkeypatch class TestClassForShowSource def beta end end result = pry_eval("show-doc TestClassForShowSource -a") result.should =~ /used by/ result.should =~ /local monkeypatch/ end describe "messages relating to -a" do it 'indicates all available monkeypatches can be shown with -a when (when -a not used and more than one candidate exists for class)' do class TestClassForShowSource def beta end end result = pry_eval('show-doc TestClassForShowSource') result.should =~ /available monkeypatches/ end it 'shouldnt say anything about monkeypatches when only one candidate exists for selected class' do class Aarrrrrghh def o;end end result = pry_eval('show-doc Aarrrrrghh') result.should.not =~ /available monkeypatches/ Object.remove_const(:Aarrrrrghh) end end end describe "when no class/module arg is given" do before do module TestHost # hello there froggy module M def d; end def e; end end end end after do Object.remove_const(:TestHost) end it 'should return doc for current module' do pry_eval(TestHost::M, "show-doc").should =~ /hello there froggy/ end end # FIXME: THis is nto a good spec anyway, because i dont think it # SHOULD skip! describe "should skip over broken modules" do before do module TestHost # hello module M binding.eval("def a; end", "dummy.rb", 1) binding.eval("def b; end", "dummy.rb", 2) binding.eval("def c; end", "dummy.rb", 3) end # goodbye module M def d; end def e; end end end end after do Object.remove_const(:TestHost) end it 'should return doc for first valid module' do result = pry_eval("show-doc TestHost::M") result.should =~ /goodbye/ result.should.not =~ /hello/ end end end describe "on commands" do # mostly copied & modified from test_help.rb before do @oldset = Pry.config.commands @set = Pry.config.commands = Pry::CommandSet.new do import Pry::Commands end end after do Pry.config.commands = @oldset end it 'should display help for a specific command' do pry_eval('show-doc ls').should =~ /Usage: ls/ end it 'should display help for a regex command with a "listing"' do @set.command /bar(.*)/, "Test listing", :listing => "foo" do; end pry_eval('show-doc foo').should =~ /Test listing/ end it 'should display help for a command with a spaces in its name' do @set.command "command with spaces", "description of a command with spaces" do; end pry_eval('show-doc command with spaces').should =~ /description of a command with spaces/ end describe "class commands" do before do # pretty pink pincers class LobsterLady < Pry::ClassCommand match "lobster-lady" description "nada." def process "lobster" end end Pry.commands.add_command(LobsterLady) end after do Object.remove_const(:LobsterLady) end it 'should display "help" when looking up by command name' do pry_eval('show-doc lobster-lady').should =~ /nada/ Pry.commands.delete("lobster-lady") end it 'should display actual preceding comment for a class command, when class is used (rather than command name) when looking up' do pry_eval('show-doc LobsterLady').should =~ /pretty pink pincers/ Pry.commands.delete("lobster-lady") end end end describe "should set _file_ and _dir_" do it 'should set _file_ and _dir_ to file containing method source' do t = pry_tester t.process_command "show-doc TestClassForShowSource#alpha" t.pry.last_file.should =~ /show_source_doc_examples/ t.pry.last_dir.should =~ /fixtures/ end end unless Pry::Helpers::BaseHelpers.rbx? describe "can't find class docs" do describe "for classes" do before do module Jesus class Brian; end # doink-doc class Jingle def a; :doink; end end class Jangle < Jingle; end class Bangle < Jangle; end end end after do Object.remove_const(:Jesus) end it 'shows superclass doc' do t = pry_tester t.process_command "show-doc Jesus::Jangle" t.last_output.should =~ /doink-doc/ end it 'errors when class has no superclass to show' do t = pry_tester lambda { t.process_command "show-doc Jesus::Brian" }.should.raise(Pry::CommandError).message. should =~ /Couldn't locate/ end it 'shows warning when reverting to superclass docs' do t = pry_tester t.process_command "show-doc Jesus::Jangle" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Jangle.*Showing.*Jesus::Jingle instead/ end it 'shows nth level superclass docs (when no intermediary superclasses have code either)' do t = pry_tester t.process_command "show-doc Jesus::Bangle" t.last_output.should =~ /doink-doc/ end it 'shows correct warning when reverting to nth level superclass' do t = pry_tester t.process_command "show-doc Jesus::Bangle" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Bangle.*Showing.*Jesus::Jingle instead/ end end describe "for modules" do before do module Jesus # alpha-doc module Alpha def alpha; :alpha; end end module Zeta; end module Beta include Alpha end module Gamma include Beta end end end after do Object.remove_const(:Jesus) end it 'shows included module doc' do t = pry_tester t.process_command "show-doc Jesus::Beta" t.last_output.should =~ /alpha-doc/ end it 'shows warning when reverting to included module doc' do t = pry_tester t.process_command "show-doc Jesus::Beta" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Beta.*Showing.*Jesus::Alpha instead/ end it 'errors when module has no included module to show' do t = pry_tester lambda { t.process_command "show-source Jesus::Zeta" }.should.raise(Pry::CommandError).message. should =~ /Couldn't locate/ end it 'shows nth level included module doc (when no intermediary modules have code either)' do t = pry_tester t.process_command "show-doc Jesus::Gamma" t.last_output.should =~ /alpha-doc/ end it 'shows correct warning when reverting to nth level included module' do t = pry_tester t.process_command "show-source Jesus::Gamma" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Gamma.*Showing.*Jesus::Alpha instead/ end end end end end end pry-0.9.12.6/spec/commands/amend_line_spec.rb0000644000004100000410000001203712272154172021004 0ustar www-datawww-datarequire 'helper' describe "amend-line" do before do @t = pry_tester end it 'should amend the last line of input when no line number specified' do eval_str = unindent(<<-STR) def hello puts :bing STR @t.process_command 'amend-line puts :blah', eval_str eval_str.should == unindent(<<-STR) def hello puts :blah STR end it 'should amend the specified line of input when line number given' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang STR @t.process_command 'amend-line 1 def goodbye', eval_str eval_str.should == unindent(<<-STR) def goodbye puts :bing puts :bang STR end it 'should amend the first line of input when 0 given as line number' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang STR @t.process_command 'amend-line 0 def goodbye', eval_str eval_str.should == unindent(<<-STR) def goodbye puts :bing puts :bang STR end it 'should amend a specified line when negative number given' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang STR @t.process_command 'amend-line -1 puts :bink', eval_str eval_str.should == unindent(<<-STR) def hello puts :bing puts :bink STR @t.process_command 'amend-line -2 puts :bink', eval_str eval_str.should == unindent(<<-STR) def hello puts :bink puts :bink STR end it 'should amend a range of lines of input when negative numbers given' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang puts :boat STR @t.process_command 'amend-line -3..-2 puts :bink', eval_str eval_str.should == unindent(<<-STR) def hello puts :bink puts :boat STR end it 'should correctly amend the specified line with interpolated text' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang STR @t.process_command 'amend-line puts "#{goodbye}"', eval_str eval_str.should == unindent(<<-'STR') def hello puts :bing puts "#{goodbye}" STR end it 'should display error if nothing to amend' do error = nil begin @t.process_command 'amend-line' rescue Pry::CommandError => e error = e end error.should.not.be.nil error.message.should =~ /No input to amend/ end it 'should correctly amend the specified range of lines' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang puts :heart STR @t.process_command 'amend-line 2..3 puts :bong', eval_str eval_str.should == unindent(<<-STR) def hello puts :bong puts :heart STR end it 'should correctly delete a specific line using the ! for content' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang puts :boast puts :heart STR @t.process_command 'amend-line 3 !', eval_str eval_str.should == unindent(<<-STR) def hello puts :bing puts :boast puts :heart STR end it 'should correctly delete a range of lines using the ! for content' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang puts :boast puts :heart STR @t.process_command 'amend-line 2..4 !', eval_str eval_str.should == unindent(<<-STR) def hello puts :heart STR end it 'should correctly delete the previous line using the ! for content' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang puts :boast puts :heart STR @t.process_command 'amend-line !', eval_str eval_str.should == unindent(<<-STR) def hello puts :bing puts :bang puts :boast STR end it 'should amend the specified range of lines, with numbers < 0 in range' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang puts :boast puts :heart STR @t.process_command 'amend-line 2..-2 puts :bong', eval_str eval_str.should == unindent(<<-STR) def hello puts :bong puts :heart STR end it 'should correctly insert a line before a specified line using >' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang STR @t.process_command 'amend-line 2 > puts :inserted', eval_str eval_str.should == unindent(<<-STR) def hello puts :inserted puts :bing puts :bang STR end it 'should ignore second value of range with > syntax' do eval_str = unindent(<<-STR) def hello puts :bing puts :bang STR @t.process_command 'amend-line 2..21 > puts :inserted', eval_str eval_str.should == unindent(<<-STR) def hello puts :inserted puts :bing puts :bang STR end end pry-0.9.12.6/spec/commands/bang_spec.rb0000644000004100000410000000050712272154172017617 0ustar www-datawww-datarequire 'helper' describe "!" do before do @t = pry_tester end it 'should correctly clear the input buffer ' do eval_str = unindent(<<-STR) def hello puts :bing STR @t.process_command '!', eval_str @t.last_output.should =~ /Input buffer cleared!/ eval_str.should == '' end end pry-0.9.12.6/spec/commands/exit_program_spec.rb0000644000004100000410000000057612272154172021416 0ustar www-datawww-datarequire 'helper' describe "exit-program" do it 'should raise SystemExit' do proc { pry_eval('exit-program') }.should.raise SystemExit end it 'should exit the program with the provided value' do begin pry_eval 'exit-program 66' rescue SystemExit => e e.status.should == 66 else raise "Failed to raise SystemExit" end end end pry-0.9.12.6/spec/commands/exit_spec.rb0000644000004100000410000000172512272154172017664 0ustar www-datawww-datarequire 'helper' describe "exit" do it 'should pop a binding with exit' do pry_tester(:outer).simulate_repl do |t| t.eval 'cd :inner' t.eval('self').should == :inner t.eval 'exit' t.eval('self').should == :outer t.eval 'exit-all' end end it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit' do pry_tester(0).simulate_repl do |t| t.eval 'exit' end.should == nil end it 'should break out of the repl loop of Pry instance when binding_stack has only one binding with exit, and return user-given value' do pry_tester(0).simulate_repl do |t| t.eval 'exit :john' end.should == :john end it 'should break out the repl loop of Pry instance even after an exception in user-given value' do pry_tester(0).simulate_repl do |t| proc { t.eval 'exit = 42' }.should.raise(SyntaxError) t.eval 'exit' end.should == nil end end pry-0.9.12.6/spec/commands/save_file_spec.rb0000644000004100000410000001216712272154173020653 0ustar www-datawww-datarequire 'helper' describe "save-file" do before do @tf = Tempfile.new(["pry", ".py"]) @path = @tf.path @t = pry_tester end after do @tf.close(true) end describe "-f" do it 'should save a file to a file' do temp_file do |f| path = f.path f.puts ":cute_horse" f.flush @t.eval("save-file '#{path}' --to '#{@path}'") File.read(@path).should == File.read(path) end end end describe "-i" do it 'should save input expressions to a file (single expression)' do @t.eval ':horse_nostrils' @t.eval "save-file -i 1 --to '#{@path}'" File.read(@path).should == ":horse_nostrils\n" end it "should display a success message on save" do @t.eval ':horse_nostrils' @t.eval("save-file -i 1 --to '#{@path}'").should =~ /successfully saved/ end it 'should save input expressions to a file (range)' do @t.eval ':or_nostrils', ':sucking_up_all_the_oxygen', ':or_whatever' @t.eval "save-file -i 1..2 --to '#{@path}'" File.read(@path).should == ":or_nostrils\n:sucking_up_all_the_oxygen\n" end it 'should save multi-ranged input expressions' do @t.eval ':or_nostrils', ':sucking_up_all_the_oxygen', ':or_whatever', ':baby_ducks', ':cannot_escape' @t.eval "save-file -i 1..2 -i 4..5 --to '#{@path}'" File.read(@path).should == ":or_nostrils\n:sucking_up_all_the_oxygen\n:baby_ducks\n:cannot_escape\n" end end describe "saving methods" do before do @o = Object.new def @o.baby :baby end def @o.bang :bang end @t = pry_tester(@o) end describe "single method" do it 'should save a method to a file' do @t.eval "save-file --to '#{@path}' baby" File.read(@path).should == Pry::Method.from_obj(@o, :baby).source end it "should display a success message on save" do @t.eval("save-file --to '#{@path}' baby").should =~ /successfully saved/ end it 'should save a method to a file truncated by --lines' do @t.eval "save-file --to '#{@path}' baby --lines 2..4" # must add 1 as first line of method is 1 File.read(@path).should == Pry::Method.from_obj(@o, :baby).source.lines.to_a[1..5].join end end # TODO: do we want to reintroduce this spec?? # # describe "multiple method" do # it 'should save multiple methods to a file' do # @t.eval "save-file #{@path} -m baby -m bang" # File.read(@path).should == Pry::Method.from_obj(@o, :baby).source + # Pry::Method.from_obj(@o, :bang).source # end # it 'should save multiple methods to a file trucated by --lines' do # @t.eval "save-file #{@path} -m baby -m bang --lines 2..-2" # # must add 1 as first line of method is 1 # File.read(@path).should == (Pry::Method.from_obj(@o, :baby).source + # Pry::Method.from_obj(@o, :bang).source).lines.to_a[1..-2].join # end # it 'should save multiple methods to a file trucated by --lines 1 ' \ # '(single parameter, not range)' do # @t.eval "save-file #{@path} -m baby -m bang --lines 1" # # must add 1 as first line of method is 1 # File.read(@path).should == (Pry::Method.from_obj(@o, :baby).source + # Pry::Method.from_obj(@o, :bang).source).lines.to_a[0] # end # end end describe "overwrite by default (no --append)" do it 'should overwrite specified file with new input' do @t.eval ':horse_nostrils' @t.eval "save-file -i 1 --to '#{@path}'" @t.eval ':sucking_up_all_the_oxygen' @t.eval "save-file -i 2 --to '#{@path}'" File.read(@path).should == ":sucking_up_all_the_oxygen\n" end end describe "--append" do it 'should append to end of specified file' do @t.eval ':horse_nostrils' @t.eval "save-file -i 1 --to '#{@path}'" @t.eval ':sucking_up_all_the_oxygen' @t.eval "save-file -i 2 --to '#{@path}' -a" File.read(@path).should == ":horse_nostrils\n:sucking_up_all_the_oxygen\n" end end describe "saving commands" do it 'should save a command to a file' do @t.eval "save-file --to '#{@path}' show-source" cmd_source = Pry.commands["show-source"].source File.read(@path).should == cmd_source end end # TODO: reintroduce these specs at some point? # # describe "combined options" do # before do # @o = Object.new # def @o.baby # :baby # end # @t = pry_tester(@o) # end # it 'should save input cache and a method to a file (in that order)' do # @t.eval ":horse_nostrils" # @t.eval "save-file -i 1 -m baby #{@path}" # File.read(@path).should == ":horse_nostrils\n" + # Pry::Method.from_obj(@o, :baby).source # end # it 'should select a portion to save using --lines' do # @t.eval ":horse_nostrils" # @t.eval "save-file -i 1 -m baby #{@path} --lines 2..-2" # str = ":horse_nostrils\n" + Pry::Method.from_obj(@o, :baby).source # File.read(@path).should == str.lines.to_a[1..-2].join # end # end end pry-0.9.12.6/spec/commands/gem_list_spec.rb0000644000004100000410000000106312272154172020511 0ustar www-datawww-datarequire 'helper' describe "gem-list" do # fixing bug for 1.8 compat it 'should not raise when invoked' do proc { pry_eval(self, 'gem-list') }.should.not.raise end it 'should work arglessly' do list = pry_eval('gem-list') list.should =~ /slop \(/ list.should =~ /bacon \(/ end it 'should find arg' do prylist = pry_eval('gem-list slop') prylist.should =~ /slop \(/ prylist.should.not =~ /bacon/ end it 'should return non-results as silence' do pry_eval('gem-list aoeuoueouaou').should.empty? end end pry-0.9.12.6/spec/commands/play_spec.rb0000644000004100000410000000711312272154172017655 0ustar www-datawww-data# This command needs a TONNE more tests for it, but i can't figure out # how to do them yet, and i really want to release. Sorry. Someone # come along and do a better job. require 'helper' describe "play" do before do @t = pry_tester @eval_str = '' end describe "with an argument" do # can't think of a f*cking way to test this!! describe "implied file" do # it 'should play from the file associated with the current binding' do # # require 'fixtures/play_helper' # end # describe "integer" do # it "should process one line from _pry_.last_file" do # @t.process_command 'play --lines 1', @eval_str # @eval_str.should =~ /bing = :bing\n/ # end # end # describe "range" do # it "should process multiple lines at once from _pry_.last_file" do # @t.process_command 'play --lines 1..3', @eval_str # [/bing = :bing\n/, /bang = :bang\n/, /bong = :bong\n/].each { |str| # @eval_str.should =~ str # } # end end end describe "whatever" do before do @o = Object.new def @o.test_method :test_method_content end end it 'should play documentation with the -d switch' do # @v = 10 # @y = 20 def @o.test_method :test_method_content end pry_tester(@o).process_command 'play -d test_method', @eval_str @eval_str.should == unindent(<<-STR) @v = 10 @y = 20 STR end it 'should restrict -d switch with --lines' do # @x = 0 # @v = 10 # @y = 20 # @z = 30 def @o.test_method :test_method_content end pry_tester(@o).process_command 'play -d test_method --lines 2..3', @eval_str @eval_str.should == unindent(<<-STR) @v = 10 @y = 20 STR end it 'has pretty error messages when -d cant find object' do lambda { @t.process_command "play -d sdfsdf" }.should.raise(Pry::CommandError).message.should.match(/Cannot locate/) end it 'should play a method (a single line)' do pry_tester(@o).process_command 'play test_method --lines 2', @eval_str @eval_str.should == ":test_method_content\n" end it 'should properly reindent lines' do def @o.test_method 'hello world' end pry_tester(@o).process_command 'play test_method --lines 2', @eval_str @eval_str.should == "'hello world'\n" end it 'should APPEND to the input buffer when playing a method line, not replace it' do @eval_str = unindent(<<-STR) def another_test_method STR pry_tester(@o).process_command 'play test_method --lines 2', @eval_str @eval_str.should == unindent(<<-STR) def another_test_method :test_method_content STR end it 'should play a method (multiple lines)' do def @o.test_method @var0 = 10 @var1 = 20 @var2 = 30 @var3 = 40 end pry_tester(@o).process_command 'play test_method --lines 3..4', @eval_str @eval_str.should == unindent(<<-STR, 0) @var1 = 20 @var2 = 30 STR end describe "play -i" do it 'should play multi-ranged input expressions' do a = b = c = d = e = 0 redirect_pry_io(InputTester.new('a += 1', 'b += 1', 'c += 1', 'd += 1', 'e += 1', "play -i 1..3"), StringIO.new) do binding.pry end [a, b, c].all? { |v| v.should == 2 } d.should == 1 end end end end pry-0.9.12.6/spec/commands/ls_spec.rb0000644000004100000410000001425312272154172017331 0ustar www-datawww-datarequire 'helper' describe "ls" do describe "below ceiling" do it "should stop before Object by default" do pry_eval("cd Class.new{ def goo; end }.new", "ls").should.not =~ /Object/ pry_eval("cd Class.new{ def goo; end }", "ls -M").should.not =~ /Object/ end it "should include object if -v is given" do pry_eval("cd Class.new{ def goo; end }.new", "ls -m -v").should =~ /Object/ pry_eval("cd Class.new{ def goo; end }", "ls -vM").should =~ /Object/ end it "should include super-classes by default" do pry_eval( "cd Class.new(Class.new{ def goo; end; public :goo }).new", "ls").should =~ /goo/ pry_eval( "cd Class.new(Class.new{ def goo; end; public :goo })", "ls -M").should =~ /goo/ end it "should not include super-classes when -q is given" do pry_eval("cd Class.new(Class.new{ def goo; end }).new", "ls -q").should.not =~ /goo/ pry_eval("cd Class.new(Class.new{ def goo; end })", "ls -M -q").should.not =~ /goo/ end end describe "help" do it 'should show help with -h' do pry_eval("ls -h").should =~ /Usage: ls/ end end describe "methods" do it "should show public methods by default" do output = pry_eval("ls Class.new{ def goo; end; public :goo }.new") output.should =~ /methods: goo/ end it "should not show protected/private by default" do pry_eval("ls -M Class.new{ def goo; end; private :goo }").should.not =~ /goo/ pry_eval("ls Class.new{ def goo; end; protected :goo }.new").should.not =~ /goo/ end it "should show public methods with -p" do pry_eval("ls -p Class.new{ def goo; end }.new").should =~ /methods: goo/ end it "should show protected/private methods with -p" do pry_eval("ls -pM Class.new{ def goo; end; protected :goo }").should =~ /methods: goo/ pry_eval("ls -p Class.new{ def goo; end; private :goo }.new").should =~ /methods: goo/ end it "should work for objects with an overridden method method" do require 'net/http' # This doesn't actually touch the network, promise! pry_eval("ls Net::HTTP::Get.new('localhost')").should =~ /Net::HTTPGenericRequest#methods/ end end describe 'with -l' do it 'should find locals and sort by descending size' do result = pry_eval("aa = 'asdf'; bb = 'xyz'", 'ls -l') result.should.not =~ /=>/ result.should.not =~ /0x\d{5}/ result.should =~ /asdf.*xyz/m end it 'should not list pry noise' do pry_eval('ls -l').should.not =~ /_(?:dir|file|ex|pry|out|in)_/ end end describe "when inside Modules" do it "should still work" do pry_eval( "cd Module.new{ def foobie; end; public :foobie }", "ls -M").should =~ /foobie/ end it "should work for ivars" do pry_eval( "module StigmaT1sm; def foobie; @@gharble = 456; end; end", "Object.new.tap{ |o| o.extend(StigmaT1sm) }.foobie", "cd StigmaT1sm", "ls -i").should =~ /@@gharble/ end it "should include instance methods by default" do output = pry_eval( "ls Module.new{ def shinanagarns; 4; end; public :shinanagarns }") output.should =~ /shinanagarns/ end it "should behave normally when invoked on Module itself" do pry_eval("ls Module").should.not =~ /Pry/ end end describe "constants" do it "should show constants defined on the current module" do pry_eval("class TempFoo1; BARGHL = 1; end", "ls TempFoo1").should =~ /BARGHL/ end it "should not show constants defined on parent modules by default" do pry_eval("class TempFoo2; LHGRAB = 1; end; class TempFoo3 < TempFoo2; BARGHL = 1; end", "ls TempFoo3").should.not =~ /LHGRAB/ end it "should show constants defined on ancestors with -v" do pry_eval("class TempFoo4; LHGRAB = 1; end; class TempFoo5 < TempFoo4; BARGHL = 1; end", "ls -v TempFoo5").should =~ /LHGRAB/ end it "should not autoload constants!" do autoload :McflurgleTheThird, "/tmp/this-file-d000esnat-exist.rb" lambda{ pry_eval("ls -c") }.should.not.raise end end describe "grep" do it "should reduce the number of outputted things" do pry_eval("ls -c").should =~ /ArgumentError/ pry_eval("ls -c --grep Run").should.not =~ /ArgumentError/ end it "should still output matching things" do pry_eval("ls -c --grep Run").should =~ /RuntimeError/ end end describe "when no arguments given" do describe "when at the top-level" do # rubinius has a bug that means local_variables of "main" aren't reported inside eval() unless Pry::Helpers::BaseHelpers.rbx? it "should show local variables" do pry_eval("ls").should =~ /_pry_/ pry_eval("arbitrar = 1", "ls").should =~ /arbitrar/ end end end describe "when in a class" do it "should show constants" do pry_eval("class GeFromulate1; FOOTIFICATE=1.3; end", "cd GeFromulate1", "ls").should =~ /FOOTIFICATE/ end it "should show class variables" do pry_eval("class GeFromulate2; @@flurb=1.3; end", "cd GeFromulate2", "ls").should =~ /@@flurb/ end it "should show methods" do pry_eval("class GeFromulate3; def self.mooflight; end ; end", "cd GeFromulate3", "ls").should =~ /mooflight/ end end describe "when in an object" do it "should show methods" do pry_eval("cd Class.new{ def self.fooerise; end; self }", "ls").should =~ /fooerise/ end it "should show instance variables" do pry_eval("cd Class.new", "@alphooent = 1", "ls").should =~ /@alphooent/ end end end if Pry::Helpers::BaseHelpers.jruby? describe 'on java objects' do it 'should omit java-esque aliases by default' do pry_eval('ls java.lang.Thread.current_thread').should =~ /\bthread_group\b/ pry_eval('ls java.lang.Thread.current_thread').should.not =~ /\bgetThreadGroup\b/ end it 'should include java-esque aliases if requested' do pry_eval('ls java.lang.Thread.current_thread -J').should =~ /\bthread_group\b/ pry_eval('ls java.lang.Thread.current_thread -J').should =~ /\bgetThreadGroup\b/ end end end end pry-0.9.12.6/spec/commands/find_method_spec.rb0000644000004100000410000000377112272154172021176 0ustar www-datawww-datarequire 'helper' # we turn off the test for MRI 1.8 because our source_location hack # for C methods actually runs the methods - and since it runs ALL # methods (in an attempt to find a match) it runs 'exit' and aborts # the test, causing a failure. We should fix this in the future by # blacklisting certain methods for 1.8 MRI (such as exit, fork, and so on) unless Pry::Helpers::BaseHelpers.mri_18? MyKlass = Class.new do def hello "timothy" end def goodbye "jenny" end def tea_tim? "timothy" end def tea_time? "polly" end end describe "find-method" do describe "find matching methods by name regex (-n option)" do it "should find a method by regex" do pry_eval("find-method hell MyKlass").should =~ /MyKlass.*?hello/m end it "should NOT match a method that does not match the regex" do pry_eval("find-method hell MyKlass").should.not =~ /MyKlass.*?goodbye/m end end describe "find matching methods by content regex (-c option)" do it "should find a method by regex" do pry_eval("find-method -c timothy MyKlass").should =~ /MyKlass.*?hello/m end it "should NOT match a method that does not match the regex" do pry_eval("find-method timothy MyKlass").should.not =~ /MyKlass.*?goodbye/m end end it "should work with badly behaved constants" do MyKlass::X = Object.new def (MyKlass::X).hash raise "mooo" end pry_eval("find-method -c timothy MyKlass").should =~ /MyKlass.*?hello/m end it "should escape regexes correctly" do good = /tea_time\?/ bad = /tea_tim\?/ pry_eval('find-method tea_time? MyKlass').should =~ good pry_eval('find-method tea_time? MyKlass').should =~ good pry_eval('find-method tea_time\? MyKlass').should.not =~ bad pry_eval('find-method tea_time\? MyKlass').should =~ good end end Object.remove_const(:MyKlass) end pry-0.9.12.6/spec/commands/hist_spec.rb0000644000004100000410000001235012272154172017656 0ustar www-datawww-datarequire 'helper' describe "hist" do before do Pry.history.clear @hist = Pry.history @str_output = StringIO.new @t = pry_tester do # For looking at what hist pushes into the input stack. The # implementation of this helper will definitely have to change at some # point. def next_input @pry.input.string end end end it 'should display the correct history' do @hist.push "hello" @hist.push "world" @t.eval('hist').should =~ /hello\n.*world/ end it 'should replay history correctly (single item)' do o = Object.new @hist.push "@x = 10" @hist.push "@y = 20" @hist.push "@z = 30" @t.context = o @t.eval 'hist --replay -1' @t.next_input.should == "@z = 30\n" end it 'should replay a range of history correctly (range of items)' do o = Object.new @hist.push "@x = 10" @hist.push "@y = 20" @t.context = o @t.eval 'hist --replay 0..2' @t.next_input.should == "@x = 10\n@y = 20\n" end # this is to prevent a regression where input redirection is # replaced by just appending to `eval_string` it 'should replay a range of history correctly (range of commands)' do o = Object.new @hist.push "cd 1" @hist.push "cd 2" redirect_pry_io(InputTester.new("hist --replay 0..2", "Pad.stack = _pry_.binding_stack.dup", "exit-all")) do o.pry end o = Pad.stack[-2..-1].map { |v| v.eval('self') } o.should == [1, 2] Pad.clear end it 'should grep for correct lines in history' do @hist.push "abby" @hist.push "box" @hist.push "button" @hist.push "pepper" @hist.push "orange" @hist.push "grape" @hist.push "def blah 1" @hist.push "def boink 2" @hist.push "place holder" @t.eval('hist --grep o').should =~ /\d:.*?box\n\d:.*?button\n\d:.*?orange/ # test more than one word in a regex match (def blah) @t.eval('hist --grep def blah').should =~ /def blah 1/ # test more than one word with leading white space in a regex match (def boink) @t.eval('hist --grep def boink').should =~ /def boink 2/ end it 'should return last N lines in history with --tail switch' do ("a".."z").each do |v| @hist.push v end out = @t.eval 'hist --tail 3' out.each_line.count.should == 3 out.should =~ /x\n\d+:.*y\n\d+:.*z/ end it 'should apply --tail after --grep' do @hist.push "print 1" @hist.push "print 2" @hist.push "puts 3" @hist.push "print 4" @hist.push "puts 5" out = @t.eval 'hist --tail 2 --grep print' out.each_line.count.should == 2 out.should =~ /\d:.*?print 2\n\d:.*?print 4/ end it 'should apply --head after --grep' do @hist.push "puts 1" @hist.push "print 2" @hist.push "puts 3" @hist.push "print 4" @hist.push "print 5" out = @t.eval 'hist --head 2 --grep print' out.each_line.count.should == 2 out.should =~ /\d:.*?print 2\n\d:.*?print 4/ end # strangeness in this test is due to bug in Readline::HISTORY not # always registering first line of input it 'should return first N lines in history with --head switch' do ("a".."z").each do |v| @hist.push v end out = @t.eval 'hist --head 4' out.each_line.count.should == 4 out.should =~ /a\n\d+:.*b\n\d+:.*c/ end # strangeness in this test is due to bug in Readline::HISTORY not # always registering first line of input it 'should show lines between lines A and B with the --show switch' do ("a".."z").each do |v| @hist.push v end out = @t.eval 'hist --show 1..4' out.each_line.count.should == 4 out.should =~ /b\n\d+:.*c\n\d+:.*d/ end it "should store a call with `--replay` flag" do redirect_pry_io(InputTester.new(":banzai", "hist --replay 1", "hist", "exit-all"), @str_output) do Pry.start end @str_output.string.should =~ /hist --replay 1/ end it "should not contain lines produced by `--replay` flag" do redirect_pry_io(InputTester.new(":banzai", ":geronimo", ":huzzah", "hist --replay 1..3", "hist", "exit-all"), @str_output) do Pry.start end @str_output.string.each_line.to_a.reject { |line| line.start_with?("=>") }.size.should == 4 @str_output.string.each_line.to_a.last.should =~ /hist --replay 1\.\.3/ @str_output.string.each_line.to_a[-2].should =~ /:huzzah/ end it "should raise CommandError when index of `--replay` points out to another `hist --replay`" do redirect_pry_io(InputTester.new(":banzai", "hist --replay 1", "hist --replay 2", "exit-all"), @str_output) do Pry.start end @str_output.string.should =~ /Replay index 2 points out to another replay call: `hist --replay 1`/ end it "should disallow execution of `--replay ` when CommandError raised" do redirect_pry_io(InputTester.new("a = 0", "a += 1", "hist --replay 2", "hist --replay 3", "'a is ' + a.to_s", "hist", "exit-all"), @str_output) do Pry.start end @str_output.string.each_line.to_a.reject { |line| line !~ /\A\d/ }.size.should == 5 @str_output.string.should =~ /a is 2/ end end pry-0.9.12.6/spec/commands/jump_to_spec.rb0000644000004100000410000000074212272154172020366 0ustar www-datawww-datarequire 'helper' describe "jump-to" do it 'should jump to the proper binding index in the stack' do pry_eval('cd 1', 'cd 2', 'jump-to 1', 'self').should == 1 end it 'should print error when trying to jump to a non-existent binding index' do pry_eval("cd 1", "cd 2", "jump-to 100").should =~ /Invalid nest level/ end it 'should print error when trying to jump to the same binding index' do pry_eval("cd 1", "cd 2", "jump-to 2").should =~ /Already/ end end pry-0.9.12.6/spec/commands/disable_pry_spec.rb0000644000004100000410000000071512272154172021206 0ustar www-datawww-datarequire 'helper' describe "disable-pry" do before do @t = pry_tester end after do ENV.delete 'DISABLE_PRY' end it 'should quit the current session' do lambda{ @t.process_command 'disable-pry' }.should.throw(:breakout) end it "should set DISABLE_PRY" do ENV['DISABLE_PRY'].should == nil lambda{ @t.process_command 'disable-pry' }.should.throw(:breakout) ENV['DISABLE_PRY'].should == 'true' end end pry-0.9.12.6/spec/commands/cd_spec.rb0000644000004100000410000001460212272154172017277 0ustar www-datawww-datarequire 'helper' describe 'cd' do before do @o, @obj = Object.new, Object.new @obj.instance_variable_set(:@x, 66) @obj.instance_variable_set(:@y, 79) @o.instance_variable_set(:@obj, @obj) @t = pry_tester(@o) do def assert_binding_stack(other) binding_stack.map { |b| b.eval('self') }.should == other end def binding_stack eval '_pry_.binding_stack.dup' end def command_state eval '_pry_.command_state["cd"]' end def old_stack eval '_pry_.command_state["cd"].old_stack.dup' end end end describe 'state' do it 'should not to be set up in fresh instance' do @t.command_state.should.be.nil end end describe 'old stack toggling with `cd -`' do describe 'in fresh pry instance' do it 'should not toggle when there is no old stack' do 2.times do @t.eval 'cd -' @t.assert_binding_stack [@o] end end end describe 'when an error was raised' do it 'should not toggle and should keep correct stacks' do proc { @t.eval 'cd %' }.should.raise(Pry::CommandError) @t.old_stack.should == [] @t.assert_binding_stack [@o] @t.eval 'cd -' @t.old_stack.should == [] @t.assert_binding_stack [@o] end end describe 'when using simple cd syntax' do it 'should toggle' do @t.eval 'cd :mon_dogg', 'cd -' @t.assert_binding_stack [@o] @t.eval 'cd -' @t.assert_binding_stack [@o, :mon_dogg] end end describe "when using complex cd syntax" do it 'should toggle with a complex path (simple case)' do @t.eval 'cd 1/2/3', 'cd -' @t.assert_binding_stack [@o] @t.eval 'cd -' @t.assert_binding_stack [@o, 1, 2, 3] end it 'should toggle with a complex path (more complex case)' do @t.eval 'cd 1/2/3', 'cd ../4', 'cd -' @t.assert_binding_stack [@o, 1, 2, 3] @t.eval 'cd -' @t.assert_binding_stack [@o, 1, 2, 4] end end describe 'series of cd calls' do it 'should toggle with fuzzy `cd -` calls' do @t.eval 'cd :mon_dogg', 'cd -', 'cd 42', 'cd -' @t.assert_binding_stack [@o] @t.eval 'cd -' @t.assert_binding_stack [@o, 42] end end describe 'when using cd ..' do it 'should toggle with a simple path' do @t.eval 'cd :john_dogg', 'cd ..' @t.assert_binding_stack [@o] @t.eval 'cd -' @t.assert_binding_stack [@o, :john_dogg] end it 'should toggle with a complex path' do @t.eval 'cd 1/2/3/../4', 'cd -' @t.assert_binding_stack [@o] @t.eval 'cd -' @t.assert_binding_stack [@o, 1, 2, 4] end end describe 'when using cd ::' do it 'should toggle' do @t.eval 'cd ::', 'cd -' @t.assert_binding_stack [@o] @t.eval 'cd -' @t.assert_binding_stack [@o, TOPLEVEL_BINDING.eval('self')] end end describe 'when using cd /' do it 'should toggle' do @t.eval 'cd /', 'cd -' @t.assert_binding_stack [@o] @t.eval 'cd :john_dogg', 'cd /', 'cd -' @t.assert_binding_stack [@o, :john_dogg] end end describe 'when using ^D (Control-D) key press' do it 'should keep correct old binding' do @t.eval 'cd :john_dogg', 'cd :mon_dogg', 'cd :kyr_dogg', 'Pry::DEFAULT_CONTROL_D_HANDLER.call("", _pry_)' @t.assert_binding_stack [@o, :john_dogg, :mon_dogg] @t.eval 'cd -' @t.assert_binding_stack [@o, :john_dogg, :mon_dogg, :kyr_dogg] @t.eval 'cd -' @t.assert_binding_stack [@o, :john_dogg, :mon_dogg] end end end it 'should cd into simple input' do @t.eval 'cd :mon_ouie' @t.eval('self').should == :mon_ouie end it 'should break out of session with cd ..' do @t.eval 'cd :outer', 'cd :inner' @t.eval('self').should == :inner @t.eval 'cd ..' @t.eval('self').should == :outer end it "should not leave the REPL session when given 'cd ..'" do @t.eval 'cd ..' @t.eval('self').should == @o end it 'should break out to outer-most session with cd /' do @t.eval 'cd :inner' @t.eval('self').should == :inner @t.eval 'cd 5' @t.eval('self').should == 5 @t.eval 'cd /' @t.eval('self').should == @o end it 'should break out to outer-most session with just cd (no args)' do @t.eval 'cd :inner' @t.eval('self').should == :inner @t.eval 'cd 5' @t.eval('self').should == 5 @t.eval 'cd' @t.eval('self').should == @o end it 'should cd into an object and its ivar using cd obj/@ivar syntax' do @t.eval 'cd @obj/@x' @t.assert_binding_stack [@o, @obj, 66] end it 'should cd into an object and its ivar using cd obj/@ivar/ syntax (note following /)' do @t.eval 'cd @obj/@x/' @t.assert_binding_stack [@o, @obj, 66] end it 'should cd into previous object and its local using cd ../local syntax' do @t.eval 'cd @obj', 'local = :local', 'cd @x', 'cd ../local' @t.assert_binding_stack [@o, @obj, :local] end it 'should cd into an object and its ivar and back again using cd obj/@ivar/.. syntax' do @t.eval 'cd @obj/@x/..' @t.assert_binding_stack [@o, @obj] end it 'should cd into an object and its ivar and back and then into another ivar using cd obj/@ivar/../@y syntax' do @t.eval 'cd @obj/@x/../@y' @t.assert_binding_stack [@o, @obj, 79] end it 'should cd back to top-level and then into another ivar using cd /@ivar/ syntax' do @t.eval '@z = 20', 'cd @obj/@x/', 'cd /@z' @t.assert_binding_stack [@o, 20] end it 'should start a session on TOPLEVEL_BINDING with cd ::' do @t.eval 'cd ::' @t.eval('self').should == TOPLEVEL_BINDING.eval('self') end it 'should cd into complex input (with spaces)' do def @o.hello(x, y, z) :mon_ouie end @t.eval 'cd hello 1, 2, 3' @t.eval('self').should == :mon_ouie end it 'should not cd into complex input when it encounters an exception' do proc { @t.eval 'cd 1/2/swoop_a_doop/3' }.should.raise(Pry::CommandError) @t.assert_binding_stack [@o] end # Regression test for ticket #516. # FIXME: This is actually broken. # it 'should be able to cd into the Object BasicObject' do # proc { # @t.eval 'cd BasicObject.new' # }.should.not.raise # end end pry-0.9.12.6/spec/commands/show_source_spec.rb0000644000004100000410000005777112272154173021270 0ustar www-datawww-datarequire 'helper' require "fixtures/show_source_doc_examples" if !PryTestHelpers.mri18_and_no_real_source_location? describe "show-source" do before do @o = Object.new def @o.sample_method :sample end Object.const_set(:Test, Module.new) end after do Pad.clear end it "should output a method's source" do pry_eval(binding, 'show-source @o.sample_method').should =~ /def @o.sample/ end it "should output help" do pry_eval('show-source -h').should =~ /Usage:\s+show-source/ end it "should output a method's source with line numbers" do pry_eval(binding, 'show-source -l @o.sample_method').should =~ /\d+: def @o.sample/ end it "should output a method's source with line numbers starting at 1" do pry_eval(binding, 'show-source -b @o.sample_method').should =~ /1: def @o.sample/ end it "should output a method's source if inside method and no name given" do def @o.sample pry_eval(binding, 'show-source').should =~ /def @o.sample/ end @o.sample end it "should output a method's source inside method using the -l switch" do def @o.sample pry_eval(binding, 'show-source -l').should =~ /def @o.sample/ end @o.sample end it "should find methods even if there are spaces in the arguments" do def @o.foo(*bars) "Mr flibble" self end out = pry_eval(binding, "show-source @o.foo('bar', 'baz bam').foo") out.should =~ /Mr flibble/ end it "should find methods even if the object overrides method method" do c = Class.new{ def method; 98 end } pry_eval(binding, "show-source c.new.method").should =~ /98/ end it "should not show the source when a non-extant method is requested" do c = Class.new{ def method; 98; end } mock_pry(binding, "show-source c#wrongmethod").should =~ /Couldn't locate/ end it "should find instance_methods if the class overrides instance_method" do c = Class.new{ def method; 98 end def self.instance_method; 789; end } pry_eval(binding, "show-source c#method").should =~ /98/ end it "should find instance methods with self#moo" do c = Class.new{ def moo; "ve over!"; end } pry_eval(binding, "cd c", "show-source self#moo").should =~ /ve over/ end it "should not find instance methods with self.moo" do c = Class.new{ def moo; "ve over!"; end } proc { pry_eval(binding, 'cd c', 'show-source self.moo') }.should.raise(Pry::CommandError).message.should =~ /Couldn't locate/ end it "should find normal methods with self.moo" do c = Class.new{ def self.moo; "ve over!"; end } pry_eval(binding, 'cd c', 'show-source self.moo').should =~ /ve over/ end it "should not find normal methods with self#moo" do c = Class.new{ def self.moo; "ve over!"; end } proc { pry_eval(binding, 'cd c', 'show-source self#moo') }.should.raise(Pry::CommandError).message.should =~ /Couldn't locate/ end it "should find normal methods (i.e non-instance methods) by default" do c = Class.new{ def self.moo; "ve over!"; end } pry_eval(binding, "cd c", "show-source moo").should =~ /ve over/ end it "should find instance methods if no normal methods available" do c = Class.new{ def moo; "ve over!"; end } pry_eval(binding, "cd c", "show-source moo").should =~ /ve over/ end it "should find super methods" do class Foo def foo(*bars) :super_wibble end end o = Foo.new Object.remove_const(:Foo) def o.foo(*bars) :wibble end pry_eval(binding, "show-source --super o.foo"). should =~ /:super_wibble/ end it "should raise a CommandError when super method doesn't exist" do def @o.foo(*bars); end proc { pry_eval(binding, "show-source --super @o.foo") }.should.raise(Pry::CommandError).message.should =~ /No superclass found/ end # dynamically defined method source retrieval is only supported in # 1.9 - where Method#source_location is native if RUBY_VERSION =~ /1.9/ it "should output the source of a method defined inside Pry" do out = pry_eval("def dyn_method\n:test\nend", 'show-source dyn_method') out.should =~ /def dyn_method/ Object.remove_method :dyn_method end it 'should output source for an instance method defined inside pry' do pry_tester.tap do |t| t.eval "class Test::A\n def yo\n end\nend" t.eval('show-source Test::A#yo').should =~ /def yo/ end end it 'should output source for a repl method defined using define_method' do pry_tester.tap do |t| t.eval "class Test::A\n define_method(:yup) {}\nend" t.eval('show-source Test::A#yup').should =~ /define_method\(:yup\)/ end end it "should output the source of a command defined inside Pry" do command_definition = %{ Pry.commands.command "hubba-hubba" do puts "that's what she said!" end } out = pry_eval(command_definition, 'show-source hubba-hubba') out.should =~ /what she said/ Pry.commands.delete "hubba-hubba" end end describe "on sourcable objects" do if RUBY_VERSION =~ /1.9/ it "should output source defined inside pry" do pry_tester.tap do |t| t.eval "hello = proc { puts 'hello world!' }" t.eval("show-source hello").should =~ /proc \{ puts/ end end end it "should output source for procs/lambdas stored in variables" do hello = proc { puts 'hello world!' } pry_eval(binding, 'show-source hello').should =~ /proc \{ puts/ end it "should output source for procs/lambdas stored in constants" do HELLO = proc { puts 'hello world!' } pry_eval(binding, "show-source HELLO").should =~ /proc \{ puts/ Object.remove_const(:HELLO) end it "should output source for method objects" do def @o.hi; puts 'hi world'; end meth = @o.method(:hi) pry_eval(binding, "show-source meth").should =~ /puts 'hi world'/ end describe "on variables that shadow methods" do before do @t = pry_tester.eval unindent(<<-EOS) class ::TestHost def hello hello = proc { ' smile ' } pry_tester(binding) end end ::TestHost.new.hello EOS end after do Object.remove_const(:TestHost) end it "source of variable should take precedence over method that is being shadowed" do source = @t.eval('show-source hello') source.should.not =~ /def hello/ source.should =~ /proc \{ ' smile ' \}/ end it "source of method being shadowed should take precedence over variable if given self.meth_name syntax" do @t.eval('show-source self.hello').should =~ /def hello/ end end end describe "on variable or constant" do before do class TestHost def hello "hi there" end end end after do Object.remove_const(:TestHost) end it "should output source of its class if variable doesn't respond to source_location" do test_host = TestHost.new pry_eval(binding, 'show-source test_host'). should =~ /class TestHost\n.*def hello/ end it "should output source of its class if constant doesn't respond to source_location" do TEST_HOST = TestHost.new pry_eval(binding, 'show-source TEST_HOST'). should =~ /class TestHost\n.*def hello/ Object.remove_const(:TEST_HOST) end end describe "on modules" do before do class ShowSourceTestSuperClass def alpha end end class ShowSourceTestClass "bar" do; end pry_eval('show-source bar').should =~ /:body_of_foo_bar_regex/ end end describe "create_command commands" do it 'should show source for a command' do @set.create_command "foo", "babble" do def process() :body_of_foo end end pry_eval('show-source foo').should =~ /:body_of_foo/ end it 'should show source for a command defined inside pry' do pry_eval %{ _pry_.commands.create_command "foo", "babble" do def process() :body_of_foo end end } pry_eval('show-source foo').should =~ /:body_of_foo/ end end describe "real class-based commands" do before do class ::TemporaryCommand < Pry::ClassCommand match 'temp-command' def process() :body_of_temp end end Pry.commands.add_command(::TemporaryCommand) end after do Object.remove_const(:TemporaryCommand) end it 'should show source for a command' do pry_eval('show-source temp-command').should =~ /:body_of_temp/ end it 'should show source for a command defined inside pry' do pry_eval %{ class ::TemporaryCommandInPry < Pry::ClassCommand match 'temp-command-in-pry' def process() :body_of_temp end end } Pry.commands.add_command(::TemporaryCommandInPry) pry_eval('show-source temp-command-in-pry').should =~ /:body_of_temp/ Object.remove_const(:TemporaryCommandInPry) end end end describe "should set _file_ and _dir_" do it 'should set _file_ and _dir_ to file containing method source' do t = pry_tester t.process_command "show-source TestClassForShowSource#alpha" t.pry.last_file.should =~ /show_source_doc_examples/ t.pry.last_dir.should =~ /fixtures/ end end unless Pry::Helpers::BaseHelpers.rbx? describe "can't find class/module code" do describe "for classes" do before do module Jesus module Pig def lillybing; :lillybing; end end class Brian; end class Jingle def a; :doink; end end class Jangle < Jingle; include Pig; end class Bangle < Jangle; end end end after do Object.remove_const(:Jesus) end it 'shows superclass code' do t = pry_tester t.process_command "show-source Jesus::Jangle" t.last_output.should =~ /doink/ end it 'ignores included modules' do t = pry_tester t.process_command "show-source Jesus::Jangle" t.last_output.should.not =~ /lillybing/ end it 'errors when class has no superclass to show' do t = pry_tester lambda { t.process_command "show-source Jesus::Brian" }.should.raise(Pry::CommandError).message. should =~ /Couldn't locate/ end it 'shows warning when reverting to superclass code' do t = pry_tester t.process_command "show-source Jesus::Jangle" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Jangle.*Showing.*Jesus::Jingle instead/ end it 'shows nth level superclass code (when no intermediary superclasses have code either)' do t = pry_tester t.process_command "show-source Jesus::Bangle" t.last_output.should =~ /doink/ end it 'shows correct warning when reverting to nth level superclass' do t = pry_tester t.process_command "show-source Jesus::Bangle" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Bangle.*Showing.*Jesus::Jingle instead/ end end describe "for modules" do before do module Jesus module Alpha def alpha; :alpha; end end module Zeta; end module Beta include Alpha end module Gamma include Beta end end end after do Object.remove_const(:Jesus) end it 'shows included module code' do t = pry_tester t.process_command "show-source Jesus::Beta" t.last_output.should =~ /alpha/ end it 'shows warning when reverting to included module code' do t = pry_tester t.process_command "show-source Jesus::Beta" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Beta.*Showing.*Jesus::Alpha instead/ end it 'errors when module has no included module to show' do t = pry_tester lambda { t.process_command "show-source Jesus::Zeta" }.should.raise(Pry::CommandError).message. should =~ /Couldn't locate/ end it 'shows nth level included module code (when no intermediary modules have code either)' do t = pry_tester t.process_command "show-source Jesus::Gamma" t.last_output.should =~ /alpha/ end it 'shows correct warning when reverting to nth level included module' do t = pry_tester t.process_command "show-source Jesus::Gamma" t.last_output.should =~ /Warning.*?Cannot find.*?Jesus::Gamma.*Showing.*Jesus::Alpha instead/ end end end end end end pry-0.9.12.6/spec/commands/show_input_spec.rb0000644000004100000410000000053712272154173021113 0ustar www-datawww-datarequire 'helper' describe "show-input" do before do @t = pry_tester end it 'should correctly show the current lines in the input buffer' do eval_str = unindent(<<-STR) def hello puts :bing STR @t.process_command 'show-input', eval_str @t.last_output.should =~ /\A\d+: def hello\n\d+: puts :bing/ end end pry-0.9.12.6/spec/commands/cat_spec.rb0000644000004100000410000001040512272154172017455 0ustar www-datawww-datarequire 'helper' describe "cat" do before do @str_output = StringIO.new @t = pry_tester do def insert_nil_input @pry.update_input_history(nil) end def last_exception=(e) @pry.last_exception = e end end end describe "on receiving a file that does not exist" do it 'should display an error message' do proc { @t.eval 'cat supercalifragilicious66' }.should.raise(StandardError).message.should =~ /Cannot open/ end end describe "with --in" do it 'should display the last few expressions with indices' do @t.eval('10', '20', 'cat --in').should == unindent(<<-STR) 1: 10 2: 20 STR end end describe "with --in 1" do it 'should display the first expression with no index' do @t.eval('10', '20', 'cat --in 1').should == "10\n" end end describe "with --in -1" do it 'should display the last expression with no index' do @t.eval('10', '20', 'cat --in -1').should == "20\n" end end describe "with --in 1..2" do it 'should display the given range with indices, omitting nils' do @t.eval '10' @t.insert_nil_input # normally happens when a command is executed @t.eval ':hello' @t.eval('cat --in 1..3').should == unindent(<<-EOS) 1: 10 3: :hello EOS end end # this doesnt work so well on rbx due to differences in backtrace # so we currently skip rbx until we figure out a workaround describe "with --ex" do before do @o = Object.new # this is to test exception code (cat --ex) def @o.broken_method this method is broken end end if !Pry::Helpers::BaseHelpers.rbx? it 'cat --ex should display repl code that generated exception' do @t.eval unindent(<<-EOS) begin this raises error rescue => e _pry_.last_exception = e end EOS @t.eval('cat --ex').should =~ /\d+:(\s*) this raises error/ end it 'cat --ex should correctly display code that generated exception' do begin @o.broken_method rescue => e @t.last_exception = e end @t.eval('cat --ex').should =~ /this method is broken/ end end end describe "with --ex N" do it 'should cat first level of backtrace when --ex used with no argument ' do temp_file do |f| f << "bt number 1" f.flush @t.last_exception = mock_exception("#{f.path}:1", 'x', 'x') @t.eval('cat --ex').should =~ /bt number 1/ end end it 'should cat first level of backtrace when --ex 0 used ' do temp_file do |f| f << "bt number 1" f.flush @t.last_exception = mock_exception("#{f.path}:1", 'x', 'x') @t.eval('cat --ex 0').should =~ /bt number 1/ end end it 'should cat second level of backtrace when --ex 1 used ' do temp_file do |f| f << "bt number 2" f.flush @t.last_exception = mock_exception('x', "#{f.path}:1", 'x') @t.eval('cat --ex 1').should =~ /bt number 2/ end end it 'should cat third level of backtrace when --ex 2 used' do temp_file do |f| f << "bt number 3" f.flush @t.last_exception = mock_exception('x', 'x', "#{f.path}:1") @t.eval('cat --ex 2').should =~ /bt number 3/ end end it 'should show error when backtrace level out of bounds' do @t.last_exception = mock_exception('x', 'x', 'x') proc { @t.eval('cat --ex 3') }.should.raise(Pry::CommandError).message.should =~ /out of bounds/ end it 'each successive cat --ex should show the next level of backtrace, and going past the final level should return to the first' do temp_files = [] 3.times do |i| temp_files << Tempfile.new(['pry', '.rb']) temp_files.last << "bt number #{i}" temp_files.last.flush end @t.last_exception = mock_exception(*temp_files.map { |f| "#{f.path}:1" }) 3.times do |i| @t.eval('cat --ex').should =~ /bt number #{i}/ end @t.eval('cat --ex').should =~ /bt number 0/ temp_files.each do |file| file.close(true) end end end end pry-0.9.12.6/spec/commands/edit_spec.rb0000644000004100000410000004577212272154172017652 0ustar www-datawww-datarequire 'pathname' require 'helper' describe "edit" do before do @old_editor = Pry.config.editor @file = @line = @contents = nil Pry.config.editor = lambda do |file, line| @file = file; @line = line; @contents = File.read(@file) nil end end after do Pry.config.editor = @old_editor end describe "with FILE" do before do # OS-specific tempdir name. For GNU/Linux it's "tmp", for Windows it's # something "Temp". @tf_dir = if Pry::Helpers::BaseHelpers.mri_19? Pathname.new(Dir::Tmpname.tmpdir) else Pathname.new(Dir.tmpdir) end @tf_path = File.expand_path(File.join(@tf_dir.to_s, 'bar.rb')) FileUtils.touch(@tf_path) end after do FileUtils.rm(@tf_path) if File.exists?(@tf_path) end it "should invoke Pry.config.editor with absolutified filenames" do pry_eval 'edit lib/pry.rb' @file.should == File.expand_path('lib/pry.rb') pry_eval "edit #@tf_path" @file.should == @tf_path end it "should guess the line number from a colon" do pry_eval 'edit lib/pry.rb:10' @line.should == 10 end it "should use the line number from -l" do pry_eval 'edit -l 10 lib/pry.rb' @line.should == 10 end it "should not delete the file!" do pry_eval 'edit Rakefile' File.exist?(@file).should == true end it "works with files that contain blanks in their names" do tf_path = File.join(File.dirname(@tf_path), 'swoop and doop.rb') FileUtils.touch(tf_path) pry_eval "edit #{ tf_path }" @file.should == tf_path FileUtils.rm(tf_path) end describe do before do Pad.counter = 0 Pry.config.editor = lambda { |file, line| File.open(file, 'w') { |f| f << "Pad.counter = Pad.counter + 1" } nil } end it "should reload the file if it is a ruby file" do temp_file do |tf| counter = Pad.counter path = tf.path pry_eval "edit #{path}" Pad.counter.should == counter + 1 end end it "should not reload the file if it is not a ruby file" do temp_file('.py') do |tf| counter = Pad.counter path = tf.path pry_eval "edit #{path}" Pad.counter.should == counter end end it "should not reload a ruby file if -n is given" do temp_file do |tf| counter = Pad.counter path = tf.path Pad.counter.should == counter end end it "should reload a non-ruby file if -r is given" do temp_file('.pryrc') do |tf| counter = Pad.counter path = tf.path pry_eval "edit -r #{path}" Pad.counter.should == counter + 1 end end end describe do before do @reloading = nil Pry.config.editor = lambda do |file, line, reloading| @file = file; @line = line; @reloading = reloading nil end end it "should pass the editor a reloading arg" do pry_eval 'edit lib/pry.rb' @reloading.should == true pry_eval 'edit -n lib/pry.rb' @reloading.should == false end end end describe "with --ex" do before do @t = pry_tester do def last_exception=(exception) @pry.last_exception = exception end def last_exception; @pry.last_exception; end end end describe "with a real file" do before do @tf = Tempfile.new(["pry", ".rb"]) @path = @tf.path @tf << "1\n2\nraise RuntimeError" @tf.flush begin load @path rescue RuntimeError => e @t.last_exception = e end end after do @tf.close(true) File.unlink("#{@path}c") if File.exists?("#{@path}c") #rbx end it "should reload the file" do Pry.config.editor = lambda {|file, line| File.open(file, 'w'){|f| f << "FOO = 'BAR'" } nil } defined?(FOO).should.be.nil @t.eval 'edit --ex' FOO.should == 'BAR' end # regression test (this used to edit the current method instead # of the exception) it 'edits the exception even when in a patched method context' do source_location = nil Pry.config.editor = lambda {|file, line| source_location = [file, line] nil } Pad.le = @t.last_exception redirect_pry_io(InputTester.new("def broken_method", "binding.pry", "end", "broken_method", "_pry_.last_exception = Pad.le", "edit --ex -n", "exit-all", "exit-all")) do Object.new.pry end source_location.should == [@path, 3] Pad.clear end it "should not reload the file if -n is passed" do Pry.config.editor = lambda {|file, line| File.open(file, 'w'){|f| f << "FOO2 = 'BAZ'" } nil } defined?(FOO2).should.be.nil @t.eval 'edit -n --ex' defined?(FOO2).should.be.nil end describe "with --patch" do # Original source code must be untouched. it "should apply changes only in memory (monkey patching)" do Pry.config.editor = lambda {|file, line| File.open(file, 'w'){|f| f << "FOO3 = 'PIYO'" } @patched_def = File.open(file, 'r').read nil } defined?(FOO3).should.be.nil @t.eval 'edit --ex --patch' FOO3.should == 'PIYO' @tf.rewind @tf.read.should == "1\n2\nraise RuntimeError" @patched_def.should == "FOO3 = 'PIYO'" end end end describe "with --ex NUM" do before do Pry.config.editor = proc do |file, line| @__ex_file__ = file @__ex_line__ = line nil end @t.last_exception = mock_exception('a:1', 'b:2', 'c:3') end it 'should start on first level of backtrace with just --ex' do @t.eval 'edit -n --ex' @__ex_file__.should == "a" @__ex_line__.should == 1 end it 'should start editor on first level of backtrace with --ex 0' do @t.eval 'edit -n --ex 0' @__ex_file__.should == "a" @__ex_line__.should == 1 end it 'should start editor on second level of backtrace with --ex 1' do @t.eval 'edit -n --ex 1' @__ex_file__.should == "b" @__ex_line__.should == 2 end it 'should start editor on third level of backtrace with --ex 2' do @t.eval 'edit -n --ex 2' @__ex_file__.should == "c" @__ex_line__.should == 3 end it 'should display error message when backtrace level is invalid' do proc { @t.eval 'edit -n --ex 4' }.should.raise(Pry::CommandError) end end end describe "without FILE" do before do @t = pry_tester end it "should edit the current expression if it's incomplete" do eval_str = 'def a' @t.process_command 'edit', eval_str @contents.should == "def a\n" end it "should edit the previous expression if the current is empty" do @t.eval 'def a; 2; end', 'edit' @contents.should == "def a; 2; end\n" end it "should use a blank file if -t is specified" do @t.eval 'def a; 5; end', 'edit -t' @contents.should == "\n" end it "should use a blank file if -t given, even during an expression" do eval_str = 'def a;' @t.process_command 'edit -t', eval_str @contents.should == "\n" end it "should position the cursor at the end of the expression" do eval_str = "def a; 2;\nend" @t.process_command 'edit', eval_str @line.should == 2 end it "should evaluate the expression" do Pry.config.editor = lambda {|file, line| File.open(file, 'w'){|f| f << "'FOO'\n" } nil } eval_str = '' @t.process_command 'edit', eval_str eval_str.should == "'FOO'\n" end it "should not evaluate the expression with -n" do Pry.config.editor = lambda {|file, line| File.open(file, 'w'){|f| f << "'FOO'\n" } nil } eval_str = '' @t.process_command 'edit -n', eval_str eval_str.should == '' end end describe "with --in" do it "should edit the nth line of _in_" do pry_eval '10', '11', 'edit --in -2' @contents.should == "10\n" end it "should edit the last line if no argument is given" do pry_eval '10', '11', 'edit --in' @contents.should == "11\n" end it "should edit a range of lines if a range is given" do pry_eval "10", "11", "edit -i 1,2" @contents.should == "10\n11\n" end it "should edit a multi-line expression as it occupies one line of _in_" do pry_eval "class Fixnum\n def invert; -self; end\nend", "edit -i 1" @contents.should == "class Fixnum\n def invert; -self; end\nend\n" end it "should not work with a filename" do proc { pry_eval 'edit ruby.rb -i' }.should.raise(Pry::CommandError). message.should =~ /Only one of --ex, --temp, --in, --method and FILE/ end it "should not work with nonsense" do proc { pry_eval 'edit --in three' }.should.raise(Pry::CommandError). message.should =~ /Not a valid range: three/ end end describe "old edit-method tests now migrated to edit" do describe "on a method defined in a file" do before do @tempfile = (Tempfile.new(['pry', '.rb'])) @tempfile.puts <<-EOS module A def a :yup end def b :kinda end end class X include A def self.x :double_yup end def x :nope end def b super end alias c b def y? :because end class B G = :nawt def foo :possibly G end end end EOS @tempfile.flush load @tempfile.path @tempfile_path = @tempfile.path end after do @tempfile.close(true) end describe 'without -p' do before do @file = @line = @contents = nil Pry.config.editor = lambda do |file, line| @file = file; @line = line nil end end it "should correctly find a class method" do pry_eval 'edit X.x' @file.should == @tempfile_path @line.should == 14 end it "should correctly find an instance method" do pry_eval 'edit X#x' @file.should == @tempfile_path @line.should == 18 end it "should correctly find a method on an instance" do pry_eval 'x = X.new', 'edit x.x' @file.should == @tempfile_path @line.should == 18 end it "should correctly find a method from a module" do pry_eval 'edit X#a' @file.should == @tempfile_path @line.should == 2 end it "should correctly find an aliased method" do pry_eval 'edit X#c' @file.should == @tempfile_path @line.should == 22 end end describe 'with -p' do before do Pry.config.editor = lambda do |file, line| lines = File.read(file).lines.to_a lines[1] = ":maybe\n" File.open(file, 'w') do |f| f.write(lines.join) end @patched_def = String(lines[1]).chomp nil end end it "should successfully replace a class method" do pry_eval 'edit -p X.x' class << X X.method(:x).owner.should == self end X.method(:x).receiver.should == X X.x.should == :maybe end it "should successfully replace an instance method" do pry_eval 'edit -p X#x' X.instance_method(:x).owner.should == X X.new.x.should == :maybe end it "should successfully replace a method on an instance" do pry_eval 'instance = X.new', 'edit -p instance.x' instance = X.new instance.method(:x).owner.should == X instance.x.should == :maybe end it "should successfully replace a method from a module" do pry_eval 'edit -p X#a' X.instance_method(:a).owner.should == A X.new.a.should == :maybe end it "should successfully replace a method with a question mark" do pry_eval 'edit -p X#y?' X.instance_method(:y?).owner.should == X X.new.y?.should == :maybe end it "should preserve module nesting" do pry_eval 'edit -p X::B#foo' X::B.instance_method(:foo).owner.should == X::B X::B.new.foo.should == :nawt end describe "monkey-patching" do before do @edit = 'edit --patch ' # A shortcut. end # @param [Integer] lineno # @return [String] the stripped line from the tempfile at +lineno+ def stripped_line_at(lineno) @tempfile.rewind @tempfile.lines.to_a[lineno].strip end # Applies the monkey patch for +method+ with help of evaluation of # +eval_strs+. The idea is to capture the initial line number (before # the monkey patch), because it gets overwritten by the line number from # the monkey patch. And our goal is to check that the original # definition hasn't changed. # @param [UnboundMethod] method # @param [Array] eval_strs # @return [Array { :test_local => :john } ) end o.instance_variable_get(:@value).should == :john end it 'should define multiple sticky locals' do o = Object.new redirect_pry_io(InputTester.new("@value1 = test_local1", "@value2 = test_local2", "exit-all")) do Pry.start(o, :extra_sticky_locals => { :test_local1 => :john , :test_local2 => :carl} ) end o.instance_variable_get(:@value1).should == :john o.instance_variable_get(:@value2).should == :carl end it 'should define a new sticky local for the session (as Proc)' do o = Object.new redirect_pry_io(InputTester.new("@value = test_local", "exit-all")) do Pry.start(o, :extra_sticky_locals => { :test_local => proc { :john }} ) end o.instance_variable_get(:@value).should == :john end end describe "hash option value should override config value" do it 'should define a new sticky local for the session (normal value)' do Pry.config.extra_sticky_locals[:test_local] = :john o = Object.new redirect_pry_io(InputTester.new("@value = test_local", "exit-all")) do Pry.start(o, :extra_sticky_locals => { :test_local => :carl }) end o.instance_variable_get(:@value).should == :carl Pry.config.extra_sticky_locals = {} end end it 'should create a new sticky local' do o = Object.new pi = Pry.new pi.add_sticky_local(:test_local) { :test_value } pi.input, pi.output = InputTester.new("@value = test_local", "exit-all"), StringIO.new pi.repl(o) o.instance_variable_get(:@value).should == :test_value end it 'should still exist after cd-ing into new binding' do o = Object.new o2 = Object.new o.instance_variable_set(:@o2, o2) pi = Pry.new pi.add_sticky_local(:test_local) { :test_value } pi.input = InputTester.new("cd @o2\n", "@value = test_local", "exit-all") pi.output = StringIO.new pi.repl(o) o2.instance_variable_get(:@value).should == :test_value end it 'should provide different values for successive block invocations' do pry = Pry.new pry.add_sticky_local(:test_local) { rand } value1 = pry.evaluate_ruby 'test_local' value2 = pry.evaluate_ruby 'test_local' value1.should.not == value2 end end end pry-0.9.12.6/spec/command_integration_spec.rb0000644000004100000410000004434612272154172021141 0ustar www-datawww-datarequire 'helper' describe "commands" do before do @str_output = StringIO.new @o = Object.new # Shortcuts. They save a lot of typing. @bs1 = "Pad.bs1 = _pry_.binding_stack.dup" @bs2 = "Pad.bs2 = _pry_.binding_stack.dup" @bs3 = "Pad.bs3 = _pry_.binding_stack.dup" @self = "Pad.self = self" @command_tester = Pry::CommandSet.new do command "command1", "command 1 test" do output.puts "command1" end command "command2", "command 2 test" do |arg| output.puts arg end end Pad.bong = "bong" end after do Pad.clear end describe "alias_command" do it 'should make an aliasd command behave like its original' do set = Pry::CommandSet.new do command "test-command" do output.puts "testing 1, 2, 3" end alias_command "test-alias", "test-command" end redirect_pry_io(InputTester.new("test-alias"), out1 = StringIO.new) do Pry.start self, :commands => set end redirect_pry_io(InputTester.new("test-command"), out2 = StringIO.new) do Pry.start self, :commands => set end out1.string.should == out2.string end it 'should pass on arguments to original' do set = Pry::CommandSet.new do command "test-command" do |*args| output.puts "testing #{args.join(' ')}" end alias_command "test-alias", "test-command" end t = pry_tester(:commands => set) t.process_command "test-alias hello baby duck" t.last_output.should =~ /testing hello baby duck/ end it 'should pass option arguments to original' do set = Pry::CommandSet.new do import Pry::Commands alias_command "test-alias", "ls" end obj = Class.new { @x = 10 } t = pry_tester(obj, :commands => set) t.process_command "test-alias -i" t.last_output.should =~ /@x/ end it 'should pass option arguments to original with additional parameters' do set = Pry::CommandSet.new do import Pry::Commands alias_command "test-alias", "ls -M" end obj = Class.new { @x = Class.new { define_method(:plymouth) {} } } t = pry_tester(obj, :commands => set) t.process_command "test-alias @x" t.last_output.should =~ /plymouth/ end it 'should be able to alias a regex command' do set = Pry::CommandSet.new do command /du.k/ do output.puts "ducky" end alias_command "test-alias", "duck" end t = pry_tester(:commands => set) t.process_command "test-alias" t.last_output.should =~ /ducky/ end it 'should be able to make the alias a regex' do set = Pry::CommandSet.new do command /du.k/ do output.puts "ducky" end alias_command /test-ali.s/, "duck" end redirect_pry_io(InputTester.new("test-alias"), out1 = StringIO.new) do Pry.start self, :commands => set end out1.string.should =~ /ducky/ end end describe "Pry::Command#run" do it 'should allow running of commands with following whitespace' do set = Pry::CommandSet.new do import Pry::Commands command "test-run" do run "cd / " end end redirect_pry_io(InputTester.new("cd 1/2/3/4/5/6", @bs1, "test-run", @self, @bs2, "exit-all")) do Pry.start(@o, :commands => set) end Pad.bs1.size.should == 7 Pad.self.should == @o Pad.bs2.size.should == 1 end it 'should allow running of cd command when contained in a single string' do set = Pry::CommandSet.new do import Pry::Commands command "test-run" do run "cd /" end end redirect_pry_io(InputTester.new("cd 1/2/3/4/5/6", @bs1, "test-run", @self, @bs2, "exit-all")) do Pry.start(@o, :commands => set) end Pad.bs1.size.should == 7 Pad.self.should == @o Pad.bs2.size.should == 1 end it 'should allow running of cd command when split into array' do set = Pry::CommandSet.new do import Pry::Commands command "test-run" do run "cd", "/" end end redirect_pry_io(InputTester.new("cd 1/2/3/4/5/6", @bs1, "test-run", @self, @bs2, "exit-all")) do Pry.start(@o, :commands => set) end Pad.bs1.size.should == 7 Pad.self.should == @o Pad.bs2.size.should == 1 end it 'should run a command from within a command' do klass = Pry::CommandSet.new do command "v" do output.puts "v command" end command "run_v" do run "v" end end Pry.new(:input => InputTester.new("run_v"), :output => @str_output, :commands => klass).rep @str_output.string.should =~ /v command/ end it 'should run a regex command from within a command' do klass = Pry::CommandSet.new do command /v(.*)?/ do |arg| output.puts "v #{arg}" end command "run_v" do run "vbaby" end end redirect_pry_io(InputTester.new("run_v"), @str_output) do Pry.new(:commands => klass).rep end @str_output.string.should =~ /v baby/ end it 'should run a command from within a command with arguments' do klass = Pry::CommandSet.new do command /v(\w+)/ do |arg1, arg2| output.puts "v #{arg1} #{arg2}" end command "run_v_explicit_parameter" do run "vbaby", "param" end command "run_v_embedded_parameter" do run "vbaby param" end end ["run_v_explicit_parameter", "run_v_embedded_parameter"].each do |cmd| redirect_pry_io(InputTester.new(cmd), @str_output) do Pry.new(:commands => klass).rep end @str_output.string.should =~ /v baby param/ end end end describe "Pry#run_command" do it 'should run a command in a specified context' do b = Pry.binding_for('seven') p = Pry.new(:output => @str_output) p.run_command("ls -m", "", b) p.output.string.should =~ /downcase/ end it 'should run a command that modifies the passed in eval_string' do b = Pry.binding_for(7) p = Pry.new(:output => @str_output) eval_string = "def hello\npeter pan\n" p.run_command("amend-line !", eval_string, b) eval_string.should =~ /def hello/ eval_string.should.not =~ /peter pan/ end it 'should run a command in the context of a session' do pry_tester.tap do |t| t.eval "@session_ivar = 10", "_pry_.run_command('ls')" t.last_output.should =~ /@session_ivar/ end end end it 'should interpolate ruby code into commands' do set = Pry::CommandSet.new do command "hello", "", :keep_retval => true do |arg| arg end end str_input = StringIO.new('hello #{Pad.bong}') Pry.new(:input => str_input, :output => @str_output, :commands => set).rep @str_output.string.should =~ /bong/ end # bug fix for https://github.com/pry/pry/issues/170 it 'should not choke on complex string interpolation when checking if ruby code is a command' do redirect_pry_io(InputTester.new('/#{Regexp.escape(File.expand_path("."))}/'), @str_output) do pry end @str_output.string.should.not =~ /SyntaxError/ end it 'should NOT interpolate ruby code into commands if :interpolate => false' do set = Pry::CommandSet.new do command "hello", "", :keep_retval => true, :interpolate => false do |arg| arg end end str_input = StringIO.new('hello #{Pad.bong}') Pry.new(:input => str_input, :output => @str_output, :commands => set).rep @str_output.string.should =~ /Pad\.bong/ end it 'should NOT try to interpolate pure ruby code (no commands) ' do Pry.new(:input => StringIO.new('format \'#{aggy}\''), :output => @str_output).rep @str_output.string.should.not =~ /NameError/ @str_output = StringIO.new Pry.new(:input => StringIO.new('format #{aggy}'), :output => @str_output).rep @str_output.string.should.not =~ /NameError/ @str_output = StringIO.new Pad.interp = "bong" Pry.new(:input => StringIO.new('format \'#{Pad.interp}\''), :output => @str_output).rep @str_output.string.should.not =~ /bong/ end it 'should create a command with a space in its name' do set = Pry::CommandSet.new do command "hello baby", "" do output.puts "hello baby command" end end redirect_pry_io(InputTester.new("hello baby", "exit-all"), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello baby command/ end it 'should create a command with a space in its name and pass an argument' do set = Pry::CommandSet.new do command "hello baby", "" do |arg| output.puts "hello baby command #{arg}" end end redirect_pry_io(InputTester.new("hello baby john"), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello baby command john/ end it 'should create a regex command and be able to invoke it' do set = Pry::CommandSet.new do command /hello(.)/, "" do c = captures.first output.puts "hello#{c}" end end redirect_pry_io(InputTester.new("hello1"), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello1/ end it 'should create a regex command and pass captures into the args list before regular arguments' do set = Pry::CommandSet.new do command /hello(.)/, "" do |c1, a1| output.puts "hello #{c1} #{a1}" end end redirect_pry_io(InputTester.new("hello1 baby"), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello 1 baby/ end it 'should create a regex command and interpolate the captures' do set = Pry::CommandSet.new do command /hello (.*)/, "" do |c1| output.puts "hello #{c1}" end end redirect_pry_io(InputTester.new('hello #{Pad.bong}'), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello bong/ end it 'should create a regex command and arg_string should be interpolated' do set = Pry::CommandSet.new do command /hello(\w+)/, "" do |c1, a1, a2, a3| output.puts "hello #{c1} #{a1} #{a2} #{a3}" end end Pad.bing = "bing" Pad.bang = "bang" redirect_pry_io(InputTester.new('hellojohn #{Pad.bing} #{Pad.bong} #{Pad.bang}'), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello john bing bong bang/ end it 'if a regex capture is missing it should be nil' do set = Pry::CommandSet.new do command /hello(.)?/, "" do |c1, a1| output.puts "hello #{c1.inspect} #{a1}" end end redirect_pry_io(InputTester.new("hello baby"), @str_output) do Pry.new(:commands => set).rep end @str_output.string.should =~ /hello nil baby/ end it 'should create a command in a nested context and that command should be accessible from the parent' do x = "@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nexit-all" redirect_pry_io(StringIO.new("@x=nil\ncd 7\n_pry_.commands.instance_eval {\ncommand('bing') { |arg| run arg }\n}\ncd ..\nbing ls\nexit-all"), @str_output) do Pry.new.repl('0') end @str_output.string.should =~ /@x/ end it 'should define a command that keeps its return value' do klass = Pry::CommandSet.new do command "hello", "", :keep_retval => true do :kept_hello end end Pry.new(:input => StringIO.new("hello\n"), :output => @str_output, :commands => klass).rep @str_output.string.should =~ /:kept_hello/ @str_output.string.should =~ /=>/ end it 'should define a command that does NOT keep its return value' do klass = Pry::CommandSet.new do command "hello", "", :keep_retval => false do :kept_hello end end Pry.new(:input => StringIO.new("hello\n"), :output => @str_output, :commands => klass).rep (@str_output.string =~ /:kept_hello/).should == nil @str_output.string !~ /=>/ end it 'should define a command that keeps its return value even when nil' do klass = Pry::CommandSet.new do command "hello", "", :keep_retval => true do nil end end Pry.new(:input => StringIO.new("hello\n"), :output => @str_output, :commands => klass).rep @str_output.string.should =~ /nil/ @str_output.string.should =~ /=>/ end it 'should define a command that keeps its return value but does not return when value is void' do klass = Pry::CommandSet.new do command "hello", "", :keep_retval => true do void end end Pry.new(:input => StringIO.new("hello\n"), :output => @str_output, :commands => klass).rep @str_output.string.empty?.should == true end it 'a command (with :keep_retval => false) that replaces eval_string with a valid expression should not have the expression value suppressed' do klass = Pry::CommandSet.new do command "hello", "" do eval_string.replace("6") end end Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => @str_output, :commands => klass).rep @str_output.string.should =~ /6/ end it 'a command (with :keep_retval => true) that replaces eval_string with a valid expression should overwrite the eval_string with the return value' do klass = Pry::CommandSet.new do command "hello", "", :keep_retval => true do eval_string.replace("6") 7 end end Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => @str_output, :commands => klass).rep @str_output.string.should =~ /7/ @str_output.string.should.not =~ /6/ end it 'a command that return a value in a multi-line expression should clear the expression and return the value' do klass = Pry::CommandSet.new do command "hello", "", :keep_retval => true do 5 end end Pry.new(:input => StringIO.new("def yo\nhello\n"), :output => @str_output, :commands => klass).rep @str_output.string.should =~ /5/ end it 'should set the commands default, and the default should be overridable' do klass = Pry::CommandSet.new do command "hello" do output.puts "hello world" end end Pry.commands = klass Pry.new(:input => InputTester.new("hello"), :output => @str_output).rep @str_output.string.should =~ /hello world/ other_klass = Pry::CommandSet.new do command "goodbye", "" do output.puts "goodbye world" end end @str_output = StringIO.new Pry.new(:input => InputTester.new("goodbye"), :output => @str_output, :commands => other_klass).rep @str_output.string.should =~ /goodbye world/ end it 'should inherit commands from Pry::Commands' do klass = Pry::CommandSet.new Pry::Commands do command "v" do end end klass.commands.include?("nesting").should == true klass.commands.include?("jump-to").should == true klass.commands.include?("cd").should == true klass.commands.include?("v").should == true end it 'should change description of a command using desc' do klass = Pry::CommandSet.new do import Pry::Commands end orig = klass.commands["help"].description klass.instance_eval do desc "help", "blah" end klass.commands["help"].description.should.not == orig klass.commands["help"].description.should == "blah" end it 'should enable an inherited method to access opts and output and target, due to instance_exec' do klass = Pry::CommandSet.new do command "v" do output.puts "#{target.eval('self')}" end end child_klass = Pry::CommandSet.new klass do end Pry.new(:print => proc {}, :input => InputTester.new("v"), :output => @str_output, :commands => child_klass).rep("john") @str_output.string.rstrip.should == "john" end it 'should import commands from another command object' do klass = Pry::CommandSet.new do import_from Pry::Commands, "ls", "jump-to" end klass.commands.include?("ls").should == true klass.commands.include?("jump-to").should == true end it 'should delete some inherited commands when using delete method' do klass = Pry::CommandSet.new Pry::Commands do command "v" do end delete "show-doc", "show-method" delete "ls" end klass.commands.include?("nesting").should == true klass.commands.include?("jump-to").should == true klass.commands.include?("cd").should == true klass.commands.include?("v").should == true klass.commands.include?("show-doc").should == false klass.commands.include?("show-method").should == false klass.commands.include?("ls").should == false end it 'should override some inherited commands' do klass = Pry::CommandSet.new Pry::Commands do command "jump-to" do output.puts "jump-to the music" end command "help" do output.puts "help to the music" end end # suppress evaluation output Pry.print = proc {} Pry.new(:input => InputTester.new("jump-to"), :output => @str_output, :commands => klass).rep @str_output.string.rstrip.should == "jump-to the music" @str_output = StringIO.new Pry.new(:input => InputTester.new("help"), :output => @str_output, :commands => klass).rep @str_output.string.should == "help to the music\n" Pry.reset_defaults Pry.color = false end it 'should run a command with no parameter' do pry_tester = Pry.new pry_tester.commands = @command_tester pry_tester.input = InputTester.new("command1", "exit-all") pry_tester.commands = @command_tester pry_tester.output = @str_output pry_tester.rep @str_output.string.should =~ /command1/ end it 'should run a command with one parameter' do pry_tester = Pry.new pry_tester.commands = @command_tester pry_tester.input = InputTester.new("command2 horsey", "exit-all") pry_tester.commands = @command_tester pry_tester.output = @str_output pry_tester.rep @str_output.string.should =~ /horsey/ end end pry-0.9.12.6/spec/fixtures/0000755000004100000410000000000012272154173015420 5ustar www-datawww-datapry-0.9.12.6/spec/fixtures/candidate_helper1.rb0000644000004100000410000000013112272154173021274 0ustar www-datawww-data# rank 0 class CandidateTest def test1 end def test2 end def test3 end end pry-0.9.12.6/spec/fixtures/example.erb0000644000004100000410000000005712272154173017547 0ustar www-datawww-data Look at me, testing my erb! pry-0.9.12.6/spec/fixtures/whereami_helper.rb0000644000004100000410000000010212272154173021076 0ustar www-datawww-dataclass Cor def a; end def b; end def c; end def d; end end pry-0.9.12.6/spec/fixtures/testrc0000644000004100000410000000007612272154173016652 0ustar www-datawww-dataTEST_RC = [] if !Object.const_defined?(:TEST_RC) TEST_RC << 0 pry-0.9.12.6/spec/fixtures/candidate_helper2.rb0000644000004100000410000000010612272154173021277 0ustar www-datawww-data# rank 1 class CandidateTest def test4 end def test5 end end pry-0.9.12.6/spec/fixtures/show_source_doc_examples.rb0000644000004100000410000000035012272154173023026 0ustar www-datawww-data# used by test_show_source.rb and test_documentation.rb class TestClassForShowSource def alpha end end class TestClassForShowSourceClassEval def alpha end end class TestClassForShowSourceInstanceEval def alpha end end pry-0.9.12.6/spec/fixtures/example_nesting.rb0000644000004100000410000000315012272154173021126 0ustar www-datawww-data # [] class A # ["class A"] def a; end # ["class A"] class B; def b; end; end # ["class A", "class B"] end # [] # [] class << A # ["class << A"] class B # ["class << A", "class B"] def c; end # ["class << A", "class B"] end # ["class << A"] # ["class << A"] module F::B # ["class << A", "module F::B"] def foo; end # ["class << A", "module F::B"] end # ["class << A"] end # [] # [] module (:symbol.class)::Exciting # def foo; end # class B # def goo; end # end # end # [] # [] module C # ["module C"] class D # ["module C", "class D"] def guh; foo.end; end # ["module C", "class D"] end # ["module C"] def bar; :end; end # ["module C"] class << new.bar; end # ["module C"] class << new.bar; def f; end; end # # ["module C"] class << self; def mug; end; end # ["module C", "class << self"] end # [] pry-0.9.12.6/spec/fixtures/testrcbad0000644000004100000410000000005512272154173017316 0ustar www-datawww-dataTEST_BEFORE_RAISE = 1 raise "messin with ya" pry-0.9.12.6/spec/command_helpers_spec.rb0000644000004100000410000000140612272154172020246 0ustar www-datawww-datarequire 'helper' describe Pry::Helpers::CommandHelpers do before do @helper = Pry::Helpers::CommandHelpers end describe "unindent" do it "should remove the same prefix from all lines" do @helper.unindent(" one\n two\n").should == "one\ntwo\n" end it "should not be phased by empty lines" do @helper.unindent(" one\n\n two\n").should == "one\n\ntwo\n" end it "should only remove a common prefix" do @helper.unindent(" one\n two\n").should == " one\ntwo\n" end it "should also remove tabs if present" do @helper.unindent("\tone\n\ttwo\n").should == "one\ntwo\n" end it "should ignore lines starting with --" do @helper.unindent(" one\n--\n two\n").should == "one\n--\ntwo\n" end end end pry-0.9.12.6/spec/hooks_spec.rb0000644000004100000410000004144612272154173016242 0ustar www-datawww-datarequire 'helper' describe Pry::Hooks do before do @hooks = Pry::Hooks.new end describe "adding a new hook" do it 'should not execute hook while adding it' do run = false @hooks.add_hook(:test_hook, :my_name) { run = true } run.should == false end it 'should not allow adding of a hook with a duplicate name' do @hooks.add_hook(:test_hook, :my_name) {} lambda { @hooks.add_hook(:test_hook, :my_name) {} }.should.raise ArgumentError end it 'should create a new hook with a block' do @hooks.add_hook(:test_hook, :my_name) { } @hooks.hook_count(:test_hook).should == 1 end it 'should create a new hook with a callable' do @hooks.add_hook(:test_hook, :my_name, proc { }) @hooks.hook_count(:test_hook).should == 1 end it 'should use block if given both block and callable' do run = false foo = false @hooks.add_hook(:test_hook, :my_name, proc { foo = true }) { run = true } @hooks.hook_count(:test_hook).should == 1 @hooks.exec_hook(:test_hook) run.should == true foo.should == false end it 'should raise if not given a block or any other object' do lambda { @hooks.add_hook(:test_hook, :my_name) }.should.raise ArgumentError end it 'should create multiple hooks for an event' do @hooks.add_hook(:test_hook, :my_name) {} @hooks.add_hook(:test_hook, :my_name2) {} @hooks.hook_count(:test_hook).should == 2 end it 'should return a count of 0 for an empty hook' do @hooks.hook_count(:test_hook).should == 0 end end describe "Pry::Hooks#merge" do describe "merge!" do it 'should merge in the Pry::Hooks' do h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {} h2 = Pry::Hooks.new h2.merge!(h1) h2.get_hook(:test_hook, :testing).should == h1.get_hook(:test_hook, :testing) end it 'should not share merged elements with original' do h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {} h2 = Pry::Hooks.new h2.merge!(h1) h2.add_hook(:test_hook, :testing2) {} h2.get_hook(:test_hook, :testing2).should.not == h1.get_hook(:test_hook, :testing2) end it 'should NOT overwrite hooks belonging to shared event in receiver' do h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {} callable = proc {} h2 = Pry::Hooks.new.add_hook(:test_hook, :testing2, callable) h2.merge!(h1) h2.get_hook(:test_hook, :testing2).should == callable end it 'should overwrite identical hook in receiver' do callable1 = proc { :one } h1 = Pry::Hooks.new.add_hook(:test_hook, :testing, callable1) callable2 = proc { :two } h2 = Pry::Hooks.new.add_hook(:test_hook, :testing, callable2) h2.merge!(h1) h2.get_hook(:test_hook, :testing).should == callable1 h2.hook_count(:test_hook).should == 1 end it 'should preserve hook order' do name = "" h1 = Pry::Hooks.new h1.add_hook(:test_hook, :testing3) { name << "h" } h1.add_hook(:test_hook, :testing4) { name << "n" } h2 = Pry::Hooks.new h2.add_hook(:test_hook, :testing1) { name << "j" } h2.add_hook(:test_hook, :testing2) { name << "o" } h2.merge!(h1) h2.exec_hook(:test_hook) name.should == "john" end describe "merge" do it 'should return a fresh, independent instance' do h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {} h2 = Pry::Hooks.new h3 = h2.merge(h1) h3.should.not == h1 h3.should.not == h2 end it 'should contain hooks from original instance' do h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {} h2 = Pry::Hooks.new.add_hook(:test_hook2, :testing) {} h3 = h2.merge(h1) h3.get_hook(:test_hook, :testing).should == h1.get_hook(:test_hook, :testing) h3.get_hook(:test_hook2, :testing).should == h2.get_hook(:test_hook2, :testing) end it 'should not affect original instances when new hooks are added' do h1 = Pry::Hooks.new.add_hook(:test_hook, :testing) {} h2 = Pry::Hooks.new.add_hook(:test_hook2, :testing) {} h3 = h2.merge(h1) h3.add_hook(:test_hook3, :testing) {} h1.get_hook(:test_hook3, :testing).should == nil h2.get_hook(:test_hook3, :testing).should == nil end end end end describe "dupping a Pry::Hooks instance" do it 'should share hooks with original' do @hooks.add_hook(:test_hook, :testing) do :none_such end hooks_dup = @hooks.dup hooks_dup.get_hook(:test_hook, :testing).should == @hooks.get_hook(:test_hook, :testing) end it 'adding a new event to dupped instance should not affect original' do @hooks.add_hook(:test_hook, :testing) { :none_such } hooks_dup = @hooks.dup hooks_dup.add_hook(:other_test_hook, :testing) { :okay_man } hooks_dup.get_hook(:other_test_hook, :testing).should.not == @hooks.get_hook(:other_test_hook, :testing) end it 'adding a new hook to dupped instance should not affect original' do @hooks.add_hook(:test_hook, :testing) { :none_such } hooks_dup = @hooks.dup hooks_dup.add_hook(:test_hook, :testing2) { :okay_man } hooks_dup.get_hook(:test_hook, :testing2).should.not == @hooks.get_hook(:test_hook, :testing2) end end describe "getting hooks" do describe "get_hook" do it 'should return the correct requested hook' do run = false fun = false @hooks.add_hook(:test_hook, :my_name) { run = true } @hooks.add_hook(:test_hook, :my_name2) { fun = true } @hooks.get_hook(:test_hook, :my_name).call run.should == true fun.should == false end it 'should return nil if hook does not exist' do @hooks.get_hook(:test_hook, :my_name).should == nil end end describe "get_hooks" do it 'should return a hash of hook names/hook functions for an event' do hook1 = proc { 1 } hook2 = proc { 2 } @hooks.add_hook(:test_hook, :my_name1, hook1) @hooks.add_hook(:test_hook, :my_name2, hook2) hash = @hooks.get_hooks(:test_hook) hash.size.should == 2 hash[:my_name1].should == hook1 hash[:my_name2].should == hook2 end it 'should return an empty hash if no hooks defined' do @hooks.get_hooks(:test_hook).should == {} end end end describe "clearing all hooks for an event" do it 'should clear all hooks' do @hooks.add_hook(:test_hook, :my_name) { } @hooks.add_hook(:test_hook, :my_name2) { } @hooks.add_hook(:test_hook, :my_name3) { } @hooks.clear(:test_hook) @hooks.hook_count(:test_hook).should == 0 end end describe "deleting a hook" do it 'should successfully delete a hook' do @hooks.add_hook(:test_hook, :my_name) {} @hooks.delete_hook(:test_hook, :my_name) @hooks.hook_count(:test_hook).should == 0 end it 'should return the deleted hook' do run = false @hooks.add_hook(:test_hook, :my_name) { run = true } @hooks.delete_hook(:test_hook, :my_name).call run.should == true end it 'should return nil if hook does not exist' do @hooks.delete_hook(:test_hook, :my_name).should == nil end end describe "executing a hook" do it 'should execute block hook' do run = false @hooks.add_hook(:test_hook, :my_name) { run = true } @hooks.exec_hook(:test_hook) run.should == true end it 'should execute proc hook' do run = false @hooks.add_hook(:test_hook, :my_name, proc { run = true }) @hooks.exec_hook(:test_hook) run.should == true end it 'should execute a general callable hook' do callable = Object.new.tap do |obj| obj.instance_variable_set(:@test_var, nil) class << obj attr_accessor :test_var def call() @test_var = true; end end end @hooks.add_hook(:test_hook, :my_name, callable) @hooks.exec_hook(:test_hook) callable.test_var.should == true end it 'should execute all hooks for an event if more than one is defined' do x = nil y = nil @hooks.add_hook(:test_hook, :my_name1) { y = true } @hooks.add_hook(:test_hook, :my_name2) { x = true } @hooks.exec_hook(:test_hook) x.should == true y.should == true end it 'should execute hooks in order' do array = [] @hooks.add_hook(:test_hook, :my_name1) { array << 1 } @hooks.add_hook(:test_hook, :my_name2) { array << 2 } @hooks.add_hook(:test_hook, :my_name3) { array << 3 } @hooks.exec_hook(:test_hook) array.should == [1, 2, 3] end it 'return value of exec_hook should be that of last executed hook' do @hooks.add_hook(:test_hook, :my_name1) { 1 } @hooks.add_hook(:test_hook, :my_name2) { 2 } @hooks.add_hook(:test_hook, :my_name3) { 3 } @hooks.exec_hook(:test_hook).should == 3 end it 'should add exceptions to the errors array' do @hooks.add_hook(:test_hook, :foo1) { raise 'one' } @hooks.add_hook(:test_hook, :foo2) { raise 'two' } @hooks.add_hook(:test_hook, :foo3) { raise 'three' } @hooks.exec_hook(:test_hook) @hooks.errors.map(&:message).should == ['one', 'two', 'three'] end it 'should return the last exception raised as the return value' do @hooks.add_hook(:test_hook, :foo1) { raise 'one' } @hooks.add_hook(:test_hook, :foo2) { raise 'two' } @hooks.add_hook(:test_hook, :foo3) { raise 'three' } @hooks.exec_hook(:test_hook).should == @hooks.errors.last end end describe "integration tests" do describe "when_started hook" do it 'should yield options to the hook' do options = nil Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| options = opt } redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do Pry.start binding, :hello => :baby end options[:hello].should == :baby Pry.config.hooks.delete_hook(:when_started, :test_hook) end describe "target" do it 'should yield the target, as a binding ' do b = nil Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| b = target } redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do Pry.start 5, :hello => :baby end b.is_a?(Binding).should == true Pry.config.hooks.delete_hook(:when_started, :test_hook) end it 'should yield the target to the hook' do b = nil Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _| b = target } redirect_pry_io(StringIO.new("exit"), out=StringIO.new) do Pry.start 5, :hello => :baby end b.eval('self').should == 5 Pry.config.hooks.delete_hook(:when_started, :test_hook) end end it 'should allow overriding of target (and binding_stack)' do options = nil o = Object.new class << o; attr_accessor :value; end Pry.config.hooks.add_hook(:when_started, :test_hook) { |target, opt, _pry_| _pry_.binding_stack = [Pry.binding_for(o)] } redirect_pry_io(InputTester.new("@value = true","exit-all")) do Pry.start binding, :hello => :baby end o.value.should == true Pry.config.hooks.delete_hook(:when_started, :test_hook) end end describe "after_session hook" do it 'should always run, even if uncaught exception bubbles out of repl' do o = OpenStruct.new o.great_escape = Class.new(StandardError) old_ew = Pry.config.exception_whitelist Pry.config.exception_whitelist << o.great_escape array = [1, 2, 3, 4, 5] begin redirect_pry_io(StringIO.new("raise great_escape"), out=StringIO.new) do Pry.start o, :hooks => Pry::Hooks.new.add_hook(:after_session, :cleanup) { array = nil } end rescue => ex exception = ex end # ensure that an exception really was raised and it broke out # of the repl exception.is_a?(o.great_escape).should == true # check that after_session hook ran array.should == nil # cleanup after test Pry.config.exception_whitelist = old_ew end describe "before_eval hook" do describe "modifying input code" do it 'should replace input code with code determined by hook' do hooks = Pry::Hooks.new.add_hook(:before_eval, :quirk) { |code, pry| code.replace(":little_duck") } redirect_pry_io(InputTester.new(":jemima", "exit-all"), out = StringIO.new) do Pry.start(self, :hooks => hooks) end out.string.should =~ /little_duck/ out.string.should.not =~ /jemima/ end it 'should not interfere with command processing when replacing input code' do commands = Pry::CommandSet.new do import_from Pry::Commands, "exit-all" command "how-do-you-like-your-blue-eyed-boy-now-mister-death" do output.puts "in hours of bitterness i imagine balls of sapphire, of metal" end end hooks = Pry::Hooks.new.add_hook(:before_eval, :quirk) { |code, pry| code.replace(":little_duck") } redirect_pry_io(InputTester.new("how-do-you-like-your-blue-eyed-boy-now-mister-death", "exit-all"), out = StringIO.new) do Pry.start(self, :hooks => hooks, :commands => commands) end out.string.should =~ /in hours of bitterness i imagine balls of sapphire, of metal/ out.string.should.not =~ /little_duck/ end end end describe "exceptions" do before do Pry.config.hooks.add_hook(:after_eval, :baddums){ raise "Baddums" } Pry.config.hooks.add_hook(:after_eval, :simbads){ raise "Simbads" } end after do Pry.config.hooks.delete_hook(:after_eval, :baddums) Pry.config.hooks.delete_hook(:after_eval, :simbads) end it "should not raise exceptions" do lambda{ mock_pry("1", "2", "3") }.should.not.raise end it "should print out a notice for each exception raised" do mock_pry("1").should =~ /after_eval hook failed: RuntimeError: Baddums\n.*after_eval hook failed: RuntimeError: Simbads/m end end end end describe "anonymous hooks" do it 'should allow adding of hook without a name' do @hooks.add_hook(:test_hook, nil) {} @hooks.hook_count(:test_hook).should == 1 end it 'should only allow one anonymous hook to exist' do @hooks.add_hook(:test_hook, nil) { } @hooks.add_hook(:test_hook, nil) { } @hooks.hook_count(:test_hook).should == 1 end it 'should execute most recently added anonymous hook' do x = nil y = nil @hooks.add_hook(:test_hook, nil) { y = 1 } @hooks.add_hook(:test_hook, nil) { x = 2 } @hooks.exec_hook(:test_hook) y.should == nil x.should == 2 end end describe "deprecated hash-based API" do after do Pry.config.hooks.clear_all if Pry.config.hooks end describe "Pry.config.hooks" do it 'should allow a hash-assignment' do Pry.config.hooks = { :before_session => proc { :hello } } Pry.config.hooks.get_hook(:before_session, nil).call.should == :hello end describe "Pry.config.hooks[]" do it 'should return the only anonymous hook' do Pry.config.hooks = { :before_session => proc { :hello } } Pry.config.hooks[:before_session].call.should == :hello end it 'should add an anonymous hook when using Pry.config.hooks[]=' do Pry.config.hooks[:before_session] = proc { :bing } Pry.config.hooks.hook_count(:before_session).should == 1 end it 'should add overwrite previous anonymous hooks with new one when calling Pry.config.hooks[]= multiple times' do x = nil Pry.config.hooks[:before_session] = proc { x = 1 } Pry.config.hooks[:before_session] = proc { x = 2 } Pry.config.hooks.exec_hook(:before_session) Pry.config.hooks.hook_count(:before_session).should == 1 x.should == 2 end end end describe "Pry.start" do it 'should accept a hash for :hooks parameter' do redirect_pry_io(InputTester.new("exit-all"), out=StringIO.new) do Pry.start binding, :hooks => { :before_session => proc { |output, _, _| output.puts 'hello friend' } } end out.string.should =~ /hello friend/ end end end end pry-0.9.12.6/spec/indent_spec.rb0000644000004100000410000001432112272154173016370 0ustar www-datawww-datarequire 'helper' # Please keep in mind that any hash signs ("#") in the heredoc strings are # placed on purpose. Without these editors might remove the whitespace on empty # lines. describe Pry::Indent do before do @indent = Pry::Indent.new end it 'should indent an array' do input = "array = [\n10,\n15\n]" output = "array = [\n 10,\n 15\n]" @indent.indent(input).should == output end it 'should indent a hash' do input = "hash = {\n:name => 'Ruby'\n}" output = "hash = {\n :name => 'Ruby'\n}" @indent.indent(input).should == output end it 'should indent a function' do input = "def\nreturn 10\nend" output = "def\n return 10\nend" @indent.indent(input).should == output end it 'should indent a module and class' do input = "module Foo\n# Hello world\nend" output = "module Foo\n # Hello world\nend" input_class = "class Foo\n# Hello world\nend" output_class = "class Foo\n # Hello world\nend" @indent.indent(input).should == output @indent.indent(input_class).should == output_class end it 'should indent separate lines' do @indent.indent('def foo').should == 'def foo' @indent.indent('return 10').should == ' return 10' @indent.indent('end').should == 'end' end it 'should not indent single line statements' do input = < do" do input = "while 5 do\n5\nend" @indent.indent(input).should == "while 5 do\n 5\nend" end it "should ident case statements" do input = <\n[]}]\n]").should == "[[{\n [] =>\n []}]\n]" end it "should not indent single-line ifs" do @indent.indent("foo if bar\n#").should == "foo if bar\n#" @indent.reset.indent("foo() if bar\n#").should == "foo() if bar\n#" @indent.reset.indent("foo 'hi' if bar\n#").should == "foo 'hi' if bar\n#" @indent.reset.indent("foo 1 while bar\n#").should == "foo 1 while bar\n#" @indent.reset.indent("super if true\n#").should == "super if true\n#" @indent.reset.indent("true if false\n#").should == "true if false\n#" @indent.reset.indent("String if false\n#").should == "String if false\n#" end it "should indent cunningly disguised ifs" do @indent.indent("{1 => if bar\n#").should == "{1 => if bar\n #" @indent.reset.indent("foo(if bar\n#").should == "foo(if bar\n #" @indent.reset.indent("bar(baz, if bar\n#").should == "bar(baz, if bar\n #" @indent.reset.indent("[if bar\n#").should == "[if bar\n #" @indent.reset.indent("true; while bar\n#").should == "true; while bar\n #" end it "should differentiate single/multi-line unless" do @indent.indent("foo unless bar\nunless foo\nbar\nend").should == "foo unless bar\nunless foo\n bar\nend" end it "should not indent single/multi-line until" do @indent.indent("%w{baz} until bar\nuntil foo\nbar\nend").should == "%w{baz} until bar\nuntil foo\n bar\nend" end it "should indent begin rescue end" do input = < :wrong rescue => e doit :right end INPUT output = < :wrong rescue => e doit :right end OUTPUT @indent.indent(input).should == output end it "should not indent inside strings" do @indent.indent(%(def a\n"foo\nbar"\n end)).should == %(def a\n "foo\nbar"\nend) @indent.indent(%(def a\nputs %w(foo\nbar), 'foo\nbar'\n end)).should == %(def a\n puts %w(foo\nbar), 'foo\nbar'\nend) end it "should not indent inside HEREDOCs" do @indent.indent(%(def a\nputs < true/m end it "should allow whitespace delimeted strings" do mock_pry('"%s" %% foo ').should =~ /"foo"/ end it "should allow newline delimeted strings" do mock_pry('"%s" %%','foo').should =~ /"foo"/ end it "should allow whitespace delimeted strings ending on the first char of a line" do mock_pry('"%s" %% ', ' #done!').should =~ /"\\n"/ end end pry-0.9.12.6/spec/Procfile0000644000004100000410000000015412272154172015234 0ustar www-datawww-data# Run this with: # gem install foreman && foreman start -f spec/Procfile pryhere: sh -c '(cd ..; rake pry)' pry-0.9.12.6/spec/input_stack_spec.rb0000644000004100000410000000566412272154173017445 0ustar www-datawww-data# coding: utf-8 require 'helper' describe "Pry#input_stack" do before do @str_output = StringIO.new end it 'should accept :input_stack as a config option' do stack = [StringIO.new("test")] Pry.new(:input_stack => stack).input_stack.should == stack end it 'should use defaults from Pry.config' do Pry.config.input_stack = [StringIO.new("exit")] Pry.new.input_stack.should == Pry.config.input_stack Pry.config.input_stack = [] end it 'should read from all input objects on stack and exit session (usingn repl)' do stack = [b = StringIO.new(":cloister\nexit\n"), c = StringIO.new(":baron\n")] instance = Pry.new(:input => StringIO.new(":alex\n"), :output => @str_output, :input_stack => stack) instance.repl @str_output.string.should =~ /:alex/ @str_output.string.should =~ /:baron/ @str_output.string.should =~ /:cloister/ end it 'input objects should be popped off stack as they are used up' do stack = [StringIO.new(":cloister\n"), StringIO.new(":baron\n")] instance = Pry.new(:input => StringIO.new(":alex\n"), :output => @str_output, :input_stack => stack) stack.size.should == 2 instance.rep @str_output.string.should =~ /:alex/ instance.rep @str_output.string.should =~ /:baron/ stack.size.should == 1 instance.rep @str_output.string.should =~ /:cloister/ stack.size.should == 0 end it 'should revert to Pry.config.input when it runs out of input objects in input_stack' do redirect_pry_io(StringIO.new(":rimbaud\nexit\n"), StringIO.new) do stack = [StringIO.new(":cloister\n"), StringIO.new(":baron\n")] instance = Pry.new(:input => StringIO.new(":alex\n"), :output => @str_output, :input_stack => stack) instance.repl @str_output.string.should =~ /:alex/ @str_output.string.should =~ /:baron/ @str_output.string.should =~ /:cloister/ @str_output.string.should =~ /:rimbaud/ end end it 'should display error and throw(:breakout) if at end of input after using up input_stack objects' do catch(:breakout) do redirect_pry_io(StringIO.new(":rimbaud\n"), @str_output) do Pry.new(:input_stack => [StringIO.new(":a\n"), StringIO.new(":b\n")]).repl end end @str_output.string.should =~ /Error: Pry ran out of things to read/ end if "".respond_to?(:encoding) after do Pry.line_buffer = [""] Pry.current_line = 1 end it "should pass strings to Pry in the right encoding" do input1 = "'f。。'.encoding.name" # utf-8, see coding declaration input2 = input1.encode('Shift_JIS') mock_pry(input1, input2).should == %{=> "UTF-8"\n=> "Shift_JIS"\n\n} end it "should be able to use unicode regexes on a UTF-8 terminal" do mock_pry('":-Þ" =~ /þ/i').should == %{=> 2\n\n} end end end pry-0.9.12.6/spec/command_spec.rb0000644000004100000410000005751412272154172016537 0ustar www-datawww-datarequire 'helper' describe "Pry::Command" do before do @set = Pry::CommandSet.new @set.import Pry::Commands end describe 'call_safely' do it 'should display a message if gems are missing' do cmd = @set.create_command "ford-prefect", "From a planet near Beetlegeuse", :requires_gem => %w(ghijkl) do # end mock_command(cmd, %w(hello world)).output.should =~ /install-command ford-prefect/ end it 'should abort early if arguments are required' do cmd = @set.create_command 'arthur-dent', "Doesn't understand Thursdays", :argument_required => true do # end lambda { mock_command(cmd, %w()) }.should.raise(Pry::CommandError) end it 'should return VOID without keep_retval' do cmd = @set.create_command 'zaphod-beeblebrox', "Likes pan-Galactic Gargle Blasters" do def process 3 end end mock_command(cmd).return.should == Pry::Command::VOID_VALUE end it 'should return the return value with keep_retval' do cmd = @set.create_command 'tricia-mcmillian', "a.k.a Trillian", :keep_retval => true do def process 5 end end mock_command(cmd).return.should == 5 end it 'should call hooks in the right order' do cmd = @set.create_command 'marvin', "Pained by the diodes in his left side" do def process output.puts 3 + args[0].to_i end end @set.before_command 'marvin' do |i| output.puts 2 + i.to_i end @set.before_command 'marvin' do |i| output.puts 1 + i.to_i end @set.after_command 'marvin' do |i| output.puts 4 + i.to_i end @set.after_command 'marvin' do |i| output.puts 5 + i.to_i end mock_command(cmd, %w(2)).output.should == "3\n4\n5\n6\n7\n" end # TODO: This strikes me as rather silly... it 'should return the value from the last hook with keep_retval' do cmd = @set.create_command 'slartibartfast', "Designs Fjords", :keep_retval => true do def process 22 end end @set.after_command 'slartibartfast' do 10 end mock_command(cmd).return.should == 10 end end describe 'help' do it 'should default to the description for blocky commands' do @set.command 'oolon-colluphid', "Raving Atheist" do # end mock_command(@set.commands['help'], %w(oolon-colluphid), :command_set => @set).output.should =~ /Raving Atheist/ end it 'should use slop to generate the help for classy commands' do @set.create_command 'eddie', "The ship-board computer" do def options(opt) opt.banner "Over-cheerful, and makes a ticking noise." end end mock_command(@set.commands['help'], %w(eddie), :command_set => @set).output.should =~ /Over-cheerful/ end it 'should provide --help for classy commands' do cmd = @set.create_command 'agrajag', "Killed many times by Arthur" do def options(opt) opt.on :r, :retaliate, "Try to get Arthur back" end end mock_command(cmd, %w(--help)).output.should =~ /--retaliate/ end it 'should provide a -h for classy commands' do cmd = @set.create_command 'zarniwoop', "On an intergalactic cruise, in his office." do def options(opt) opt.on :e, :escape, "Help zaphod escape the Total Perspective Vortex" end end mock_command(cmd, %w(--help)).output.should =~ /Total Perspective Vortex/ end it 'should use the banner provided' do cmd = @set.create_command 'deep-thought', "The second-best computer ever" do banner <<-BANNER Who's merest operational parameters, I am not worthy to compute. BANNER end mock_command(cmd, %w(--help)).output.should =~ /Who\'s merest/ end end describe 'context' do context = { :target => binding, :output => StringIO.new, :eval_string => "eval-string", :command_set => @set, :pry_instance => Object.new } it 'should capture lots of stuff from the hash passed to new before setup' do cmd = @set.create_command 'fenchurch', "Floats slightly off the ground" do define_method(:setup) do self.context.should == context target.should == context[:target] target_self.should == context[:target].eval('self') output.should == context[:output] end define_method(:process) do eval_string.should == "eval-string" command_set.should == @set _pry_.should == context[:pry_instance] end end cmd.new(context).call end end describe 'classy api' do it 'should call setup, then subcommands, then options, then process' do cmd = @set.create_command 'rooster', "Has a tasty towel" do def setup output.puts "setup" end def subcommands(cmd) output.puts "subcommands" end def options(opt) output.puts "options" end def process output.puts "process" end end mock_command(cmd).output.should == "setup\nsubcommands\noptions\nprocess\n" end it 'should raise a command error if process is not overridden' do cmd = @set.create_command 'jeltz', "Commander of a Vogon constructor fleet" do def proccces # end end lambda { mock_command(cmd) }.should.raise(Pry::CommandError) end it 'should work if neither options, nor setup is overridden' do cmd = @set.create_command 'wowbagger', "Immortal, insulting.", :keep_retval => true do def process 5 end end mock_command(cmd).return.should == 5 end it 'should provide opts and args as provided by slop' do cmd = @set.create_command 'lintilla', "One of 800,000,000 clones" do def options(opt) opt.on :f, :four, "A numeric four", :as => Integer, :optional_argument => true end def process args.should == ['four'] opts[:f].should == 4 end end mock_command(cmd, %w(--four 4 four)) end it 'should allow overriding options after definition' do cmd = @set.create_command /number-(one|two)/, "Lieutenants of the Golgafrinchan Captain", :shellwords => false do command_options :listing => 'number-one' end cmd.command_options[:shellwords].should == false cmd.command_options[:listing].should == 'number-one' end it "should create subcommands" do cmd = @set.create_command 'mum', 'Your mum' do def subcommands(cmd) cmd.command :yell end def process opts.fetch_command(:blahblah).should == nil opts.fetch_command(:yell).present?.should == true end end mock_command(cmd, ['yell']) end it "should create subcommand options" do cmd = @set.create_command 'mum', 'Your mum' do def subcommands(cmd) cmd.command :yell do on :p, :person end end def process args.should == ['papa'] opts.fetch_command(:yell).present?.should == true opts.fetch_command(:yell).person?.should == true end end mock_command(cmd, %w|yell --person papa|) end it "should accept top-level arguments" do cmd = @set.create_command 'mum', 'Your mum' do def subcommands(cmd) cmd.on :yell end def process args.should == ['yell', 'papa', 'sonny', 'daughter'] end end mock_command(cmd, %w|yell papa sonny daughter|) end describe "explicit classes" do before do @x = Class.new(Pry::ClassCommand) do options :baby => :pig match /goat/ description "waaaninngggiiigygygygygy" end end it 'subclasses should inherit options, match and description from superclass' do k = Class.new(@x) k.options.should == @x.options k.match.should == @x.match k.description.should == @x.description end end end describe 'tokenize' do it 'should interpolate string with #{} in them' do cmd = @set.command 'random-dent' do |*args| args.should == ["3", "8"] end foo = 5 cmd.new(:target => binding).process_line 'random-dent #{1 + 2} #{3 + foo}' end it 'should not fail if interpolation is not needed and target is not set' do cmd = @set.command 'the-book' do |*args| args.should == ['--help'] end cmd.new.process_line 'the-book --help' end it 'should not interpolate commands with :interpolate => false' do cmd = @set.command 'thor', 'norse god', :interpolate => false do |*args| args.should == ['%(#{foo})'] end cmd.new.process_line 'thor %(#{foo})' end it 'should use shell-words to split strings' do cmd = @set.command 'eccentrica' do |*args| args.should == ['gallumbits', 'eroticon', '6'] end cmd.new.process_line %(eccentrica "gallumbits" 'erot''icon' 6) end it 'should split on spaces if shellwords is not used' do cmd = @set.command 'bugblatter-beast', 'would eat its grandmother', :shellwords => false do |*args| args.should == ['"of', 'traal"'] end cmd.new.process_line %(bugblatter-beast "of traal") end it 'should add captures to arguments for regex commands' do cmd = @set.command /perfectly (normal)( beast)?/i do |*args| args.should == ['Normal', ' Beast', '(honest!)'] end cmd.new.process_line %(Perfectly Normal Beast (honest!)) end end describe 'process_line' do it 'should check for command name collisions if configured' do old = Pry.config.collision_warning Pry.config.collision_warning = true cmd = @set.command 'frankie' do end frankie = 'boyle' output = StringIO.new cmd.new(:target => binding, :output => output).process_line %(frankie mouse) output.string.should =~ /command .* conflicts/ Pry.config.collision_warning = old end it 'should spot collision warnings on assignment if configured' do old = Pry.config.collision_warning Pry.config.collision_warning = true cmd = @set.command 'frankie' do end output = StringIO.new cmd.new(:target => binding, :output => output).process_line %(frankie = mouse) output.string.should =~ /command .* conflicts/ Pry.config.collision_warning = old end it "should set the commands' arg_string and captures" do cmd = @set.command /benj(ie|ei)/ do |*args| self.arg_string.should == "mouse" self.captures.should == ['ie'] args.should == ['ie', 'mouse'] end cmd.new.process_line %(benjie mouse) end it "should raise an error if the line doesn't match the command" do cmd = @set.command 'grunthos', 'the flatulent' lambda { cmd.new.process_line %(grumpos) }.should.raise(Pry::CommandError) end end describe "block parameters" do before do @context = Object.new @set.command "walking-spanish", "down the hall", :takes_block => true do PryTestHelpers.inject_var(:@x, command_block.call, target) end @set.import Pry::Commands @t = pry_tester(@context, :commands => @set) end it 'should accept multiline blocks' do @t.eval <<-EOS walking-spanish | do :jesus end EOS @context.instance_variable_get(:@x).should == :jesus end it 'should accept normal parameters along with block' do @set.block_command "walking-spanish", "litella's been screeching for a blind pig.", :takes_block => true do |x, y| PryTestHelpers.inject_var(:@x, x, target) PryTestHelpers.inject_var(:@y, y, target) PryTestHelpers.inject_var(:@block_var, command_block.call, target) end @t.eval 'walking-spanish john carl| { :jesus }' @context.instance_variable_get(:@x).should == "john" @context.instance_variable_get(:@y).should == "carl" @context.instance_variable_get(:@block_var).should == :jesus end describe "single line blocks" do it 'should accept blocks with do ; end' do @t.eval 'walking-spanish | do ; :jesus; end' @context.instance_variable_get(:@x).should == :jesus end it 'should accept blocks with do; end' do @t.eval 'walking-spanish | do; :jesus; end' @context.instance_variable_get(:@x).should == :jesus end it 'should accept blocks with { }' do @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == :jesus end end describe "block-related content removed from arguments" do describe "arg_string" do it 'should remove block-related content from arg_string (with one normal arg)' do @set.block_command "walking-spanish", "down the hall", :takes_block => true do |x, y| PryTestHelpers.inject_var(:@arg_string, arg_string, target) PryTestHelpers.inject_var(:@x, x, target) end @t.eval 'walking-spanish john| { :jesus }' @context.instance_variable_get(:@arg_string).should == @context.instance_variable_get(:@x) end it 'should remove block-related content from arg_string (with no normal args)' do @set.block_command "walking-spanish", "down the hall", :takes_block => true do PryTestHelpers.inject_var(:@arg_string, arg_string, target) end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@arg_string).should == "" end it 'should NOT remove block-related content from arg_string when :takes_block => false' do block_string = "| { :jesus }" @set.block_command "walking-spanish", "homemade special", :takes_block => false do PryTestHelpers.inject_var(:@arg_string, arg_string, target) end @t.eval "walking-spanish #{block_string}" @context.instance_variable_get(:@arg_string).should == block_string end end describe "args" do describe "block_command" do it "should remove block-related content from arguments" do @set.block_command "walking-spanish", "glass is full of sand", :takes_block => true do |x, y| PryTestHelpers.inject_var(:@x, x, target) PryTestHelpers.inject_var(:@y, y, target) end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == nil @context.instance_variable_get(:@y).should == nil end it "should NOT remove block-related content from arguments if :takes_block => false" do @set.block_command "walking-spanish", "litella screeching for a blind pig", :takes_block => false do |x, y| PryTestHelpers.inject_var(:@x, x, target) PryTestHelpers.inject_var(:@y, y, target) end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == "|" @context.instance_variable_get(:@y).should == "{" end end describe "create_command" do it "should remove block-related content from arguments" do @set.create_command "walking-spanish", "punk sanders carved one out of wood", :takes_block => true do def process(x, y) PryTestHelpers.inject_var(:@x, x, target) PryTestHelpers.inject_var(:@y, y, target) end end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == nil @context.instance_variable_get(:@y).should == nil end it "should NOT remove block-related content from arguments if :takes_block => false" do @set.create_command "walking-spanish", "down the hall", :takes_block => false do def process(x, y) PryTestHelpers.inject_var(:@x, x, target) PryTestHelpers.inject_var(:@y, y, target) end end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == "|" @context.instance_variable_get(:@y).should == "{" end end end end describe "blocks can take parameters" do describe "{} style blocks" do it 'should accept multiple parameters' do @set.block_command "walking-spanish", "down the hall", :takes_block => true do PryTestHelpers.inject_var(:@x, command_block.call(1, 2), target) end @t.eval 'walking-spanish | { |x, y| [x, y] }' @context.instance_variable_get(:@x).should == [1, 2] end end describe "do/end style blocks" do it 'should accept multiple parameters' do @set.create_command "walking-spanish", "litella", :takes_block => true do def process PryTestHelpers.inject_var(:@x, command_block.call(1, 2), target) end end @t.eval <<-EOS walking-spanish | do |x, y| [x, y] end EOS @context.instance_variable_get(:@x).should == [1, 2] end end end describe "closure behaviour" do it 'should close over locals in the definition context' do @t.eval 'var = :hello', 'walking-spanish | { var }' @context.instance_variable_get(:@x).should == :hello end end describe "exposing block parameter" do describe "block_command" do it "should expose block in command_block method" do @set.block_command "walking-spanish", "glass full of sand", :takes_block => true do PryTestHelpers.inject_var(:@x, command_block.call, target) end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == :jesus end end describe "create_command" do it "should NOT expose &block in create_command's process method" do @set.create_command "walking-spanish", "down the hall", :takes_block => true do def process(&block) block.call end end @out = StringIO.new proc { @t.eval 'walking-spanish | { :jesus }' }.should.raise(NoMethodError) end it "should expose block in command_block method" do @set.create_command "walking-spanish", "homemade special", :takes_block => true do def process PryTestHelpers.inject_var(:@x, command_block.call, target) end end @t.eval 'walking-spanish | { :jesus }' @context.instance_variable_get(:@x).should == :jesus end end end end describe "a command made with a custom sub-class" do before do class MyTestCommand < Pry::ClassCommand match /my-*test/ description 'So just how many sound technicians does it take to' \ 'change a lightbulb? 1? 2? 3? 1-2-3? Testing?' options :shellwords => false, :listing => 'my-test' def process output.puts command_name * 2 end end Pry.commands.add_command MyTestCommand end after do Pry.commands.delete 'my-test' end it "allows creation of custom subclasses of Pry::Command" do pry_eval('my---test').should =~ /my-testmy-test/ end if !mri18_and_no_real_source_location? it "shows the source of the process method" do pry_eval('show-source my-test').should =~ /output.puts command_name/ end end describe "command options hash" do it "is always present" do options_hash = { :requires_gem => [], :keep_retval => false, :argument_required => false, :interpolate => true, :shellwords => false, :listing => 'my-test', :use_prefix => true, :takes_block => false } MyTestCommand.options.should == options_hash end describe ":listing option" do it "defaults to :match if not set explicitly" do class HappyNewYear < Pry::ClassCommand match 'happy-new-year' description 'Happy New Year 2013' end Pry.commands.add_command HappyNewYear HappyNewYear.options[:listing].should == 'happy-new-year' Pry.commands.delete 'happy-new-year' end it "can be set explicitly" do class MerryChristmas < Pry::ClassCommand match 'merry-christmas' description 'Merry Christmas!' command_options :listing => 'happy-holidays' end Pry.commands.add_command MerryChristmas MerryChristmas.options[:listing].should == 'happy-holidays' Pry.commands.delete 'merry-christmas' end it "equals to :match option's inspect, if :match is Regexp" do class CoolWinter < Pry::ClassCommand match /.*winter/ description 'Is winter cool or cool?' end Pry.commands.add_command CoolWinter CoolWinter.options[:listing].should == '/.*winter/' Pry.commands.delete /.*winter/ end end end end describe "commands can save state" do before do @set = Pry::CommandSet.new do create_command "litella", "desc" do def process state.my_state ||= 0 state.my_state += 1 end end create_command "sanders", "desc" do def process state.my_state = "wood" end end create_command /[Hh]ello-world/, "desc" do def process state.my_state ||= 0 state.my_state += 2 end end end.import Pry::Commands @t = pry_tester(:commands => @set) end it 'should save state for the command on the Pry#command_state hash' do @t.eval 'litella' @t.pry.command_state["litella"].my_state.should == 1 end it 'should ensure state is maintained between multiple invocations of command' do @t.eval 'litella' @t.eval 'litella' @t.pry.command_state["litella"].my_state.should == 2 end it 'should ensure state with same name stored seperately for each command' do @t.eval 'litella', 'sanders' @t.pry.command_state["litella"].my_state.should == 1 @t.pry.command_state["sanders"].my_state.should =="wood" end it 'should ensure state is properly saved for regex commands' do @t.eval 'hello-world', 'Hello-world' @t.pry.command_state[/[Hh]ello-world/].my_state.should == 4 end end if defined?(Bond) describe 'complete' do it 'should return the arguments that are defined' do @set.create_command "torrid" do def options(opt) opt.on :test opt.on :lest opt.on :pests end end @set.complete('torrid ').should.include('--test ') end end end describe 'group' do before do @set.import( Pry::CommandSet.new do create_command("magic") { group("Not for a public use") } end ) end it 'should be correct for default commands' do @set.commands["help"].group.should == "Help" end it 'should not change once it is initialized' do @set.commands["magic"].group("-==CD COMMAND==-") @set.commands["magic"].group.should == "Not for a public use" end it 'should not disappear after the call without parameters' do @set.commands["magic"].group @set.commands["magic"].group.should == "Not for a public use" end end end pry-0.9.12.6/spec/method_spec.rb0000644000004100000410000004207612272154173016377 0ustar www-datawww-datarequire 'helper' require 'set' describe Pry::Method do it "should use String names for compatibility" do klass = Class.new { def hello; end } Pry::Method.new(klass.instance_method(:hello)).name.should == "hello" end describe ".from_str" do it 'should look up instance methods if no methods available and no options provided' do klass = Class.new { def hello; end } meth = Pry::Method.from_str(:hello, Pry.binding_for(klass)) meth.should == klass.instance_method(:hello) end it 'should look up methods if no instance methods available and no options provided' do klass = Class.new { def self.hello; end } meth = Pry::Method.from_str(:hello, Pry.binding_for(klass)) meth.should == klass.method(:hello) end it 'should look up instance methods first even if methods available and no options provided' do klass = Class.new { def hello; end; def self.hello; end } meth = Pry::Method.from_str(:hello, Pry.binding_for(klass)) meth.should == klass.instance_method(:hello) end it 'should look up instance methods if "instance-methods" option provided' do klass = Class.new { def hello; end; def self.hello; end } meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {"instance-methods" => true}) meth.should == klass.instance_method(:hello) end it 'should look up methods if :methods option provided' do klass = Class.new { def hello; end; def self.hello; end } meth = Pry::Method.from_str(:hello, Pry.binding_for(klass), {:methods => true}) meth.should == klass.method(:hello) end it 'should look up instance methods using the Class#method syntax' do klass = Class.new { def hello; end; def self.hello; end } meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding)) meth.should == klass.instance_method(:hello) end it 'should look up methods using the object.method syntax' do klass = Class.new { def hello; end; def self.hello; end } meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding)) meth.should == klass.method(:hello) end it 'should NOT look up instance methods using the Class#method syntax if no instance methods defined' do klass = Class.new { def self.hello; end } meth = Pry::Method.from_str("klass#hello", Pry.binding_for(binding)) meth.should == nil end it 'should NOT look up methods using the object.method syntax if no methods defined' do klass = Class.new { def hello; end } meth = Pry::Method.from_str("klass.hello", Pry.binding_for(binding)) meth.should == nil end it 'should look up methods using klass.new.method syntax' do klass = Class.new { def hello; :hello; end } meth = Pry::Method.from_str("klass.new.hello", Pry.binding_for(binding)) meth.name.should == "hello" end it 'should look up instance methods using klass.meth#method syntax' do klass = Class.new { def self.meth; Class.new; end } meth = Pry::Method.from_str("klass.meth#initialize", Pry.binding_for(binding)) meth.name.should == "initialize" end it 'should look up methods using instance::bar syntax' do klass = Class.new{ def self.meth; Class.new; end } meth = Pry::Method.from_str("klass::meth", Pry.binding_for(binding)) meth.name.should == "meth" end it 'should not raise an exception if receiver does not exist' do lambda { Pry::Method.from_str("random_klass.meth", Pry.binding_for(binding)) }.should.not.raise end end describe '.from_binding' do it 'should be able to pick a method out of a binding' do Pry::Method.from_binding(Class.new{ def self.foo; binding; end }.foo).name.should == "foo" end it 'should NOT find a method from the toplevel binding' do Pry::Method.from_binding(TOPLEVEL_BINDING).should == nil end it "should find methods that have been undef'd" do c = Class.new do def self.bar class << self; undef bar; end binding end end m = Pry::Method.from_binding(c.bar) m.name.should == "bar" end # Our source_location trick doesn't work, due to https://github.com/rubinius/rubinius/issues/953 unless Pry::Helpers::BaseHelpers.rbx? it 'should find the super method correctly' do a = Class.new{ def gag33; binding; end; def self.line; __LINE__; end } b = Class.new(a){ def gag33; super; end } g = b.new.gag33 m = Pry::Method.from_binding(g) m.owner.should == a m.source_line.should == a.line m.name.should == "gag33" end end it 'should find the right method if a super method exists' do a = Class.new{ def gag; binding; end; } b = Class.new(a){ def gag; super; binding; end; def self.line; __LINE__; end } m = Pry::Method.from_binding(b.new.gag) m.owner.should == b m.source_line.should == b.line m.name.should == "gag" end if defined?(BasicObject) && !Pry::Helpers::BaseHelpers.rbx? # rubinius issue 1921 it "should find the right method from a BasicObject" do a = Class.new(BasicObject) { def gag; ::Kernel.binding; end; def self.line; __LINE__; end } m = Pry::Method.from_binding(a.new.gag) m.owner.should == a m.source_file.should == __FILE__ m.source_line.should == a.line end end it 'should find the right method even if it was renamed and replaced' do o = Object.new class << o def borscht "nips" binding end alias paella borscht def borscht() paella end end m = Pry::Method.from_binding(o.borscht) m.source.should == Pry::Method(o.method(:paella)).source end end describe 'super' do it 'should be able to find the super method on a bound method' do a = Class.new{ def rar; 4; end } b = Class.new(a){ def rar; super; end } obj = b.new zuper = Pry::Method(obj.method(:rar)).super zuper.owner.should == a zuper.receiver.should == obj end it 'should be able to find the super method of an unbound method' do a = Class.new{ def rar; 4; end } b = Class.new(a){ def rar; super; end } zuper = Pry::Method(b.instance_method(:rar)).super zuper.owner.should == a end it 'should return nil if no super method exists' do a = Class.new{ def rar; super; end } Pry::Method(a.instance_method(:rar)).super.should == nil end it 'should be able to find super methods defined on modules' do m = Module.new{ def rar; 4; end } a = Class.new{ def rar; super; end; include m } zuper = Pry::Method(a.new.method(:rar)).super zuper.owner.should == m end it 'should be able to find super methods defined on super-classes when there are modules in the way' do a = Class.new{ def rar; 4; end } m = Module.new{ def mooo; 4; end } b = Class.new(a){ def rar; super; end; include m } zuper = Pry::Method(b.new.method(:rar)).super zuper.owner.should == a end it 'should be able to jump up multiple levels of bound method, even through modules' do a = Class.new{ def rar; 4; end } m = Module.new{ def rar; 4; end } b = Class.new(a){ def rar; super; end; include m } zuper = Pry::Method(b.new.method(:rar)).super zuper.owner.should == m zuper.super.owner.should == a end end describe 'all_from_class' do def should_find_method(name) Pry::Method.all_from_class(@class).map(&:name).should.include(name) end it 'should be able to find public instance methods defined in a class' do @class = Class.new{ def meth; 1; end } should_find_method('meth') end it 'should be able to find private and protected instance methods defined in a class' do @class = Class.new { protected; def prot; 1; end; private; def priv; 1; end } should_find_method('priv') should_find_method('prot') end it 'should find methods all the way up to Kernel' do @class = Class.new should_find_method('exit!') end it 'should be able to find instance methods defined in a super-class' do @class = Class.new(Class.new{ def meth; 1; end }) {} should_find_method('meth') end it 'should be able to find instance methods defined in modules included into this class' do @class = Class.new{ include Module.new{ def meth; 1; end; } } should_find_method('meth') end it 'should be able to find instance methods defined in modules included into super-classes' do @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } }) should_find_method('meth') end it 'should attribute overridden methods to the sub-class' do @class = Class.new(Class.new{ include Module.new{ def meth; 1; end; } }) { def meth; 2; end } Pry::Method.all_from_class(@class).detect{ |x| x.name == 'meth' }.owner.should == @class end it 'should be able to find methods defined on a singleton class' do @class = (class << Object.new; def meth; 1; end; self; end) should_find_method('meth') end it 'should be able to find methods on super-classes when given a singleton class' do @class = (class << Class.new{ def meth; 1; end}.new; self; end) should_find_method('meth') end end describe 'all_from_obj' do describe 'on normal objects' do def should_find_method(name) Pry::Method.all_from_obj(@obj).map(&:name).should.include(name) end it "should find methods defined in the object's class" do @obj = Class.new{ def meth; 1; end }.new should_find_method('meth') end it "should find methods defined in modules included into the object's class" do @obj = Class.new{ include Module.new{ def meth; 1; end } }.new should_find_method('meth') end it "should find methods defined in the object's singleton class" do @obj = Object.new class << @obj; def meth; 1; end; end should_find_method('meth') end it "should find methods in modules included into the object's singleton class" do @obj = Object.new @obj.extend Module.new{ def meth; 1; end } should_find_method('meth') end it "should find methods all the way up to Kernel" do @obj = Object.new should_find_method('exit!') end it "should not find methods defined on the classes singleton class" do @obj = Class.new{ class << self; def meth; 1; end; end }.new Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth') end it "should work in the face of an overridden send" do @obj = Class.new{ def meth; 1; end; def send; raise EOFError; end }.new should_find_method('meth') end end describe 'on classes' do def should_find_method(name) Pry::Method.all_from_obj(@class).map(&:name).should.include(name) end it "should find methods defined in the class' singleton class" do @class = Class.new{ class << self; def meth; 1; end; end } should_find_method('meth') end it "should find methods defined on modules extended into the class" do @class = Class.new{ extend Module.new{ def meth; 1; end; } } should_find_method('meth') end it "should find methods defined on the singleton class of super-classes" do @class = Class.new(Class.new{ class << self; def meth; 1; end; end }) should_find_method('meth') end it "should not find methods defined within the class" do @class = Class.new{ def meth; 1; end } Pry::Method.all_from_obj(@obj).map(&:name).should.not.include('meth') end it "should find methods defined on Class" do @class = Class.new should_find_method('allocate') end it "should find methods defined on Kernel" do @class = Class.new should_find_method('exit!') end it "should attribute overridden methods to the sub-class' singleton class" do @class = Class.new(Class.new{ class << self; def meth; 1; end; end }) { class << self; def meth; 1; end; end } Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end) end it "should attrbute overridden methods to the class not the module" do @class = Class.new { class << self; def meth; 1; end; end; extend Module.new{ def meth; 1; end; } } Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'meth' }.owner.should == (class << @class; self; end) end it "should attribute overridden methods to the relevant singleton class in preference to Class" do @class = Class.new { class << self; def allocate; 1; end; end } Pry::Method.all_from_obj(@class).detect{ |x| x.name == 'allocate' }.owner.should == (class << @class; self; end) end end describe 'method resolution order' do module LS class Top; end class Next < Top; end module M; end module N; include M; end module O; include M; end module P; end class Low < Next; include N; include P; end class Lower < Low; extend N; end class Bottom < Lower; extend O; end end def singleton_class(obj); class << obj; self; end; end it "should look at a class and then its superclass" do Pry::Method.instance_resolution_order(LS::Next).should == [LS::Next] + Pry::Method.instance_resolution_order(LS::Top) end it "should include the included modules between a class and its superclass" do Pry::Method.instance_resolution_order(LS::Low).should == [LS::Low, LS::P, LS::N, LS::M] + Pry::Method.instance_resolution_order(LS::Next) end it "should not include modules extended into the class" do Pry::Method.instance_resolution_order(LS::Bottom).should == [LS::Bottom] + Pry::Method.instance_resolution_order(LS::Lower) end it "should include included modules for Modules" do Pry::Method.instance_resolution_order(LS::O).should == [LS::O, LS::M] end it "should include the singleton class of objects" do obj = LS::Low.new Pry::Method.resolution_order(obj).should == [singleton_class(obj)] + Pry::Method.instance_resolution_order(LS::Low) end it "should not include singleton classes of numbers" do Pry::Method.resolution_order(4).should == Pry::Method.instance_resolution_order(Fixnum) end it "should include singleton classes for classes" do Pry::Method.resolution_order(LS::Low).should == [singleton_class(LS::Low)] + Pry::Method.resolution_order(LS::Next) end it "should include modules included into singleton classes" do Pry::Method.resolution_order(LS::Lower).should == [singleton_class(LS::Lower), LS::N, LS::M] + Pry::Method.resolution_order(LS::Low) end it "should include modules at most once" do Pry::Method.resolution_order(LS::Bottom).count(LS::M).should == 1 end it "should include modules at the point which they would be reached" do Pry::Method.resolution_order(LS::Bottom).should == [singleton_class(LS::Bottom), LS::O] + (Pry::Method.resolution_order(LS::Lower)) end it "should include the Pry::Method.instance_resolution_order of Class after the singleton classes" do Pry::Method.resolution_order(LS::Top).should == [singleton_class(LS::Top), singleton_class(Object), (defined? BasicObject) && singleton_class(BasicObject)].compact + Pry::Method.instance_resolution_order(Class) end end end describe 'method_name_from_first_line' do it 'should work in all simple cases' do meth = Pry::Method.new(nil) meth.send(:method_name_from_first_line, "def x").should == "x" meth.send(:method_name_from_first_line, "def self.x").should == "x" meth.send(:method_name_from_first_line, "def ClassName.x").should == "x" meth.send(:method_name_from_first_line, "def obj_name.x").should == "x" end end describe 'method aliases' do before do @class = Class.new { def eat end alias fress eat alias_method :omnomnom, :fress def eruct end } end it 'should be able to find method aliases' do meth = Pry::Method(@class.new.method(:eat)) aliases = Set.new(meth.aliases) aliases.should == Set.new(["fress", "omnomnom"]) end it 'should return an empty Array if cannot find aliases' do meth = Pry::Method(@class.new.method(:eruct)) meth.aliases.should.be.empty end it 'should not include the own name in the list of aliases' do meth = Pry::Method(@class.new.method(:eat)) meth.aliases.should.not.include "eat" end unless Pry::Helpers::BaseHelpers.mri_18? # Ruby 1.8 doesn't support this feature. it 'should be able to find aliases for methods implemented in C' do meth = Pry::Method(Hash.new.method(:key?)) aliases = Set.new(meth.aliases) aliases.should == Set.new(["include?", "member?", "has_key?"]) end end end end pry-0.9.12.6/spec/wrapped_module_spec.rb0000644000004100000410000002011112272154173020110 0ustar www-datawww-datarequire 'helper' describe Pry::WrappedModule do describe "#initialize" do it "should raise an exception when a non-module is passed" do lambda{ Pry::WrappedModule.new(nil) }.should.raise ArgumentError end end describe "candidates" do before do class Host %w(spec/fixtures/candidate_helper1.rb spec/fixtures/candidate_helper2.rb).each do |file| binding.eval File.read(file), file, 1 end # rank 2 class CandidateTest def test6 end end class ForeverAlone class DoublyNested # nested docs class TriplyNested def nested_method end end end end end end describe "number_of_candidates" do it 'should return the correct number of candidates' do Pry::WrappedModule(Host::CandidateTest).number_of_candidates.should == 3 end it 'should return 0 candidates for a class with no methods and no other definitions' do Pry::WrappedModule(Host::ForeverAlone).number_of_candidates.should == 0 end end describe "ordering of candidates" do it 'should return class with largest number of methods as primary candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(0).file.should =~ /helper1/ end it 'should return class with second largest number of methods as second ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(1).file.should =~ /helper2/ end it 'should return class with third largest number of methods as third ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(2).file.should =~ /#{__FILE__}/ end it 'should raise when trying to access non-existent candidate' do lambda { Pry::WrappedModule(Host::CandidateTest).candidate(3) }.should.raise Pry::CommandError end end describe "source_location" do it 'should return primary candidates source_location by default' do wm = Pry::WrappedModule(Host::CandidateTest) wm.source_location.should == wm.candidate(0).source_location end it 'should return nil if no source_location can be found' do Pry::WrappedModule(Host::ForeverAlone).source_location.should == nil end end describe "source" do it 'should return primary candidates source by default' do wm = Pry::WrappedModule(Host::CandidateTest) wm.source.should == wm.candidate(0).source end it 'should return source for highest ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(0).source.should =~ /test1/ end it 'should return source for second ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(1).source.should =~ /test4/ end it 'should return source for third ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(2).source.should =~ /test6/ end it 'should return source for deeply nested class' do Pry::WrappedModule(Host::ForeverAlone::DoublyNested::TriplyNested).source.should =~ /nested_method/ Pry::WrappedModule(Host::ForeverAlone::DoublyNested::TriplyNested).source.lines.count.should == 4 end end describe "doc" do it 'should return primary candidates doc by default' do wm = Pry::WrappedModule(Host::CandidateTest) wm.doc.should == wm.candidate(0).doc end it 'should return doc for highest ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(0).doc.should =~ /rank 0/ end it 'should return doc for second ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(1).doc.should =~ /rank 1/ end it 'should return doc for third ranked candidate' do Pry::WrappedModule(Host::CandidateTest).candidate(2).doc.should =~ /rank 2/ end it 'should return docs for deeply nested class' do Pry::WrappedModule(Host::ForeverAlone::DoublyNested::TriplyNested).doc.should =~ /nested docs/ end end after do Object.remove_const(:Host) end end describe ".method_prefix" do before do Foo = Class.new @foo = Foo.new end after do Object.remove_const(:Foo) end it "should return Foo# for normal classes" do Pry::WrappedModule.new(Foo).method_prefix.should == "Foo#" end it "should return Bar# for modules" do Pry::WrappedModule.new(Kernel).method_prefix.should == "Kernel#" end it "should return Foo. for singleton classes of classes" do Pry::WrappedModule.new(class << Foo; self; end).method_prefix.should == "Foo." end describe "of singleton classes of objects" do Pry::WrappedModule.new(class << @foo; self; end).method_prefix.should == "self." end describe "of anonymous classes should not be empty" do Pry::WrappedModule.new(Class.new).method_prefix.should =~ /##/ end describe "of singleton classes of anonymous classes should not be empty" do Pry::WrappedModule.new(class << Class.new; self; end).method_prefix.should =~ /#./ end end describe ".singleton_class?" do it "should be true for singleton classes" do Pry::WrappedModule.new(class << ""; self; end).singleton_class?.should == true end it "should be false for normal classes" do Pry::WrappedModule.new(Class.new).singleton_class?.should == false end it "should be false for modules" do Pry::WrappedModule.new(Module.new).singleton_class?.should == false end end describe ".singleton_instance" do it "should raise an exception when called on a non-singleton-class" do lambda{ Pry::WrappedModule.new(Class).singleton_instance }.should.raise ArgumentError end it "should return the attached object" do Pry::WrappedModule.new(class << "hi"; self; end).singleton_instance.should == "hi" Pry::WrappedModule.new(class << Object; self; end).singleton_instance.should.equal?(Object) end end describe ".super" do describe "receiver is a class" do before do @a = Class.new @m = Module.new @b = Class.new(@a) @b.send(:include, @m) @c = Class.new(@b) end it 'should return superclass for a wrapped class' do Pry::WrappedModule(@c).super.wrapped.should == @b end it 'should return nth superclass for a wrapped class' do d = Class.new(@c) Pry::WrappedModule(d).super(2).wrapped.should == @b end it 'should ignore modules when retrieving nth superclass' do Pry::WrappedModule(@c).super(2).wrapped.should == @a end it 'should return nil when no nth superclass exists' do Pry::WrappedModule(@c).super(10).should == nil end it 'should return self when .super(0) is used' do c = Pry::WrappedModule(@c) c.super(0).should == c end end describe "receiver is a module" do before do @m1 = Module.new @m2 = Module.new.tap { |v| v.send(:include, @m1) } @m3 = Module.new.tap { |v| v.send(:include, @m2) } end it 'should not ignore modules when retrieving supers' do Pry::WrappedModule(@m3).super.wrapped.should == @m2 end it 'should retrieve nth super' do Pry::WrappedModule(@m3).super(2).wrapped.should == @m1 end it 'should return self when .super(0) is used' do m = Pry::WrappedModule(@m1) m.super(0).should == m end end end describe ".from_str" do it 'should lookup a constant' do m = Pry::WrappedModule.from_str("Host::CandidateTest", binding) m.wrapped.should == Host::CandidateTest end it 'should lookup a local' do local = Host::CandidateTest m = Pry::WrappedModule.from_str("local", binding) m.wrapped.should == Host::CandidateTest end it 'should lookup an ivar' do @ivar = Host::CandidateTest m = Pry::WrappedModule.from_str("@ivar", binding) m.wrapped.should == Host::CandidateTest end end end pry-0.9.12.6/spec/helpers/0000755000004100000410000000000012272154173015211 5ustar www-datawww-datapry-0.9.12.6/spec/helpers/bacon.rb0000644000004100000410000000403512272154173016622 0ustar www-datawww-data# Colorize output (based on greeneggs (c) 2009 Michael Fleet) # TODO: Make own gem (assigned to rking) module Bacon class Context include PryTestHelpers end COLORS = {'F' => 31, 'E' => 35, 'M' => 33, '.' => 32} USE_COLOR = !(ENV['NO_PRY_COLORED_BACON'] == 'true') && Pry::Helpers::BaseHelpers.use_ansi_codes? module TestUnitOutput def handle_requirement(description) error = yield if error.empty? print colorize_string('.') else print colorize_string(error[0..0]) end end def handle_summary puts puts ErrorLog if Backtraces out = "%d tests, %d assertions, %d failures, %d errors" % Counter.values_at(:specifications, :requirements, :failed, :errors) if Counter.values_at(:failed, :errors).inject(:+) > 0 puts colorize_string(out, 'F') else puts colorize_string(out, '.') end end def colorize_string(text, color = nil) if USE_COLOR "\e[#{ COLORS[color || text] }m#{ text }\e[0m" else text end end end end # Reset top-level binding at the beginning of each test case. module Bacon class Context def it_with_reset_binding(description, &block) Pry.toplevel_binding = nil it_without_reset_binding(description, &block) end alias it_without_reset_binding it alias it it_with_reset_binding end end # Support mocha # mocha-on-bacon (c) Copyright (C) 2011, Eloy Durán module Bacon module MochaRequirementsCounter def self.increment Counter[:requirements] += 1 end end class Context include Mocha::API def it_with_mocha(description, &block) it_without_mocha(description) do begin mocha_setup block.call mocha_verify(MochaRequirementsCounter) rescue Mocha::ExpectationError => e raise Error.new(:failed, e.message) ensure mocha_teardown end end end alias it_without_mocha it alias it it_with_mocha end end pry-0.9.12.6/spec/helpers/mock_pry.rb0000644000004100000410000000133212272154173017360 0ustar www-datawww-datadef mock_pry(*args) args.flatten! binding = args.first.is_a?(Binding) ? args.shift : binding() input = InputTester.new(*args) output = StringIO.new redirect_pry_io(input, output) do binding.pry end output.string end # Set I/O streams. Out defaults to an anonymous StringIO. def redirect_pry_io(new_in, new_out = StringIO.new) old_in = Pry.input old_out = Pry.output Pry.input = new_in Pry.output = new_out begin yield ensure Pry.input = old_in Pry.output = old_out end end class InputTester def initialize(*actions) @orig_actions = actions.dup @actions = actions end def readline(*) @actions.shift end def rewind @actions = @orig_actions.dup end end pry-0.9.12.6/spec/helpers/table_spec.rb0000644000004100000410000000556012272154173017645 0ustar www-datawww-datarequire 'helper' describe 'Formatting Table' do it 'knows about colorized fitting' do t = Pry::Helpers::Table.new %w(hihi), :column_count => 1 t.fits_on_line?(4).should == true t.items = [] t.fits_on_line?(4).should == true t.items = %w(hi hi) t.fits_on_line?(4).should == true t.column_count = 2 t.fits_on_line?(4).should == false t.items = %w( a ccc bb dddd ).sort t.fits_on_line?(8).should == true t.fits_on_line?(7).should == false end describe 'formatting - should order downward and wrap to columns' do FAKE_COLUMNS = 62 def try_round_trip(expected) things = expected.split(/\s+/).sort actual = Pry::Helpers.tablify(things, FAKE_COLUMNS).to_s.strip [expected, actual].each{|e| e.gsub! /\s+$/, ''} if actual != expected bar = '-'*25 puts \ bar+'expected'+bar, expected, bar+'actual'+bar, actual end actual.should == expected end it 'should handle a tiny case' do try_round_trip(<<-eot) asdf asfddd fdass eot end it 'should handle the basic case' do try_round_trip(<<-eot) aadd ddasffssdad sdsaadaasd ssfasaafssd adassdfffaasds f sdsfasddasfds ssssdaa assfsafsfsds fsasa ssdsssafsdasdf eot end it 'should handle... another basic case' do try_round_trip(<<-EOT) aaad dasaasffaasf fdasfdfss safdfdddsasd aaadfasassdfff ddadadassasdf fddsasadfssdss sasf aaddaafaf dddasaaaaaa fdsasad sddsa aas dfsddffdddsdfd ff sddsfsaa adasadfaaffds dsfafdsfdfssda ffadsfafsaafa ss asddaadaaadfdd dssdss ffssfsfafaadss ssas asdsdaa faadf fsddfff ssdfssff asfadsssaaad fasfaafdssd s EOT end it 'should handle colors' do try_round_trip(<<-EOT) \e[31maaaaaaaaaa\e[0m \e[31mccccccccccccccccccccccccccccc\e[0m \e[31mbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\e[0m \e[31mddddddddddddd\e[0m EOT end it 'should handle empty input' do try_round_trip('') end it 'should handle one-token input' do try_round_trip('asdf') end end describe 'line length is smaller than the length of the longest word' do before do element = 'swizzle' @elem_len = element.length @out = [element, 'crime', 'fun'] end it 'should not raise error' do should.not.raise(FloatDomainError) { Pry::Helpers.tablify(@out, @elem_len - 1) } end it 'should format output as one column' do table = Pry::Helpers.tablify(@out, @elem_len - 1).to_s table.should == "swizzle\ncrime \nfun " end end describe 'decide between one-line or indented output' do Pry::Helpers.tablify_or_one_line('head', %w(ing)).should == 'head: ing' end end pry-0.9.12.6/spec/editor_spec.rb0000644000004100000410000000355512272154173016404 0ustar www-datawww-datarequire 'pathname' require 'helper' describe Pry::Editor do class << Pry::Editor public :build_editor_invocation_string end before do # OS-specific tempdir name. For GNU/Linux it's "tmp", for Windows it's # something "Temp". @tf_dir = if Pry::Helpers::BaseHelpers.mri_19? Pathname.new(Dir::Tmpname.tmpdir) else Pathname.new(Dir.tmpdir) end @tf_path = File.join(@tf_dir.to_s, 'hello world.rb') end unless Pry::Helpers::BaseHelpers.windows? describe "build_editor_invocation_string" do before do class << Pry::Editor public :build_editor_invocation_string end end it 'should shell-escape files' do invocation_str = Pry::Editor.build_editor_invocation_string(@tf_path, 5, true) invocation_str.should =~ /#@tf_dir.+hello\\ world\.rb/ end end end describe "build_editor_invocation_string on windows" do before do class << Pry::Editor def windows?; true; end end end after do class << Pry::Editor undef windows? end end it "should replace / by \\" do invocation_str = Pry::Editor.build_editor_invocation_string(@tf_path, 5, true) invocation_str.should =~ %r(\\#{@tf_dir.basename}\\) end it "should not shell-escape files" do invocation_str = Pry::Editor.build_editor_invocation_string(@tf_path, 5, true) invocation_str.should =~ /hello world\.rb/ end end describe 'invoke_editor with a proc' do before do @old_editor = Pry.config.editor Pry.config.editor = proc{ |file, line, blocking| @file = file nil } end after do Pry.config.editor = @old_editor end it 'should not shell-escape files' do Pry::Editor.invoke_editor(@tf_path, 10, true) @file.should == @tf_path end end end pry-0.9.12.6/spec/command_set_spec.rb0000644000004100000410000004305512272154172017405 0ustar www-datawww-datarequire 'helper' describe Pry::CommandSet do before do @set = Pry::CommandSet.new do import Pry::Commands end @ctx = { :target => binding, :command_set => @set } end it 'should call the block used for the command when it is called' do run = false @set.command 'foo' do run = true end @set.run_command @ctx, 'foo' run.should == true end it 'should pass arguments of the command to the block' do @set.command 'foo' do |*args| args.should == [1, 2, 3] end @set.run_command @ctx, 'foo', 1, 2, 3 end it 'should use the first argument as context' do ctx = @ctx @set.command 'foo' do self.context.should == ctx end @set.run_command @ctx, 'foo' end it 'should raise an error when calling an undefined command' do @set.command('foo') {} lambda { @set.run_command @ctx, 'bar' }.should.raise(Pry::NoCommandError) end it 'should be able to remove its own commands' do @set.command('foo') {} @set.delete 'foo' lambda { @set.run_command @ctx, 'foo' }.should.raise(Pry::NoCommandError) end it 'should be able to remove its own commands, by listing name' do @set.command(/^foo1/, 'desc', :listing => 'foo') {} @set.delete 'foo' lambda { @set.run_command @ctx, /^foo1/ }.should.raise(Pry::NoCommandError) end it 'should be able to import some commands from other sets' do run = false other_set = Pry::CommandSet.new do command('foo') { run = true } command('bar') {} end @set.import_from(other_set, 'foo') @set.run_command @ctx, 'foo' run.should == true lambda { @set.run_command @ctx, 'bar' }.should.raise(Pry::NoCommandError) end it 'should return command set after import' do run = false other_set = Pry::CommandSet.new do command('foo') { run = true } command('bar') {} end @set.import(other_set).should == @set end it 'should return command set after import_from' do run = false other_set = Pry::CommandSet.new do command('foo') { run = true } command('bar') {} end @set.import_from(other_set, 'foo').should == @set end it 'should be able to import some commands from other sets using listing name' do run = false other_set = Pry::CommandSet.new do command(/^foo1/, 'desc', :listing => 'foo') { run = true } end @set.import_from(other_set, 'foo') @set.run_command @ctx, /^foo1/ run.should == true end it 'should be able to import a whole set' do run = [] other_set = Pry::CommandSet.new do command('foo') { run << true } command('bar') { run << true } end @set.import other_set @set.run_command @ctx, 'foo' @set.run_command @ctx, 'bar' run.should == [true, true] end it 'should be able to import sets at creation' do run = false @set.command('foo') { run = true } Pry::CommandSet.new(@set).run_command @ctx, 'foo' run.should == true end it 'should set the descriptions of commands' do @set.command('foo', 'some stuff') {} @set.commands['foo'].description.should == 'some stuff' end describe "aliases" do it 'should be able to alias command' do run = false @set.command('foo', 'stuff') { run = true } @set.alias_command 'bar', 'foo' @set.commands['bar'].match.should == 'bar' @set.commands['bar'].description.should == 'Alias for `foo`' @set.run_command @ctx, 'bar' run.should == true end it 'should inherit options from original command' do run = false @set.command('foo', 'stuff', :shellwords => true, :interpolate => false) { run = true } @set.alias_command 'bar', 'foo' @set.commands['bar'].options[:shellwords].should == @set.commands['foo'].options[:shellwords] @set.commands['bar'].options[:interpolate].should == @set.commands['foo'].options[:interpolate] # however some options should not be inherited @set.commands['bar'].options[:listing].should.not == @set.commands['foo'].options[:listing] @set.commands['bar'].options[:listing].should == "bar" end it 'should be able to specify alias\'s description when aliasing' do run = false @set.command('foo', 'stuff') { run = true } @set.alias_command 'bar', 'foo', :desc => "tobina" @set.commands['bar'].match.should == 'bar' @set.commands['bar'].description.should == "tobina" @set.run_command @ctx, 'bar' run.should == true end it "should be able to alias a command by its invocation line" do run = false @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true } @set.alias_command 'bar', 'foo1' @set.commands['bar'].match.should == 'bar' @set.commands['bar'].description.should == 'Alias for `foo1`' @set.run_command @ctx, 'bar' run.should == true end it "should be able to specify options when creating alias" do run = false @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true } @set.alias_command /^b.r/, 'foo1', :listing => "bar" @set.commands[/^b.r/].options[:listing].should == "bar" end it "should set description to default if description parameter is nil" do run = false @set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true } @set.alias_command "bar", 'foo1' @set.commands["bar"].description.should == "Alias for `foo1`" end end it 'should be able to change the descriptions of commands' do @set.command('foo', 'bar') {} @set.desc 'foo', 'baz' @set.commands['foo'].description.should == 'baz' end it 'should get the descriptions of commands' do @set.command('foo', 'bar') {} @set.desc('foo').should == 'bar' end it 'should get the descriptions of commands, by listing' do @set.command(/^foo1/, 'bar', :listing => 'foo') {} @set.desc('foo').should == 'bar' end it 'should return Pry::Command::VOID_VALUE for commands by default' do @set.command('foo') { 3 } @set.run_command(@ctx, 'foo').should == Pry::Command::VOID_VALUE end it 'should be able to keep return values' do @set.command('foo', '', :keep_retval => true) { 3 } @set.run_command(@ctx, 'foo').should == 3 end it 'should be able to keep return values, even if return value is nil' do @set.command('foo', '', :keep_retval => true) { nil } @set.run_command(@ctx, 'foo').should == nil end it 'should be able to have its own helpers' do @set.command('foo') do should.respond_to :my_helper end @set.helpers do def my_helper; end end @set.run_command(@ctx, 'foo') Pry::Command.subclass('foo', '', {}, Module.new).new({:target => binding}).should.not.respond_to :my_helper end it 'should not recreate a new helper module when helpers is called' do @set.command('foo') do should.respond_to :my_helper should.respond_to :my_other_helper end @set.helpers do def my_helper; end end @set.helpers do def my_other_helper; end end @set.run_command(@ctx, 'foo') end it 'should import helpers from imported sets' do imported_set = Pry::CommandSet.new do helpers do def imported_helper_method; end end end @set.import imported_set @set.command('foo') { should.respond_to :imported_helper_method } @set.run_command(@ctx, 'foo') end it 'should import helpers even if only some commands are imported' do imported_set = Pry::CommandSet.new do helpers do def imported_helper_method; end end command('bar') {} end @set.import_from imported_set, 'bar' @set.command('foo') { should.respond_to :imported_helper_method } @set.run_command(@ctx, 'foo') end it 'should provide a :listing for a command that defaults to its name' do @set.command 'foo', "" do;end @set.commands['foo'].options[:listing].should == 'foo' end it 'should provide a :listing for a command that differs from its name' do @set.command 'foo', "", :listing => 'bar' do;end @set.commands['foo'].options[:listing].should == 'bar' end it "should provide a 'help' command" do @ctx[:command_set] = @set @ctx[:output] = StringIO.new lambda { @set.run_command(@ctx, 'help') }.should.not.raise end describe "renaming a command" do it 'should be able to rename and run a command' do run = false @set.command('foo') { run = true } @set.rename_command('bar', 'foo') @set.run_command(@ctx, 'bar') run.should == true end it 'should accept listing name when renaming a command' do run = false @set.command('foo', "", :listing => 'love') { run = true } @set.rename_command('bar', 'love') @set.run_command(@ctx, 'bar') run.should == true end it 'should raise exception trying to rename non-existent command' do lambda { @set.rename_command('bar', 'foo') }.should.raise ArgumentError end it 'should make old command name inaccessible' do @set.command('foo') { } @set.rename_command('bar', 'foo') lambda { @set.run_command(@ctx, 'foo') }.should.raise Pry::NoCommandError end it 'should be able to pass in options when renaming command' do desc = "hello" listing = "bing" @set.command('foo') { } @set.rename_command('bar', 'foo', :description => desc, :listing => listing, :keep_retval => true) @set.commands['bar'].description.should == desc @set.commands['bar'].options[:listing].should == listing @set.commands['bar'].options[:keep_retval].should == true end end describe "command decorators - before_command and after_command" do describe "before_command" do it 'should be called before the original command' do foo = [] @set.command('foo') { foo << 1 } @set.before_command('foo') { foo << 2 } @set.run_command(@ctx, 'foo') foo.should == [2, 1] end it 'should be called before the original command, using listing name' do foo = [] @set.command(/^foo1/, '', :listing => 'foo') { foo << 1 } @set.before_command('foo') { foo << 2 } @set.run_command(@ctx, /^foo1/) foo.should == [2, 1] end it 'should share the context with the original command' do @ctx[:target] = "test target string".__binding__ before_val = nil orig_val = nil @set.command('foo') { orig_val = target } @set.before_command('foo') { before_val = target } @set.run_command(@ctx, 'foo') before_val.should == @ctx[:target] orig_val.should == @ctx[:target] end it 'should work when applied multiple times' do foo = [] @set.command('foo') { foo << 1 } @set.before_command('foo') { foo << 2 } @set.before_command('foo') { foo << 3 } @set.before_command('foo') { foo << 4 } @set.run_command(@ctx, 'foo') foo.should == [4, 3, 2, 1] end end describe "after_command" do it 'should be called after the original command' do foo = [] @set.command('foo') { foo << 1 } @set.after_command('foo') { foo << 2 } @set.run_command(@ctx, 'foo') foo.should == [1, 2] end it 'should be called after the original command, using listing name' do foo = [] @set.command(/^foo1/, '', :listing => 'foo') { foo << 1 } @set.after_command('foo') { foo << 2 } @set.run_command(@ctx, /^foo1/) foo.should == [1, 2] end it 'should share the context with the original command' do @ctx[:target] = "test target string".__binding__ after_val = nil orig_val = nil @set.command('foo') { orig_val = target } @set.after_command('foo') { after_val = target } @set.run_command(@ctx, 'foo') after_val.should == @ctx[:target] orig_val.should == @ctx[:target] end it 'should determine the return value for the command' do @set.command('foo', 'bar', :keep_retval => true) { 1 } @set.after_command('foo') { 2 } @set.run_command(@ctx, 'foo').should == 2 end it 'should work when applied multiple times' do foo = [] @set.command('foo') { foo << 1 } @set.after_command('foo') { foo << 2 } @set.after_command('foo') { foo << 3 } @set.after_command('foo') { foo << 4 } @set.run_command(@ctx, 'foo') foo.should == [1, 2, 3, 4] end end describe "before_command and after_command" do it 'should work when combining both before_command and after_command' do foo = [] @set.command('foo') { foo << 1 } @set.after_command('foo') { foo << 2 } @set.before_command('foo') { foo << 3 } @set.run_command(@ctx, 'foo') foo.should == [3, 1, 2] end end end describe 'find_command' do it 'should find commands with the right string' do cmd = @set.command('rincewind'){ } @set.find_command('rincewind').should == cmd end it 'should not find commands with spaces before' do cmd = @set.command('luggage'){ } @set.find_command(' luggage').should == nil end it 'should find commands with arguments after' do cmd = @set.command('vetinari'){ } @set.find_command('vetinari --knock 3').should == cmd end it 'should find commands with names containing spaces' do cmd = @set.command('nobby nobbs'){ } @set.find_command('nobby nobbs --steal petty-cash').should == cmd end it 'should find command defined by regex' do cmd = @set.command(/(capt|captain) vimes/i){ } @set.find_command('Capt Vimes').should == cmd end it 'should find commands defined by regex with arguments' do cmd = @set.command(/(cpl|corporal) Carrot/i){ } @set.find_command('cpl carrot --write-home').should == cmd end it 'should not find commands by listing' do cmd = @set.command(/werewol(f|ve)s?/, 'only once a month', :listing => "angua"){ } @set.find_command('angua').should == nil end it 'should not find commands without command_prefix' do Pry.config.command_prefix = '%' cmd = @set.command('detritus'){ } @set.find_command('detritus').should == nil Pry.config.command_prefix = '' end it "should find commands that don't use the prefix" do Pry.config.command_prefix = '%' cmd = @set.command('colon', 'Sergeant Fred', :use_prefix => false){ } @set.find_command('colon').should == cmd Pry.config.command_prefix = '' end it "should find the command that has the longest match" do cmd = @set.command(/\.(.*)/){ } cmd2 = @set.command(/\.\|\|(.*)/){ } @set.find_command('.||').should == cmd2 end it "should find the command that has the longest name" do cmd = @set.command(/\.(.*)/){ } cmd2 = @set.command('.||'){ } @set.find_command('.||').should == cmd2 end end describe '.valid_command?' do it 'should be true for commands that can be found' do cmd = @set.command('archchancellor') @set.valid_command?('archchancellor of_the?(:University)').should == true end it 'should be false for commands that can\'' do @set.valid_command?('def monkey(ape)').should == false end it 'should not cause argument interpolation' do cmd = @set.command('hello') lambda { @set.valid_command?('hello #{raise "futz"}') }.should.not.raise end end describe '.process_line' do it 'should return Result.new(false) if there is no matching command' do result = @set.process_line('1 + 42') result.command?.should == false result.void_command?.should == false result.retval.should == nil end it 'should return Result.new(true, VOID) if the command is not keep_retval' do @set.create_command('mrs-cake') do def process; 42; end end result = @set.process_line('mrs-cake') result.command?.should == true result.void_command?.should == true result.retval.should == Pry::Command::VOID_VALUE end it 'should return Result.new(true, retval) if the command is keep_retval' do @set.create_command('magrat', 'the maiden', :keep_retval => true) do def process; 42; end end result = @set.process_line('magrat') result.command?.should == true result.void_command?.should == false result.retval.should == 42 end it 'should pass through context' do ctx = { :eval_string => "bloomers", :pry_instance => Object.new, :output => StringIO.new, :target => binding } @set.create_command('agnes') do define_method(:process) do eval_string.should == ctx[:eval_string] output.should == ctx[:output] target.should == ctx[:target] _pry_.should == ctx[:pry_instance] end end @set.process_line('agnes', ctx) end it 'should add command_set to context' do set = @set @set.create_command(/nann+y ogg+/) do define_method(:process) do command_set.should == set end end @set.process_line('nannnnnny oggggg') end end if defined?(Bond) describe '.complete' do it "should list all command names" do @set.create_command('susan'){ } @set.complete('sus').should.include 'susan ' end it "should delegate to commands" do @set.create_command('susan'){ def complete(search); ['--foo']; end } @set.complete('susan ').should == ['--foo'] end end end end pry-0.9.12.6/spec/run_command_spec.rb0000644000004100000410000000124612272154173017413 0ustar www-datawww-datarequire 'helper' describe "Pry.run_command" do before do o = Object.new def o.drum "roken is dodelijk" end @context = Pry.binding_for(o) end it 'performs a simple ls' do @context.eval("hokey_pokey = 10") Pry.run_command "ls", :context => @context, :output => out = StringIO.new out.string.should =~ /hokey_pokey/ end if !PryTestHelpers.mri18_and_no_real_source_location? # This is a regression test as 0.9.11 broke this behaviour it 'can perform a show-source' do Pry.run_command "show-source drum", :context => @context, :output => out = StringIO.new out.string.should =~ /roken is dodelijk/ end end end pry-0.9.12.6/spec/pry_output_spec.rb0000644000004100000410000000476212272154173017351 0ustar www-datawww-datarequire 'helper' describe Pry do describe "output failsafe" do after do Pry.config.print = Pry::DEFAULT_PRINT end it "should catch serialization exceptions" do Pry.config.print = lambda { |*a| raise "catch-22" } lambda { mock_pry("1") }.should.not.raise end it "should display serialization exceptions" do Pry.config.print = lambda { |*a| raise "catch-22" } mock_pry("1").should =~ /\(pry\) output error: #/ end it "should catch errors serializing exceptions" do Pry.config.print = lambda do |*a| raise Exception.new("catch-22").tap{ |e| class << e; def inspect; raise e; end; end } end mock_pry("1").should =~ /\(pry\) output error: failed to show result/ end end describe "DEFAULT_PRINT" do it "should output the right thing" do mock_pry("[1]").should =~ /^=> \[1\]/ end it "should include the =>" do accumulator = StringIO.new Pry.config.print.call(accumulator, [1]) accumulator.string.should == "=> \[1\]\n" end it "should not be phased by un-inspectable things" do mock_pry("class NastyClass; undef pretty_inspect; end", "NastyClass.new").should =~ /#<.*NastyClass:0x.*?>/ end end describe "color" do before do Pry.color = true end after do Pry.color = false end it "should colorize strings as though they were ruby" do accumulator = StringIO.new Pry.config.print.call(accumulator, [1]) accumulator.string.should == "=> [\e[1;34m1\e[0m]\e[0m\n" end it "should not colorize strings that already include color" do f = Object.new def f.inspect "\e[1;31mFoo\e[0m" end accumulator = StringIO.new Pry.config.print.call(accumulator, f) # We add an extra \e[0m to prevent color leak accumulator.string.should == "=> \e[1;31mFoo\e[0m\e[0m\n" end end describe "output suppression" do before do @t = pry_tester end it "should normally output the result" do mock_pry("1 + 2").should == "=> 3\n\n" end it "should not output anything if the input ends with a semicolon" do mock_pry("1 + 2;").should == "\n" end it "should output something if the input ends with a comment" do mock_pry("1 + 2 # basic addition").should == "=> 3\n\n" end it "should not output something if the input is only a comment" do mock_pry("# basic addition").should == "\n" end end end pry-0.9.12.6/spec/code_spec.rb0000644000004100000410000001324212272154172016021 0ustar www-datawww-datarequire 'helper' describe Pry::Code do describe '.from_file' do should 'read lines from a file on disk' do Pry::Code.from_file('lib/pry.rb').length.should > 0 end should 'read lines from Pry\'s line buffer' do pry_eval ':hay_guys' Pry::Code.from_file('(pry)').grep(/:hay_guys/).length.should == 1 end should 'default to Ruby' do temp_file('') do |f| Pry::Code.from_file(f.path).code_type.should == :ruby end end should 'check the extension' do temp_file('.c') do |f| Pry::Code.from_file(f.path).code_type.should == :c end end should 'use the provided extension' do temp_file('.c') do |f| Pry::Code.from_file(f.path, :ruby).code_type.should == :ruby end end should 'raise an error if the file doesn\'t exist' do proc do Pry::Code.from_file('/knalkjsdnalsd/alkjdlkq') end.should.raise(MethodSource::SourceNotFoundError) end should 'check for files relative to origin pwd' do Dir.chdir('spec') do |f| Pry::Code.from_file('spec/' + File.basename(__FILE__)).code_type.should == :ruby end end should 'find files that are relative to the current working directory' do Dir.chdir('spec') do |f| Pry::Code.from_file(File.basename(__FILE__)).code_type.should == :ruby end end end describe '.from_method' do should 'read lines from a method\'s definition' do m = Pry::Method.from_obj(Pry, :load_history) Pry::Code.from_method(m).length.should > 0 end end describe '#initialize' do before do @str = Pry::Helpers::CommandHelpers.unindent <<-CODE def hay :guys end CODE @array = ['def hay', ' :guys', 'end'] end should 'break a string into lines' do Pry::Code.new(@str).length.should == 3 end should 'accept an array' do Pry::Code.new(@array).length.should == 3 end it 'an array or string should produce an equivalent object' do Pry::Code.new(@str).should == Pry::Code.new(@array) end end describe 'filters and formatters' do before do @code = Pry::Code(Pry::Helpers::CommandHelpers.unindent <<-STR) class MyProgram def self.main puts 'Hello, world!' end end STR end describe 'filters' do describe '#between' do should 'work with an inclusive range' do @code = @code.between(1..3) @code.length.should == 3 @code.should =~ /\Aclass MyProgram/ @code.should =~ /world!'\Z/ end should 'default to an inclusive range' do @code = @code.between(3, 5) @code.length.should == 3 end should 'work with an exclusive range' do @code = @code.between(2...4) @code.length.should == 2 @code.should =~ /\A def self/ @code.should =~ /world!'\Z/ end should 'use real line numbers for positive indices' do @code = @code.after(3, 3) @code = @code.between(4, 4) @code.length.should == 1 @code.should =~ /\A end\Z/ end end describe '#before' do should 'work' do @code = @code.before(3, 1) @code.should =~ /\A def self\.main\Z/ end end describe '#around' do should 'work' do @code = @code.around(3, 1) @code.length.should == 3 @code.should =~ /\A def self/ @code.should =~ / end\Z/ end end describe '#after' do should 'work' do @code = @code.after(3, 1) @code.should =~ /\A end\Z/ end end describe '#grep' do should 'work' do @code = @code.grep(/end/) @code.length.should == 2 end end end describe 'formatters' do describe '#with_line_numbers' do should 'show line numbers' do @code = @code.with_line_numbers @code.should =~ /1:/ end should 'disable line numbers when falsy' do @code = @code.with_line_numbers @code = @code.with_line_numbers(false) @code.should.not =~ /1:/ end end describe '#with_marker' do should 'show a marker in the right place' do @code = @code.with_marker(2) @code.should =~ /^ => def self/ end should 'disable the marker when falsy' do @code = @code.with_marker(2) @code = @code.with_marker(false) @code.should =~ /^ def self/ end end describe '#with_indentation' do should 'indent the text' do @code = @code.with_indentation(2) @code.should =~ /^ def self/ end should 'disable the indentation when falsy' do @code = @code.with_indentation(2) @code = @code.with_indentation(false) @code.should =~ /^ def self/ end end end describe 'composition' do describe 'grep and with_line_numbers' do should 'work' do @code = @code.grep(/end/).with_line_numbers @code.should =~ /\A4: end/ @code.should =~ /5: end\Z/ end end describe 'grep and before and with_line_numbers' do should 'work' do @code = @code.grep(/e/).before(5, 5).with_line_numbers @code.should =~ /\A2: def self.main\n3:/ @code.should =~ /4: end\Z/ end end describe 'before and after' do should 'work' do @code = @code.before(4, 2).after(2) @code.should == " puts 'Hello, world!'" end end end end end pry-0.9.12.6/.travis.yml0000644000004100000410000000046512272154172014732 0ustar www-datawww-datarvm: - 1.8.7 - 1.9.2 - 1.9.3 - 2.0.0 - 2.1.0 - ruby-head - ree - rbx - jruby-19mode - jruby-head matrix: allow_failures: - rvm: ruby-head - rvm: jruby-head notifications: irc: "irc.freenode.org#pry" recipients: - jrmair@gmail.com branches: only: - 0-9-12-stable pry-0.9.12.6/lib/0000755000004100000410000000000012272154172013362 5ustar www-datawww-datapry-0.9.12.6/lib/pry/0000755000004100000410000000000012272154172014174 5ustar www-datawww-datapry-0.9.12.6/lib/pry/history.rb0000644000004100000410000000711012272154172016221 0ustar www-datawww-dataclass Pry # The History class is responsible for maintaining the user's input history, # both internally and within Readline. class History attr_accessor :loader, :saver, :pusher, :clearer # @return [Fixnum] Number of lines in history when Pry first loaded. attr_reader :original_lines def initialize @history = [] @saved_lines = 0 @original_lines = 0 restore_default_behavior end # Assign the default methods for loading, saving, pushing, and clearing. def restore_default_behavior @loader = method(:read_from_file) @saver = method(:write_to_file) @pusher = method(:push_to_readline) @clearer = method(:clear_readline) end # Load the input history using `History.loader`. # @return [Integer] The number of lines loaded def load @loader.call do |line| @pusher.call(line.chomp) @history << line.chomp end @saved_lines = @original_lines = @history.length end # Write this session's history using `History.saver`. # @return [Integer] The number of lines saved def save history_to_save = @history[@saved_lines..-1] @saver.call(history_to_save) @saved_lines = @history.length history_to_save.length end # Add a line to the input history, ignoring blank and duplicate lines. # @param [String] line # @return [String] The same line that was passed in def push(line) unless line.empty? || (@history.last && line == @history.last) @pusher.call(line) @history << line end line end alias << push # Clear all history. Anything the user entered before this point won't be # saved, but anything they put in afterwards will still be appended to the # history file on exit. def clear @clearer.call @history = [] @saved_lines = 0 end # @return [Fixnum] The number of lines in history. def history_line_count @history.count end def session_line_count @history.count - @original_lines end # Return an Array containing all stored history. # @return [Array] An Array containing all lines of history loaded # or entered by the user in the current session. def to_a @history.dup end private # The default loader. Yields lines from `Pry.history.config.file`. def read_from_file begin history_file = File.expand_path(Pry.config.history.file) if File.exists?(history_file) File.foreach(history_file) { |line| yield(line) } end rescue => error unless error.message.empty? warn "History file not loaded, received an error: #{error.message}" end end end # The default saver. Appends the given lines to `Pry.history.config.file`. # @param [Array] lines def write_to_file(lines) history_file = File.expand_path(Pry.config.history.file) begin File.open(history_file, 'a') do |f| lines.each { |ln| f.puts ln } end rescue Errno::EACCES # We should probably create an option Pry.show_warnings?!?!?! warn 'Unable to write to your history file, history not saved' end end # The default pusher. Appends the given line to Readline::HISTORY. # @param [String] line def push_to_readline(line) Pry.require_readline Readline::HISTORY << line end # The default clearer. Clears Readline::HISTORY. def clear_readline Pry.require_readline Readline::HISTORY.shift until Readline::HISTORY.empty? end end end pry-0.9.12.6/lib/pry/repl_file_loader.rb0000644000004100000410000000562512272154172020020 0ustar www-datawww-dataclass Pry # A class to manage the loading of files through the REPL loop. # This is an interesting trick as it processes your file as if it # was user input in an interactive session. As a result, all Pry # commands are available, and they are executed non-interactively. Furthermore # the session becomes interactive when the repl loop processes a # 'make-interactive' command in the file. The session also becomes # interactive when an exception is encountered, enabling you to fix # the error before returning to non-interactive processing with the # 'make-non-interactive' command. class REPLFileLoader def initialize(file_name) full_name = File.expand_path(file_name) raise RuntimeError, "No such file: #{full_name}" if !File.exists?(full_name) @content = StringIO.new(File.read(full_name)) end # Switch to interactive mode, i.e take input from the user # and use the regular print and exception handlers. # @param [Pry] _pry_ the Pry instance to make interactive. def interactive_mode(_pry_) _pry_.input = Pry.config.input _pry_.print = Pry.config.print _pry_.exception_handler = Pry.config.exception_handler end # Switch to non-interactive mode. Essentially # this means there is no result output # and that the session becomes interactive when an exception is encountered. # @param [Pry] _pry_ the Pry instance to make non-interactive. def non_interactive_mode(_pry_) _pry_.print = proc {} _pry_.exception_handler = proc do |o, e, _pry_| _pry_.run_command "cat --ex" o.puts "...exception encountered, going interactive!" interactive_mode(_pry_) end end # Define a few extra commands useful for flipping back & forth # between interactive/non-interactive modes def define_additional_commands s = self Pry::Commands.command "make-interactive", "Make the session interactive" do _pry_.input_stack.push _pry_.input s.interactive_mode(_pry_) end Pry::Commands.command "make-non-interactive", "Make the session non-interactive" do _pry_.input = _pry_.input_stack.pop s.non_interactive_mode(_pry_) end Pry::Commands.command "load-file", "Load another file through the repl" do |file_name| content = StringIO.new(File.read(File.expand_path(file_name))) _pry_.input_stack.push(_pry_.input) _pry_.input = content end end # Actually load the file through the REPL by setting file content # as the REPL input stream. def load Pry.initial_session_setup define_additional_commands Pry.config.hooks.add_hook(:when_started, :start_non_interactively) do |o, t, _pry_| non_interactive_mode(_pry_) end Pry.start(Pry.toplevel_binding, :input => @content, :input_stack => [StringIO.new("exit-all\n")]) end end end pry-0.9.12.6/lib/pry/pager.rb0000644000004100000410000000444012272154172015621 0ustar www-datawww-dataclass Pry::Pager # @param [String] text # A piece of text to run through a pager. # @param [Symbol?] pager # `:simple` -- Use the pure ruby pager. # `:system` -- Use the system pager (less) or the environment variable # $PAGER if set. # `nil` -- Infer what pager to use from the environment. What this # really means is that JRuby and systems that do not have # access to 'less' will run through the pure ruby pager. def self.page(text, pager = nil) case pager when nil no_pager = !SystemPager.available? if no_pager || Pry::Helpers::BaseHelpers.jruby? SimplePager.new(text).page else SystemPager.new(text).page end when :simple SimplePager.new(text).page when :system SystemPager.new(text).page else raise "'#{pager}' is not a recognized pager." end end def self.page_size @page_size ||= Pry::Terminal.height! end def initialize(text) @text = text end class SimplePager < Pry::Pager def page # The pager size minus the number of lines used by the simple pager info bar. page_size = Pry::Pager.page_size - 3 text_array = @text.lines.to_a text_array.each_slice(page_size) do |chunk| puts chunk.join break if chunk.size < page_size if text_array.size > page_size puts "\n --- Press enter to continue ( q to break ) --- " break if Readline.readline.chomp == "q" end end end end class SystemPager < Pry::Pager def self.default_pager pager = ENV["PAGER"] || "" # Default to less, and make sure less is being passed the correct options if pager.strip.empty? or pager =~ /^less\s*/ pager = "less -R -S -F -X" end pager end def self.available? if @system_pager.nil? @system_pager = begin pager_executable = default_pager.split(' ').first `which #{ pager_executable }` rescue false end else @system_pager end end def initialize(*) super @pager = SystemPager.default_pager end def page IO.popen(@pager, 'w') do |io| io.write @text end end end end pry-0.9.12.6/lib/pry/plugins.rb0000644000004100000410000000564512272154172016214 0ustar www-datawww-dataclass Pry class PluginManager PRY_PLUGIN_PREFIX = /^pry-/ # Placeholder when no associated gem found, displays warning class NoPlugin def initialize(name) @name = name end def method_missing(*args) warn "Warning: The plugin '#{@name}' was not found! (no gem found)" end end class Plugin attr_accessor :name, :gem_name, :enabled, :spec, :active def initialize(name, gem_name, spec, enabled) @name, @gem_name, @enabled, @spec = name, gem_name, enabled, spec end # Disable a plugin. (prevents plugin from being loaded, cannot # disable an already activated plugin) def disable! self.enabled = false end # Enable a plugin. (does not load it immediately but puts on # 'white list' to be loaded) def enable! self.enabled = true end # Load the Command line options defined by this plugin (if they exist) def load_cli_options cli_options_file = File.join(spec.full_gem_path, "lib/#{spec.name}/cli.rb") require cli_options_file if File.exists?(cli_options_file) end # Activate the plugin (require the gem - enables/loads the # plugin immediately at point of call, even if plugin is # disabled) # Does not reload plugin if it's already active. def activate! # Create the configuration object for the plugin. Pry.config.send("#{gem_name.gsub('-', '_')}=", OpenStruct.new) begin require gem_name if !active? rescue LoadError => e warn "Found plugin #{gem_name}, but could not require '#{gem_name}'" warn e rescue => e warn "require '#{gem_name}' # Failed, saying: #{e}" end self.active = true self.enabled = true end alias active? active alias enabled? enabled end def initialize @plugins = [] end # Find all installed Pry plugins and store them in an internal array. def locate_plugins Gem.refresh (Gem::Specification.respond_to?(:each) ? Gem::Specification : Gem.source_index.find_name('')).each do |gem| next if gem.name !~ PRY_PLUGIN_PREFIX plugin_name = gem.name.split('-', 2).last @plugins << Plugin.new(plugin_name, gem.name, gem, true) if !gem_located?(gem.name) end @plugins end # @return [Hash] A hash with all plugin names (minus the 'pry-') as # keys and Plugin objects as values. def plugins h = Hash.new { |_, key| NoPlugin.new(key) } @plugins.each do |plugin| h[plugin.name] = plugin end h end # Require all enabled plugins, disabled plugins are skipped. def load_plugins @plugins.each do |plugin| plugin.activate! if plugin.enabled? end end private def gem_located?(gem_name) @plugins.any? { |plugin| plugin.gem_name == gem_name } end end end pry-0.9.12.6/lib/pry/pry_instance.rb0000644000004100000410000006052412272154172017226 0ustar www-datawww-datarequire "pry/indent" ## # 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: # # * http://pry.github.com/ # * https://github.com/pry/pry # * the IRC channel, which is #pry on the Freenode network # class Pry attr_accessor :input attr_accessor :output attr_accessor :commands attr_accessor :print attr_accessor :exception_handler attr_accessor :input_stack attr_accessor :quiet alias :quiet? :quiet attr_accessor :custom_completions attr_accessor :binding_stack attr_accessor :last_result attr_accessor :last_file attr_accessor :last_dir attr_reader :last_exception attr_reader :input_array attr_reader :output_array attr_accessor :backtrace attr_accessor :extra_sticky_locals attr_accessor :suppress_output # This is exposed via Pry::Command#state. attr_reader :command_state # Special treatment for hooks as we want to alert people of the # changed API attr_reader :hooks # FIXME: # This is a hack to alert people of the new API. # @param [Pry::Hooks] v Only accept `Pry::Hooks` now! 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 # 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] :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) def initialize(options={}) refresh(options) @binding_stack = [] @indent = Pry::Indent.new @command_state = {} 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. 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 # The currently active `Binding`. # @return [Binding] The currently active `Binding` for the session. def current_context binding_stack.last 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] Current prompt. def prompt prompt_stack.last end def prompt=(new_prompt) if prompt_stack.empty? push_prompt new_prompt else prompt_stack[-1] = new_prompt 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. 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 # @return [Integer] The maximum amount of objects remembered by the inp and # out arrays. Defaults to 100. def memory_size @output_array.max_size end def memory_size=(size) @input_array = Pry::HistoryArray.new(size) @output_array = Pry::HistoryArray.new(size) end # Inject all the sticky locals into the `target` binding. # @param [Binding] target def inject_sticky_locals(target) sticky_locals.each_pair do |name, value| inject_local(name, value, target) end 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. def add_sticky_local(name, &block) sticky_locals[name] = block end # @return [Hash] The currently defined sticky locals. 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 # Initialize the repl session. # @param [Binding] target The target binding for the session. 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 # Clean-up after the repl session. # @param [Binding] target The target binding for the session. def repl_epilogue(target) exec_hook :after_session, output, target, self binding_stack.pop Pry.save_history if Pry.config.history.should_save 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) 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 # 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) def rep(target=TOPLEVEL_BINDING) target = Pry.binding_for(target) result = re(target) Pry.critical_section do show_result(result) 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) 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 # 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) 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 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 # Output the result or pass to an exception handler (if result is an exception). 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 def should_force_encoding?(eval_string, val) eval_string.empty? && val.respond_to?(:encoding) && val.encoding != eval_string.encoding end private :should_force_encoding? # Read and process a line of input -- check for ^D, determine which prompt to # use, rewrite the indentation if `Pry.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. 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 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) unless [val, eval_string].all?(&:empty?) eval_string << "#{indented_val.chomp}\n" end end ensure Pry.history << indented_val if interactive end 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 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 # 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") 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 # 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. 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 # 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. 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 # Set the last exception for a session. # @param [Exception] ex 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 # 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 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 # @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) def last_result_is_exception? @last_result_is_exception end # Manage switching of input objects on encountering EOFErrors def handle_read_errors should_retry = true exception_count = 0 begin yield rescue EOFError if input_stack.empty? self.input = Pry.config.input if !should_retry output.puts "Error: Pry ran out of things to read from! Attempting to break out of REPL." throw(:breakout) end should_retry = false else self.input = input_stack.pop end retry # Interrupts are handled in r() because they need to tweak eval_string # TODO: Refactor this baby. rescue Interrupt raise # If we get a random error when trying to read a line we don't want to automatically # retry, as the user will see a lot of error messages scroll past and be unable to do # anything about it. rescue RescuableException => e puts "Error: #{e.message}" output.puts e.backtrace exception_count += 1 if exception_count < 5 retry end puts "FATAL: Pry failed to get user input using `#{input}`." puts "To fix this you may be able to pass input and output file descriptors to pry directly. e.g." puts " Pry.config.input = STDIN" puts " Pry.config.output = STDOUT" puts " binding.pry" throw(:breakout) end end private :handle_read_errors # 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. 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 defined?(Readline) && 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 # 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. def should_print? !@suppress_output 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. 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 def generate_prompt(prompt_proc, conf) if prompt_proc.arity == 1 prompt_proc.call(conf) else prompt_proc.call(conf.object, conf.nesting_level, conf._pry_) end end private :generate_prompt # the array that the prompt stack is stored in def prompt_stack @prompt_stack ||= Array.new end private :prompt_stack # 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] new_prompt # @return [Array] new_prompt # @example # new_prompt = [ proc { '>' }, proc { '>>' } ] # push_prompt(new_prompt) # => new_prompt def push_prompt(new_prompt) prompt_stack.push new_prompt 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] 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 def pop_prompt prompt_stack.size > 1 ? prompt_stack.pop : prompt 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") # 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 def raise_up(*args); raise_up_common(false, *args); end def raise_up!(*args); raise_up_common(true, *args); end end pry-0.9.12.6/lib/pry/commands/0000755000004100000410000000000012272154172015775 5ustar www-datawww-datapry-0.9.12.6/lib/pry/commands/shell_command.rb0000644000004100000410000000176212272154172021135 0ustar www-datawww-dataclass Pry class Command::ShellCommand < Pry::ClassCommand match /\.(.*)/ group 'Input and Output' description "All text following a '.' is forwarded to the shell." command_options :listing => '.', :use_prefix => false, :takes_block => true banner <<-'BANNER' Usage: .COMMAND_NAME All text following a "." is forwarded to the shell. .ls -aF .uname BANNER def process(cmd) if cmd =~ /^cd\s+(.+)/i dest = $1 begin Dir.chdir File.expand_path(dest) rescue Errno::ENOENT raise CommandError, "No such directory: #{dest}" end else pass_block(cmd) if command_block command_block.call `#{cmd}` else Pry.config.system.call(output, cmd, _pry_) end end end def complete(search) super + Bond::Rc.files(search.split(" ").last || '') end end Pry::Commands.add_command(Pry::Command::ShellCommand) end pry-0.9.12.6/lib/pry/commands/gem_cd.rb0000644000004100000410000000112112272154172017533 0ustar www-datawww-dataclass Pry class Command::GemCd < Pry::ClassCommand match 'gem-cd' group 'Gems' description "Change working directory to specified gem's directory." command_options :argument_required => true banner <<-'BANNER' Usage: gem-cd GEM_NAME Change the current working directory to that in which the given gem is installed. BANNER def process(gem) Dir.chdir(Rubygem.spec(gem).full_gem_path) output.puts(Dir.pwd) end def complete(str) Rubygem.complete(str) end end Pry::Commands.add_command(Pry::Command::GemCd) end pry-0.9.12.6/lib/pry/commands/reload_code.rb0000644000004100000410000000374612272154172020574 0ustar www-datawww-dataclass Pry class Command::ReloadCode < Pry::ClassCommand match 'reload-code' group 'Misc' description 'Reload the source file that contains the specified code object.' banner <<-'BANNER' Reload the source file that contains the specified code object. e.g reload-code MyClass#my_method #=> reload a method reload-code MyClass #=> reload a class reload-code my-command #=> reload a pry command reload-code self #=> reload the 'current' object reload-code #=> identical to reload-code self BANNER def process if obj_name.empty? # if no parameters were provided then try to reload the # current file (i.e target.eval("__FILE__")) reload_current_file else code_object = Pry::CodeObject.lookup(obj_name, _pry_) reload_code_object(code_object) end end private def current_file File.expand_path target.eval("__FILE__") end def reload_current_file if !File.exists?(current_file) raise CommandError, "Current file: #{current_file} cannot be found on disk!" end load current_file output.puts "The current file: #{current_file} was reloaded!" end def reload_code_object(code_object) check_for_reloadability(code_object) load code_object.source_file output.puts "#{obj_name} was reloaded!" end def obj_name @obj_name ||= args.join(" ") end def check_for_reloadability(code_object) if !code_object || !code_object.source_file raise CommandError, "Cannot locate #{obj_name}!" elsif !File.exists?(code_object.source_file) raise CommandError, "Cannot reload #{obj_name} as it has no associated file on disk. File found was: #{code_object.source_file}" end end end Pry::Commands.add_command(Pry::Command::ReloadCode) Pry::Commands.alias_command 'reload-method', 'reload-code' end pry-0.9.12.6/lib/pry/commands/raise_up.rb0000644000004100000410000000222312272154172020130 0ustar www-datawww-dataclass Pry # N.B. using a regular expresion here so that "raise-up 'foo'" does the right thing. class Command::RaiseUp < Pry::ClassCommand match /raise-up(!?\b.*)/ group 'Context' description 'Raise an exception out of the current pry instance.' command_options :listing => 'raise-up' banner <<-BANNER Raise up, like exit, allows you to quit pry. Instead of returning a value however, it raises an exception. If you don't provide the exception to be raised, it will use the most recent exception (in pry `_ex_`). When called as raise-up! (with an exclamation mark), this command raises the exception through any nested prys you have created by "cd"ing into objects. raise-up "get-me-out-of-here" # This is equivalent to the command above. raise "get-me-out-of-here" raise-up BANNER def process return stagger_output help if captures[0] =~ /(-h|--help)\b/ # Handle 'raise-up', 'raise-up "foo"', 'raise-up RuntimeError, 'farble' in a rubyesque manner target.eval("_pry_.raise_up#{captures[0]}") end end Pry::Commands.add_command(Pry::Command::RaiseUp) end pry-0.9.12.6/lib/pry/commands/gem_open.rb0000644000004100000410000000130312272154172020110 0ustar www-datawww-dataclass Pry class Command::GemOpen < Pry::ClassCommand match 'gem-open' group 'Gems' description 'Opens the working directory of the gem in your editor' command_options :argument_required => true banner <<-'BANNER' Usage: gem-open GEM_NAME Change the current working directory to that in which the given gem is installed, and then opens your text editor. gem-open pry-exception_explorer BANNER def process(gem) Dir.chdir(Rubygem.spec(gem).full_gem_path) do Pry::Editor.invoke_editor(".", 0, false) end end def complete(str) Rubygem.complete(str) end end Pry::Commands.add_command(Pry::Command::GemOpen) end pry-0.9.12.6/lib/pry/commands/show_source.rb0000644000004100000410000000234312272154172020664 0ustar www-datawww-datarequire 'pry/commands/show_info' class Pry class Command::ShowSource < Command::ShowInfo match 'show-source' group 'Introspection' description 'Show the source for a method or class.' banner <<-'BANNER' Usage: show-source [OPTIONS] [METH|CLASS] Aliases: $, show-method Show the source for a method or class. Tries instance methods first and then methods by default. show-source hi_method show-source hi_method show-source Pry#rep # source for Pry#rep method show-source Pry # for Pry class show-source Pry -a # for all Pry class definitions (all monkey patches) show-source Pry --super # for superclass of Pry (Object class) https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method BANNER # The source for code_object prepared for display. def content_for(code_object) cannot_locate_source_error if !code_object.source Code.new(code_object.source, start_line_for(code_object)). with_line_numbers(use_line_numbers?).to_s end end Pry::Commands.add_command(Pry::Command::ShowSource) Pry::Commands.alias_command 'show-method', 'show-source' Pry::Commands.alias_command '$', 'show-source' end pry-0.9.12.6/lib/pry/commands/pry_backtrace.rb0000644000004100000410000000151512272154172021135 0ustar www-datawww-dataclass Pry class Command::PryBacktrace < Pry::ClassCommand match 'pry-backtrace' group 'Context' description 'Show the backtrace for the Pry session.' banner <<-BANNER Usage: pry-backtrace [OPTIONS] [--help] Show the backtrace for the position in the code where Pry was started. This can be used to infer the behavior of the program immediately before it entered Pry, just like the backtrace property of an exception. NOTE: if you are looking for the backtrace of the most recent exception raised, just type: `_ex_.backtrace` instead. See: https://github.com/pry/pry/wiki/Special-Locals BANNER def process stagger_output text.bold('Backtrace:') + "\n--\n" + _pry_.backtrace.join("\n") end end Pry::Commands.add_command(Pry::Command::PryBacktrace) end pry-0.9.12.6/lib/pry/commands/reset.rb0000644000004100000410000000053512272154172017447 0ustar www-datawww-dataclass Pry class Command::Reset < Pry::ClassCommand match 'reset' group 'Context' description 'Reset the REPL to a clean state.' banner <<-'BANNER' Reset the REPL to a clean state. BANNER def process output.puts 'Pry reset.' exec 'pry' end end Pry::Commands.add_command(Pry::Command::Reset) end pry-0.9.12.6/lib/pry/commands/play.rb0000644000004100000410000000361012272154172017267 0ustar www-datawww-dataclass Pry class Command::Play < Pry::ClassCommand match 'play' group 'Editing' description 'Playback a string variable or a method or a file as input.' banner <<-'BANNER' Usage: play [OPTIONS] [--help] The play command enables you to replay code from files and methods as if they were entered directly in the Pry REPL. play --lines 149..153 play -i 20 --lines 1..3 play Pry#repl --lines 1..-1 play Rakefile --lines 5 https://github.com/pry/pry/wiki/User-Input#wiki-Play BANNER def options(opt) CodeCollector.inject_options(opt) opt.on :open, 'Plays the select content except except' \ ' the last line. Useful for replaying methods and leaving the method definition "open". `amend-line`' \ ' can then be used to modify the method.' end def process @cc = CodeCollector.new(args, opts, _pry_) perform_play run "show-input" unless Pry::Code.complete_expression?(eval_string) end def perform_play eval_string << (opts.present?(:open) ? restrict_to_lines(content, (0..-2)) : content) run "fix-indent" end def should_use_default_file? !args.first && !opts.present?(:in) && !opts.present?(:out) end def content if should_use_default_file? file_content else @cc.content end end # The file to play from when no code object is specified. # e.g `play --lines 4..10` def default_file target.eval("__FILE__") && File.expand_path(target.eval("__FILE__")) end def file_content if default_file && File.exists?(default_file) @cc.restrict_to_lines(File.read(default_file), @cc.line_range) else raise CommandError, "File does not exist! File was: #{default_file.inspect}" end end end Pry::Commands.add_command(Pry::Command::Play) end pry-0.9.12.6/lib/pry/commands/cd.rb0000644000004100000410000000146112272154172016712 0ustar www-datawww-dataclass Pry class Command::Cd < Pry::ClassCommand match 'cd' group 'Context' description 'Move into a new context (object or scope).' banner <<-'BANNER' Usage: cd [OPTIONS] [--help] Move into new context (object or scope). As in UNIX shells use `cd ..` to go back, `cd /` to return to Pry top-level and `cd -` to toggle between last two scopes. Complex syntax (e.g `cd ../@x/y`) also supported. cd @x cd .. cd / cd - https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope BANNER def process state.old_stack ||= [] stack, state.old_stack = context_from_object_path(arg_string, _pry_, state.old_stack) _pry_.binding_stack = stack if stack end end Pry::Commands.add_command(Pry::Command::Cd) end pry-0.9.12.6/lib/pry/commands/fix_indent.rb0000644000004100000410000000064512272154172020456 0ustar www-datawww-dataclass Pry class Command::FixIndent < Pry::ClassCommand match 'fix-indent' group 'Input and Output' description "Correct the indentation for contents of the input buffer" banner <<-USAGE Usage: fix-indent USAGE def process indented_str = Pry::Indent.indent(eval_string) eval_string.replace indented_str end end Pry::Commands.add_command(Pry::Command::FixIndent) end pry-0.9.12.6/lib/pry/commands/install_command.rb0000644000004100000410000000303012272154172021462 0ustar www-datawww-dataclass Pry class Command::InstallCommand < Pry::ClassCommand match 'install-command' group 'Commands' description 'Install a disabled command.' banner <<-'BANNER' Usage: install-command COMMAND Installs the gems necessary to run the given COMMAND. You will generally not need to run this unless told to by an error message. BANNER def process(name) require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller command = find_command(name) if command_dependencies_met?(command.options) output.puts "Dependencies for #{command.name} are met. Nothing to do." return end output.puts "Attempting to install `#{name}` command..." gems_to_install = Array(command.options[:requires_gem]) gems_to_install.each do |g| next if Rubygem.installed?(g) output.puts "Installing `#{g}` gem..." begin Gem::DependencyInstaller.new.install(g) rescue Gem::GemNotFoundException raise CommandError, "Required Gem: `#{g}` not found. Aborting command installation." end end Gem.refresh gems_to_install.each do |g| begin require g rescue LoadError raise CommandError, "Required Gem: `#{g}` installed but not found?!. Aborting command installation." end end output.puts "Installation of `#{name}` successful! Type `help #{name}` for information" end end Pry::Commands.add_command(Pry::Command::InstallCommand) end pry-0.9.12.6/lib/pry/commands/gist.rb0000644000004100000410000000555212272154172017277 0ustar www-datawww-dataclass Pry class Command::Gist < Pry::ClassCommand match 'gist' group 'Misc' description 'Playback a string variable or a method or a file as input.' command_options :requires_gem => "jist" banner <<-'BANNER' Usage: gist [OPTIONS] [--help] The gist command enables you to gist code from files and methods to github. gist -i 20 --lines 1..3 gist Pry#repl --lines 1..-1 gist Rakefile --lines 5 BANNER def setup require 'jist' end def options(opt) CodeCollector.inject_options(opt) opt.on :login, "Authenticate the jist gem with GitHub" opt.on :p, :public, "Create a public gist (default: false)", :default => false opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", :default => false end def process return Jist.login! if opts.present?(:login) cc = CodeCollector.new(args, opts, _pry_) if cc.content =~ /\A\s*\z/ raise CommandError, "Found no code to gist." end if opts.present?(:clip) clipboard_content(cc.content) else # we're overriding the default behavior of the 'in' option (as # defined on CodeCollector) with our local behaviour. content = opts.present?(:in) ? input_content : cc.content gist_content content, cc.file end end def clipboard_content(content) Jist.copy(content) output.puts "Copied content to clipboard!" end def input_content content = "" CodeCollector.input_expression_ranges.each do |range| input_expressions = _pry_.input_array[range] || [] Array(input_expressions).each_with_index do |code, index| corrected_index = index + range.first if code && code != "" content << code if code !~ /;\Z/ content << "#{comment_expression_result_for_gist(Pry.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}" end end end end content end def comment_expression_result_for_gist(result) content = "" result.lines.each_with_index do |line, index| if index == 0 content << "# => #{line}" else content << "# #{line}" end end content end def gist_content(content, filename) response = Jist.gist(content, :filename => filename || "pry_gist.rb", :public => !!opts[:p]) if response url = response['html_url'] message = "Gist created at URL #{url}" begin Jist.copy(url) message << ", which is now in the clipboard." rescue Jist::ClipboardError end output.puts message end end end Pry::Commands.add_command(Pry::Command::Gist) Pry::Commands.alias_command 'clipit', 'gist --clip' Pry::Commands.alias_command 'jist', 'gist' end pry-0.9.12.6/lib/pry/commands/exit.rb0000644000004100000410000000223112272154172017271 0ustar www-datawww-dataclass Pry class Command::Exit < Pry::ClassCommand match 'exit' group 'Navigating Pry' description 'Pop the previous binding.' command_options :keep_retval => true banner <<-'BANNER' Usage: exit [OPTIONS] [--help] Aliases: quit Pop the previous binding (does NOT exit program). It can be useful to exit a context with a user-provided value. For instance an exit value can be used to determine program flow. exit "pry this" exit https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value BANNER def process if _pry_.binding_stack.one? _pry_.run_command "exit-all #{arg_string}" else # otherwise just pop a binding and return user supplied value process_pop_and_return end end def process_pop_and_return popped_object = _pry_.binding_stack.pop.eval('self') # return a user-specified value if given otherwise return the object return target.eval(arg_string) unless arg_string.empty? popped_object end end Pry::Commands.add_command(Pry::Command::Exit) Pry::Commands.alias_command 'quit', 'exit' end pry-0.9.12.6/lib/pry/commands/amend_line.rb0000644000004100000410000000662312272154172020424 0ustar www-datawww-dataclass Pry class Command::AmendLine < Pry::ClassCommand match /amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/ group 'Editing' description 'Amend a line of input in multi-line mode.' command_options :interpolate => false, :listing => 'amend-line' banner <<-'BANNER' Amend a line of input in multi-line mode. `amend-line N`, where the N represents line to replace. Can also specify a range of lines using `amend-line N..M` syntax. Passing "!" as replacement content deletes the line(s) instead. amend-line 1 puts 'new' # replace line 1 amend-line 1..4 ! # delete lines 1..4 amend-line 3 >puts 'bye' # insert before line 3 amend-line puts 'appended' # no line number modifies immediately preceding line BANNER def process raise CommandError, "No input to amend." if eval_string.empty? eval_string.replace amended_input(eval_string) run "fix-indent" run "show-input" end private # @param [String] string The string to amend. # @return [String] A new string with the amendments applied to it. def amended_input(string) input_array = eval_string.each_line.to_a if arg_string == "!" delete_from_array(input_array, line_range) elsif arg_string.start_with?(">") insert_into_array(input_array, line_range) else replace_in_array(input_array, line_range) end input_array.join end def delete_from_array(array, range) array.slice!(range) end def insert_into_array(array, range) insert_slot = Array(range).first array.insert(insert_slot, arg_string[1..-1] + "\n") end def replace_in_array(array, range) array[range] = arg_string + "\n" end # @return [Fixnum] The number of lines currently in `eval_string` (the input buffer). def line_count eval_string.lines.count end # Returns the (one-indexed) start and end lines given by the user. # The lines in this range will be affected by the `amend-line`. # Returns `nil` if no lines were specified by the user. # @return [Array, nil] def start_and_end_line_number start_line_number, end_line_number = args end_line_number ||= start_line_number.to_i [start_line_number.to_i, end_line_number.to_i] if start_line_number end # Takes two numbers that are 1-indexed, and returns a range (or # number) that is 0-indexed. 1-indexed means the first element is # indentified by 1 rather than by 0 (as is the case for Ruby arrays). # @param [Fixnum] start_line_number One-indexed number. # @param [Fixnum] end_line_number One-indexed number. # @return [Range] The zero-indexed range. def zero_indexed_range_from_one_indexed_numbers(start_line_number, end_line_number) # FIXME: one_index_number is a horrible name for this method one_index_number(start_line_number)..one_index_number(end_line_number) end # The lines (or line) that will be modified by the `amend-line`. # @return [Range, Fixnum] The lines or line. def line_range start_line_number, end_line_number = start_and_end_line_number if start_line_number zero_indexed_range_from_one_indexed_numbers(start_line_number, end_line_number) else line_count - 1 end end end Pry::Commands.add_command(Pry::Command::AmendLine) end pry-0.9.12.6/lib/pry/commands/code_collector.rb0000644000004100000410000001151112272154172021301 0ustar www-datawww-dataclass Pry class Command::CodeCollector include Helpers::CommandHelpers attr_accessor :args attr_accessor :opts attr_accessor :_pry_ # The name of the explicitly given file (if any). attr_accessor :file class << self attr_accessor :input_expression_ranges attr_accessor :output_result_ranges end @input_expression_ranges = [] @output_result_ranges = [] def initialize(args, opts, _pry_) @args = args @opts = opts @_pry_ = _pry_ end # Add the `--lines`, `-o`, `-i`, `-s`, `-d` options. def self.inject_options(opt) @input_expression_ranges = [] @output_result_ranges = [] opt.on :l, :lines, "Restrict to a subset of lines. Takes a line number or range", :optional_argument => true, :as => Range, :default => 1..-1 opt.on :o, :out, "Select lines from Pry's output result history. Takes an index or range", :optional_argument => true, :as => Range, :default => -5..-1 do |r| output_result_ranges << (r || (-5..-1)) end opt.on :i, :in, "Select lines from Pry's input expression history. Takes an index or range", :optional_argument => true, :as => Range, :default => -5..-1 do |r| input_expression_ranges << (r || (-5..-1)) end opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count opt.on :d, :doc, "Select lines from the code object's documentation" end # The content (i.e code/docs) for the selected object. # If the user provided a bare code object, it returns the source. # If the user provided the `-i` or `-o` switches, it returns the # selected input/output lines joined as a string. If the user used # `-d CODE_OBJECT` it returns the docs for that code object. # # @return [String] def content return @content if @content raise CommandError, "Only one of --out, --in, --doc and CODE_OBJECT may be specified." if bad_option_combination? content = case when opts.present?(:o) pry_output_content when opts.present?(:i) pry_input_content when opts.present?(:d) code_object_doc else code_object_source_or_file end @content ||= restrict_to_lines(content, line_range) end # The code object # # @return [Pry::WrappedModule, Pry::Method, Pry::Command] def code_object Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) end # Given a string and a range, return the `range` lines of that # string. # # @param [String] content # @param [Range, Fixnum] range # @return [String] The string restricted to the given range def restrict_to_lines(content, range) Array(content.lines.to_a[range]).join end # The selected `_pry_.output_array` as a string, as specified by # the `-o` switch. # # @return [String] def pry_output_content pry_array_content_as_string(_pry_.output_array, self.class.output_result_ranges) do |v| Pry.config.gist.inspecter.call(v) end end # The selected `_pry_.input_array` as a string, as specified by # the `-i` switch. # # @return [String] def pry_input_content pry_array_content_as_string(_pry_.input_array, self.class.input_expression_ranges) { |v| v } end # The line range passed to `--lines`, converted to a 0-indexed range. def line_range opts.present?(:lines) ? one_index_range_or_number(opts[:lines]) : 0..-1 end # Name of the object argument def obj_name @obj_name ||= args.empty? ? "" : args.join(" ") end private def bad_option_combination? [opts.present?(:in), opts.present?(:out), !args.empty?].count(true) > 1 end def pry_array_content_as_string(array, ranges, &block) all = '' ranges.each do |range| raise CommandError, "Minimum value for range is 1, not 0." if convert_to_range(range).first == 0 ranged_array = Array(array[range]) || [] ranged_array.compact.each { |v| all << block.call(v) } end all end def code_object_doc (code_object && code_object.doc) or could_not_locate(obj_name) end def code_object_source_or_file (code_object && code_object.source) || file_content end def file_content if File.exists?(obj_name) # Set the file accessor. self.file = obj_name File.read(obj_name) else could_not_locate(obj_name) end end def could_not_locate(name) raise CommandError, "Cannot locate: #{name}!" end def convert_to_range(n) if !n.is_a?(Range) (n..n) else n end end end end pry-0.9.12.6/lib/pry/commands/disabled_commands.rb0000644000004100000410000000023712272154172021754 0ustar www-datawww-dataPry::Commands.disabled_command("edit-method", "Use `edit` instead.") Pry::Commands.disabled_command("show-command", "Use show-source [command_name] instead.") pry-0.9.12.6/lib/pry/commands/switch_to.rb0000644000004100000410000000125512272154172020330 0ustar www-datawww-dataclass Pry class Command::SwitchTo < Pry::ClassCommand match 'switch-to' group 'Navigating Pry' description 'Start a new subsession on a binding in the current stack.' banner <<-'BANNER' Start a new subsession on a binding in the current stack (numbered by nesting). BANNER def process(selection) selection = selection.to_i if selection < 0 || selection > _pry_.binding_stack.size - 1 raise CommandError, "Invalid binding index #{selection} - use `nesting` command to view valid indices." else Pry.start(_pry_.binding_stack[selection]) end end end Pry::Commands.add_command(Pry::Command::SwitchTo) end pry-0.9.12.6/lib/pry/commands/gem_install.rb0000644000004100000410000000133412272154172020621 0ustar www-datawww-dataclass Pry class Command::GemInstall < Pry::ClassCommand match 'gem-install' group 'Gems' description 'Install a gem and refresh the gem cache.' command_options :argument_required => true banner <<-'BANNER' Usage: gem-install GEM_NAME Installs the given gem and refreshes the gem cache so that you can immediately 'require GEM_FILE'. gem-install pry-stack_explorer BANNER def setup require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller end def process(gem) Rubygem.install(gem) output.puts "Gem `#{ text.green(gem) }` installed." require gem end end Pry::Commands.add_command(Pry::Command::GemInstall) end pry-0.9.12.6/lib/pry/commands/import_set.rb0000644000004100000410000000106612272154172020512 0ustar www-datawww-dataclass Pry class Command::ImportSet < Pry::ClassCommand match 'import-set' group 'Commands' # TODO: Provide a better description with examples and a general conception # of this command. description 'Import a Pry command set.' banner <<-'BANNER' Import a Pry command set. BANNER def process(command_set_name) raise CommandError, "Provide a command set name" if command_set.nil? set = target.eval(arg_string) _pry_.commands.import set end end Pry::Commands.add_command(Pry::Command::ImportSet) end pry-0.9.12.6/lib/pry/commands/find_method.rb0000644000004100000410000001277112272154172020612 0ustar www-datawww-dataclass Pry class Command::FindMethod < Pry::ClassCommand extend Pry::Helpers::BaseHelpers match 'find-method' group 'Context' description 'Recursively search for a method within a Class/Module or the current namespace.' command_options :shellwords => false command_options :requires_gem => 'ruby18_source_location' if mri_18? banner <<-'BANNER' Usage: find-method [-n|-c] METHOD [NAMESPACE] Recursively search for a method within a Class/Module or the current namespace. Use the `-n` switch (the default) to search for methods whose name matches the given regex. Use the `-c` switch to search for methods that contain the given code. # Find all methods whose name match /re/ inside # the Pry namespace. Matches Pry#repl, etc. find-method re Pry # Find all methods that contain the code: # output.puts inside the Pry namepsace. find-method -c 'output.puts' Pry BANNER def setup require 'ruby18_source_location' if mri_18? end def options(opti) opti.on :n, :name, "Search for a method by name" opti.on :c, :content, "Search for a method based on content in Regex form" end def process return if args.size < 1 klass = search_class matches = if opts.content? content_search(klass) else name_search(klass) end show_search_results(matches) end private # @return [Regexp] The pattern to search for. def pattern @pattern ||= ::Regexp.new args[0] end # Output the result of the search. # # @param [Array] matches def show_search_results(matches) if matches.empty? output.puts text.bold("No Methods Matched") else print_matches(matches) end end # The class to search for methods. # We only search classes, so if the search object is an # instance, return its class. If no search object is given # search `target_self`. def search_class klass = if args[1] target.eval(args[1]) else target_self end klass.is_a?(Module) ? klass : klass.class end # pretty-print a list of matching methods. # # @param Array[Method] def print_matches(matches) grouped = matches.group_by(&:owner) order = grouped.keys.sort_by{ |x| x.name || x.to_s } order.each do |klass| print_matches_for_class(klass, grouped) end end # Print matched methods for a class def print_matches_for_class(klass, grouped) output.puts text.bold(klass.name) grouped[klass].each do |method| header = method.name_with_owner output.puts header + additional_info(header, method) end end # Return the matched lines of method source if `-c` is given or "" # if `-c` was not given def additional_info(header, method) if opts.content? ": " + colorize_code(matched_method_lines(header, method)) else "" end end def matched_method_lines(header, method) method.source.split(/\n/).select {|x| x =~ pattern }.join("\n#{' ' * header.length}") end # Run the given block against every constant in the provided namespace. # # @param Module The namespace in which to start the search. # @param Hash[Module,Boolean] The namespaces we've already visited (private) # @yieldparam klazz Each class/module in the namespace. # def recurse_namespace(klass, done={}, &block) return if !(Module === klass) || done[klass] done[klass] = true yield klass klass.constants.each do |name| next if klass.autoload?(name) begin const = klass.const_get(name) rescue RescuableException # constant loading is an inexact science at the best of times, # this often happens when a constant was .autoload? but someone # tried to load it. It's now not .autoload? but will still raise # a NameError when you access it. else recurse_namespace(const, done, &block) end end end # Gather all the methods in a namespace that pass the given block. # # @param Module The namespace in which to search. # @yieldparam Method The method to test # @yieldreturn Boolean # @return Array[Method] # def search_all_methods(namespace) done = Hash.new{ |h,k| h[k] = {} } matches = [] recurse_namespace(namespace) do |klass| (Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method| next if done[method.owner][method.name] done[method.owner][method.name] = true matches << method if yield method end end matches end # Search for all methods with a name that matches the given regex # within a namespace. # # @param Module The namespace to search # @return Array[Method] # def name_search(namespace) search_all_methods(namespace) do |meth| meth.name =~ pattern end end # Search for all methods who's implementation matches the given regex # within a namespace. # # @param Module The namespace to search # @return Array[Method] # def content_search(namespace) search_all_methods(namespace) do |meth| begin meth.source =~ pattern rescue RescuableException false end end end end Pry::Commands.add_command(Pry::Command::FindMethod) end pry-0.9.12.6/lib/pry/commands/ri.rb0000644000004100000410000000257612272154172016746 0ustar www-datawww-dataclass Pry class Command::Ri < Pry::ClassCommand match 'ri' group 'Introspection' description 'View ri documentation.' banner <<-'BANNER' Usage: ri [spec] View ri documentation. Relies on the "rdoc" gem being installed. See also "show-doc" command. ri Array#each BANNER def process(spec) # Lazily load RI require 'rdoc/ri/driver' unless defined? RDoc::RI::PryDriver # Subclass RI so that it formats its output nicely, and uses `lesspipe`. subclass = Class.new(RDoc::RI::Driver) # the hard way. subclass.class_eval do def page paging_text = StringIO.new yield paging_text Pry::Pager.page(paging_text.string) end def formatter(io) if @formatter_klass then @formatter_klass.new else RDoc::Markup::ToAnsi.new end end end RDoc::RI.const_set :PryDriver, subclass # hook it up! end # Spin-up an RI insance. ri = RDoc::RI::PryDriver.new :use_stdout => true, :interactive => false begin ri.display_names [spec] # Get the documentation (finally!) rescue RDoc::RI::Driver::NotFoundError => e output.puts "error: '#{e.name}' not found" end end end Pry::Commands.add_command(Pry::Command::Ri) end pry-0.9.12.6/lib/pry/commands/simple_prompt.rb0000644000004100000410000000070312272154172021214 0ustar www-datawww-dataclass Pry class Command::SimplePrompt < Pry::ClassCommand match 'simple-prompt' group 'Misc' description 'Toggle the simple prompt.' banner <<-'BANNER' Toggle the simple prompt. BANNER def process case _pry_.prompt when Pry::SIMPLE_PROMPT _pry_.pop_prompt else _pry_.push_prompt Pry::SIMPLE_PROMPT end end end Pry::Commands.add_command(Pry::Command::SimplePrompt) end pry-0.9.12.6/lib/pry/commands/wtf.rb0000644000004100000410000000247612272154172017133 0ustar www-datawww-dataclass Pry class Command::Wtf < Pry::ClassCommand match /wtf([?!]*)/ group 'Context' description 'Show the backtrace of the most recent exception.' options :listing => 'wtf?' banner <<-'BANNER' Usage: wtf[?|!] Show's a few lines of the backtrace of the most recent exception (also available as `_ex_.backtrace`). If you want to see more lines, add more question marks or exclamation marks. wtf? wtf?!???!?!? # To see the entire backtrace, pass the `-v` or `--verbose` flag. wtf -v BANNER def options(opt) opt.on :v, :verbose, "Show the full backtrace" end def process raise Pry::CommandError, "No most-recent exception" unless exception output.puts "#{text.bold('Exception:')} #{exception.class}: #{exception}\n--" if opts.verbose? output.puts with_line_numbers(backtrace) else output.puts with_line_numbers(backtrace.first(size_of_backtrace)) end end private def exception _pry_.last_exception end def with_line_numbers(bt) Pry::Code.new(bt, 0, :text).with_line_numbers.to_s end def backtrace exception.backtrace end def size_of_backtrace [captures[0].size, 0.5].max * 10 end end Pry::Commands.add_command(Pry::Command::Wtf) end pry-0.9.12.6/lib/pry/commands/jump_to.rb0000644000004100000410000000151512272154172020001 0ustar www-datawww-dataclass Pry class Command::JumpTo < Pry::ClassCommand match 'jump-to' group 'Navigating Pry' description 'Jump to a binding further up the stack.' banner <<-'BANNER' Jump to a binding further up the stack, popping all bindings below. BANNER def process(break_level) break_level = break_level.to_i nesting_level = _pry_.binding_stack.size - 1 case break_level when nesting_level output.puts "Already at nesting level #{nesting_level}" when (0...nesting_level) _pry_.binding_stack.slice!(break_level + 1, _pry_.binding_stack.size) else max_nest_level = nesting_level - 1 output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}." end end end Pry::Commands.add_command(Pry::Command::JumpTo) end pry-0.9.12.6/lib/pry/commands/help.rb0000644000004100000410000001145512272154172017260 0ustar www-datawww-dataclass Pry class Command::Help < Pry::ClassCommand match 'help' group 'Help' description 'Show a list of commands or information about a specific command' banner <<-'BANNER' Usage: help [COMMAND] With no arguments, help lists all the available commands in the current command-set along with their description. When given a command name as an argument, shows the help for that command. BANNER # We only want to show commands that have descriptions, so that the # easter eggs don't show up. def visible_commands visible = {} commands.each do |key, command| visible[key] = command if command.description && !command.description.empty? end visible end # Get a hash of available commands grouped by the "group" name. def command_groups visible_commands.values.group_by(&:group) end def process if args.empty? display_index(command_groups) else display_search(args.first) end end # Display the index view, with headings and short descriptions per command. # # @param Hash[String => Array[Commands]] def display_index(groups) help_text = [] sorted_group_names(groups).each do |group_name| commands = sorted_commands(groups[group_name]) if commands.any? help_text << help_text_for_commands(group_name, commands) end end stagger_output(help_text.join("\n\n")) end # Given a group name and an array of commands, # return the help string for those commands. # # @param [String] name The group name. # @param [Array]] commands # @return [String] The generated help string. def help_text_for_commands(name, commands) "#{text.bold(name)}\n" + commands.map do |command| " #{command.options[:listing].to_s.ljust(18)} #{command.description}" end.join("\n") end # @param [Hash] groups # @return [Array] An array of sorted group names. def sorted_group_names(groups) groups.keys.sort_by(&method(:group_sort_key)) end # Sort an array of commands by their `listing` name. # # @param [Array] commands The commands to sort # @return [Array] commands sorted by listing name. def sorted_commands(commands) commands.sort_by{ |command| command.options[:listing].to_s } end # Display help for an individual command or group. # # @param [String] search The string to search for. def display_search(search) if command = command_set.find_command_for_help(search) display_command(command) else display_filtered_search_results(search) end end # Display help for a searched item, filtered first by group # and if that fails, filtered by command name. # # @param [String] search The string to search for. def display_filtered_search_results(search) groups = search_hash(search, command_groups) if groups.size > 0 display_index(groups) else display_filtered_commands(search) end end # Display help for a searched item, filtered by group # # @param [String] search The string to search for. def display_filtered_commands(search) filtered = search_hash(search, visible_commands) raise CommandError, "No help found for '#{args.first}'" if filtered.empty? if filtered.size == 1 display_command(filtered.values.first) else display_index({"'#{search}' commands" => filtered.values}) end end # Display help for an individual command. # # @param [Pry::Command] command def display_command(command) stagger_output command.new.help end # Find a subset of a hash that matches the user's search term. # # If there's an exact match a Hash of one element will be returned, # otherwise a sub-Hash with every key that matches the search will # be returned. # # @param [String] the search term # @param [Hash] the hash to search def search_hash(search, hash) matching = {} hash.each_pair do |key, value| next unless key.is_a?(String) if normalize(key) == normalize(search) return {key => value} elsif normalize(key).start_with?(normalize(search)) matching[key] = value end end matching end # Clean search terms to make it easier to search group names # # @param String # @return String def normalize(key) key.downcase.gsub(/pry\W+/, '') end def group_sort_key(group_name) [%w(Help Context Editing Introspection Input_and_output Navigating_pry Gems Basic Commands).index(group_name.gsub(' ', '_')) || 99, group_name] end end Pry::Commands.add_command(Pry::Command::Help) end pry-0.9.12.6/lib/pry/commands/edit.rb0000644000004100000410000001525012272154172017252 0ustar www-datawww-dataclass Pry class Command::Edit < Pry::ClassCommand require 'pry/commands/edit/method_patcher' require 'pry/commands/edit/exception_patcher' require 'pry/commands/edit/file_and_line_locator' match 'edit' group 'Editing' description 'Invoke the default editor on a file.' banner <<-'BANNER' Usage: edit [--no-reload|--reload|--patch] [--line LINE] [--temp|--ex|FILE[:LINE]|OBJECT|--in N] Open a text editor. When no FILE is given, edits the pry input buffer. When a method/module/command is given, the code is opened in an editor. Ensure `Pry.config.editor` is set to your editor of choice. edit sample.rb edit -p MyClass#my_method edit sample.rb --line 105 edit MyClass edit MyClass#my_method edit --ex edit --method edit --ex -p https://github.com/pry/pry/wiki/Editor-integration#wiki-Edit_command BANNER def options(opt) opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)", :optional_argument => true, :as => Integer opt.on :i, :in, "Open a temporary file containing the Nth input expression. N may be a range", :optional_argument => true, :as => Range, :default => -1..-1 opt.on :t, :temp, "Open an empty temporary file" opt.on :l, :line, "Jump to this line in the opened file", :argument => true, :as => Integer opt.on :n, :"no-reload", "Don't automatically reload the edited code" opt.on :c, :current, "Open the current __FILE__ and at __LINE__ (as returned by `whereami`)" opt.on :r, :reload, "Reload the edited code immediately (default for ruby files)" opt.on :p, :patch, "Instead of editing the object's file, try to edit in a tempfile and apply as a monkey patch" opt.on :m, :method, "Explicitly edit the _current_ method (when inside a method context)." end def process if bad_option_combination? raise CommandError, "Only one of --ex, --temp, --in, --method and FILE may be specified." end if repl_edit? # code defined in pry, eval'd within pry. repl_edit elsif runtime_patch? # patch code without persisting changes apply_runtime_patch else # code stored in actual files, eval'd at top-level file_edit end end def repl_edit? !opts.present?(:ex) && !opts.present?(:current) && !opts.present?(:method) && filename_argument.empty? end def repl_edit content = Pry::Editor.edit_tempfile_with_content(initial_temp_file_content, initial_temp_file_content.lines.count) if repl_reload? silence_warnings do eval_string.replace content end end end def file_based_exception? opts.present?(:ex) && !opts.present?(:patch) end def runtime_patch? !file_based_exception? && (opts.present?(:patch) || pry_method?(code_object)) end def apply_runtime_patch if patch_exception? ExceptionPatcher.new(_pry_, state, file_and_line_for_current_exception).perform_patch else if code_object.is_a?(Pry::Method) MethodPatcher.new(_pry_, code_object).perform_patch else raise NotImplementedError, "Cannot yet patch #{code_object} objects!" end end end def ensure_file_name_is_valid(file_name) raise CommandError, "Cannot find a valid file for #{filename_argument}" if !file_name raise CommandError, "#{file_name} is not a valid file name, cannot edit!" if not_a_real_file?(file_name) end def file_and_line_for_current_exception FileAndLineLocator.from_exception(_pry_.last_exception, opts[:ex].to_i) end def file_and_line file_name, line = if opts.present?(:current) FileAndLineLocator.from_binding(target) elsif opts.present?(:ex) file_and_line_for_current_exception elsif code_object FileAndLineLocator.from_code_object(code_object, filename_argument) else # when file and line are passed as a single arg, e.g my_file.rb:30 FileAndLineLocator.from_filename_argument(filename_argument) end [file_name, opts.present?(:line) ? opts[:l].to_i : line] end def file_edit file_name, line = file_and_line ensure_file_name_is_valid(file_name) Pry::Editor.invoke_editor(file_name, line, reload?(file_name)) set_file_and_dir_locals(file_name) if reload?(file_name) silence_warnings do TOPLEVEL_BINDING.eval(File.read(file_name), file_name) end end end def filename_argument args.join(' ') end def code_object @code_object ||= !probably_a_file?(filename_argument) && Pry::CodeObject.lookup(filename_argument, _pry_) end def pry_method?(code_object) code_object.is_a?(Pry::Method) && code_object.pry_method? end def patch_exception? opts.present?(:ex) && opts.present?(:patch) end def bad_option_combination? [opts.present?(:ex), opts.present?(:temp), opts.present?(:in), opts.present?(:method), !filename_argument.empty?].count(true) > 1 end def input_expression case opts[:i] when Range (_pry_.input_array[opts[:i]] || []).join when Fixnum _pry_.input_array[opts[:i]] || "" else raise Pry::CommandError, "Not a valid range: #{opts[:i]}" end end def reloadable? opts.present?(:reload) || opts.present?(:ex) end def never_reload? opts.present?(:'no-reload') || Pry.config.disable_auto_reload end # conditions much less strict than for reload? (which is for file-based reloads) def repl_reload? !never_reload? end def reload?(file_name="") (reloadable? || file_name.end_with?(".rb")) && !never_reload? end def initial_temp_file_content case when opts.present?(:temp) "" when opts.present?(:in) input_expression when eval_string.strip != "" eval_string else _pry_.input_array.reverse_each.find { |x| x && x.strip != "" } || "" end end def probably_a_file?(str) [".rb", ".c", ".py", ".yml", ".gemspec"].include? File.extname(str) || str =~ /\/|\\/ end def complete(search) super + Bond::Rc.files(search.split(" ").last || '') end end Pry::Commands.add_command(Pry::Command::Edit) end pry-0.9.12.6/lib/pry/commands/cat/0000755000004100000410000000000012272154172016544 5ustar www-datawww-datapry-0.9.12.6/lib/pry/commands/cat/input_expression_formatter.rb0000644000004100000410000000221112272154172024566 0ustar www-datawww-dataclass Pry class Command::Cat class InputExpressionFormatter < AbstractFormatter attr_accessor :input_expressions attr_accessor :opts def initialize(input_expressions, opts) @input_expressions = input_expressions @opts = opts end def format raise CommandError, "No input expressions!" if numbered_input_items.length < 1 if numbered_input_items.length > 1 content = "" numbered_input_items.each do |i, s| content << "#{Helpers::Text.bold(i.to_s)}:\n" << decorate(Pry::Code(s).with_indentation(2)).to_s end content else decorate(Pry::Code(selected_input_items.first)).to_s end end private def selected_input_items input_expressions[normalized_expression_range] || [] end def numbered_input_items @numbered_input_items ||= normalized_expression_range.zip(selected_input_items). reject { |_, s| s.nil? || s == "" } end def normalized_expression_range absolute_index_range(opts[:i], input_expressions.length) end end end end pry-0.9.12.6/lib/pry/commands/cat/exception_formatter.rb0000644000004100000410000000421512272154172023154 0ustar www-datawww-dataclass Pry class Command::Cat class ExceptionFormatter < AbstractFormatter attr_accessor :ex attr_accessor :opts attr_accessor :_pry_ def initialize(exception, _pry_, opts) @ex = exception @opts = opts @_pry_ = _pry_ end def format check_for_errors set_file_and_dir_locals(backtrace_file, _pry_, _pry_.current_context) code = decorate(Pry::Code.from_file(backtrace_file). between(*start_and_end_line_for_code_window). with_marker(backtrace_line)).to_s "#{header}#{code}" end private def code_window_size Pry.config.default_window_size || 5 end def backtrace_level return @backtrace_level if @backtrace_level bl = if opts[:ex].nil? ex.bt_index else ex.bt_index = absolute_index_number(opts[:ex], ex.backtrace.size) end increment_backtrace_level @backtrace_level = bl end def increment_backtrace_level ex.inc_bt_index end def backtrace_file file = Array(ex.bt_source_location_for(backtrace_level)).first (file && RbxPath.is_core_path?(file)) ? RbxPath.convert_path_to_full(file) : file end def backtrace_line Array(ex.bt_source_location_for(backtrace_level)).last end def check_for_errors raise CommandError, "No exception found." unless ex raise CommandError, "The given backtrace level is out of bounds." unless backtrace_file end def start_and_end_line_for_code_window start_line = backtrace_line - code_window_size start_line = 1 if start_line < 1 [start_line, backtrace_line + code_window_size] end def header unindent %{ #{Helpers::Text.bold 'Exception:'} #{ex.class}: #{ex.message} -- #{Helpers::Text.bold('From:')} #{backtrace_file} @ line #{backtrace_line} @ #{Helpers::Text.bold("level: #{backtrace_level}")} of backtrace (of #{ex.backtrace.size - 1}). } end end end end pry-0.9.12.6/lib/pry/commands/cat/file_formatter.rb0000644000004100000410000000361712272154172022102 0ustar www-datawww-dataclass Pry class Command::Cat class FileFormatter < AbstractFormatter attr_accessor :file_with_embedded_line attr_accessor :opts attr_accessor :_pry_ def initialize(file_with_embedded_line, _pry_, opts) @file_with_embedded_line = file_with_embedded_line @opts = opts @_pry_ = _pry_ end def format raise CommandError, "Must provide a filename, --in, or --ex." if !file_with_embedded_line set_file_and_dir_locals(file_name, _pry_, _pry_.current_context) decorate(Pry::Code.from_file(file_name)) end private def file_and_line file_name, line_num = file_with_embedded_line.split(':') [File.expand_path(file_name), line_num ? line_num.to_i : nil] end def file_name file_and_line.first end def line_number file_and_line.last end def code_window_size Pry.config.default_window_size || 7 end def decorate(content) line_number ? super.around(line_number, code_window_size) : super end def code_type opts[:type] || detect_code_type_from_file(file_name) end def detect_code_type_from_file(file_name) name, ext = File.basename(file_name).split('.', 2) if ext case ext when "py" :python when "rb", "gemspec", "rakefile", "ru", "pryrc", "irbrc" :ruby when "js" return :javascript when "yml", "prytheme" :yaml when "groovy" :groovy when "c" :c when "cpp" :cpp when "java" :java else :text end else case name when "Rakefile", "Gemfile" :ruby else :text end end end end end end pry-0.9.12.6/lib/pry/commands/cat/abstract_formatter.rb0000644000004100000410000000110412272154172022753 0ustar www-datawww-dataclass Pry class Command::Cat class AbstractFormatter include Pry::Helpers::CommandHelpers include Pry::Helpers::BaseHelpers private def decorate(content) content.code_type = code_type content.between(*between_lines). with_line_numbers(use_line_numbers?) end def code_type opts[:type] || :ruby end def use_line_numbers? opts.present?(:'line-numbers') || opts.present?(:ex) end def between_lines [opts[:start] || 1, opts[:end] || -1] end end end end pry-0.9.12.6/lib/pry/commands/show_info.rb0000644000004100000410000001537512272154172020330 0ustar www-datawww-dataclass Pry class Command::ShowInfo < Pry::ClassCommand extend Pry::Helpers::BaseHelpers command_options :shellwords => false command_options :requires_gem => "ruby18_source_location" if mri_18? def setup require 'ruby18_source_location' if mri_18? end def options(opt) opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count opt.on :l, "line-numbers", "Show line numbers" opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)" opt.on :a, :all, "Show all definitions and monkeypatches of the module/class" end def process code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) raise CommandError, no_definition_message if !code_object @original_code_object = code_object if show_all_modules?(code_object) # show all monkey patches for a module result = content_and_headers_for_all_module_candidates(code_object) else # show a specific code object co = code_object_with_accessible_source(code_object) result = content_and_header_for_code_object(co) end set_file_and_dir_locals(code_object.source_file) stagger_output result end # This method checks whether the `code_object` is a WrappedModule, # if it is, then it returns the first candidate (monkeypatch) with # accessible source (or docs). If `code_object` is not a WrappedModule (i.e a # method or a command) then the `code_object` itself is just # returned. # # @return [Pry::WrappedModule, Pry::Method, Pry::Command] def code_object_with_accessible_source(code_object) if code_object.is_a?(WrappedModule) candidate = code_object.candidates.find(&:source) if candidate return candidate else raise CommandError, no_definition_message if !valid_superclass?(code_object) @used_super = true code_object_with_accessible_source(code_object.super) end else code_object end end def valid_superclass?(code_object) code_object.super && code_object.super.wrapped != Object end def content_and_header_for_code_object(code_object) header(code_object) + content_for(code_object) end def content_and_headers_for_all_module_candidates(mod) result = "Found #{mod.number_of_candidates} candidates for `#{mod.name}` definition:\n" mod.number_of_candidates.times do |v| candidate = mod.candidate(v) begin result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n" content = content_for(candidate) result << "Number of lines: #{content.lines.count}\n\n" << content rescue Pry::RescuableException result << "\nNo content found.\n" next end end result end def no_definition_message "Couldn't locate a definition for #{obj_name}!" end # Generate a header (meta-data information) for all the code # object types: methods, modules, commands, procs... def header(code_object) file_name, line_num = file_and_line_for(code_object) h = "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} " h << code_object_header(code_object, line_num) h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} " << "#{content_for(code_object).lines.count}\n\n" h << Helpers::Text.bold('** Warning:') + " Cannot find code for #{@original_code_object.nonblank_name}. Showing superclass #{code_object.nonblank_name} instead. **\n\n" if @used_super h end def code_object_header(code_object, line_num) if code_object.real_method_object? method_header(code_object, line_num) # It sucks we have to test for both Pry::WrappedModule and WrappedModule::Candidate, # probably indicates a deep refactor needs to happen in those classes. elsif code_object.is_a?(Pry::WrappedModule) || code_object.is_a?(Pry::WrappedModule::Candidate) module_header(code_object, line_num) else "" end end def method_header(code_object, line_num) h = "" h << (code_object.c_method? ? "(C Method):" : "@ line #{line_num}:") h << method_sections(code_object)[:owner] h << method_sections(code_object)[:visibility] h << method_sections(code_object)[:signature] h end def module_header(code_object, line_num) h = "" h << "@ line #{line_num}:\n" h << text.bold(code_object.module? ? "Module" : "Class") h << " #{text.bold('name:')} #{code_object.nonblank_name}" if code_object.number_of_candidates > 1 h << (text.bold("\nNumber of monkeypatches: ") + code_object.number_of_candidates.to_s) h << ". Use the `-a` option to display all available monkeypatches" end h end def method_sections(code_object) { :owner => "\n#{text.bold("Owner:")} #{code_object.owner || "N/A"}\n", :visibility => "#{text.bold("Visibility:")} #{code_object.visibility}", :signature => "\n#{text.bold("Signature:")} #{code_object.signature}" }.merge(header_options) { |key, old, new| (new && old).to_s } end def header_options { :owner => true, :visibility => true, :signature => nil } end def show_all_modules?(code_object) code_object.is_a?(Pry::WrappedModule) && opts.present?(:all) end def obj_name @obj_name ||= args.empty? ? nil : args.join(" ") end def use_line_numbers? opts.present?(:b) || opts.present?(:l) end def start_line_for(code_object) if opts.present?(:'base-one') 1 else code_object.source_line || 1 end end # takes into account possible yard docs, and returns yard_file / yard_line # Also adjusts for start line of comments (using start_line_for), which it has to infer # by subtracting number of lines of comment from start line of code_object def file_and_line_for(code_object) if code_object.module_with_yard_docs? [code_object.yard_file, code_object.yard_line] else [code_object.source_file, start_line_for(code_object)] end end def complete(input) if input =~ /([^ ]*)#([a-z0-9_]*)\z/ prefix, search = [$1, $2] methods = begin Pry::Method.all_from_class(binding.eval(prefix)) rescue RescuableException => e return super end methods.map do |method| [prefix, method.name].join('#') if method.name.start_with?(search) end.compact else super end end end end pry-0.9.12.6/lib/pry/commands/cat.rb0000644000004100000410000000422312272154172017072 0ustar www-datawww-dataclass Pry class Command::Cat < Pry::ClassCommand require 'pry/commands/cat/abstract_formatter.rb' require 'pry/commands/cat/input_expression_formatter.rb' require 'pry/commands/cat/exception_formatter.rb' require 'pry/commands/cat/file_formatter.rb' match 'cat' group 'Input and Output' description "Show code from a file, Pry's input buffer, or the last exception." banner <<-'BANNER' Usage: cat FILE cat --ex [STACK_INDEX] cat --in [INPUT_INDEX_OR_RANGE] `cat` is capable of showing part or all of a source file, the context of the last exception, or an expression from Pry's input history. `cat --ex` defaults to showing the lines surrounding the location of the last exception. Invoking it more than once travels up the exception's backtrace, and providing a number shows the context of the given index of the backtrace. BANNER def options(opt) opt.on :ex, "Show the context of the last exception", :optional_argument => true, :as => Integer opt.on :i, :in, "Show one or more entries from Pry's expression history", :optional_argument => true, :as => Range, :default => -5..-1 opt.on :s, :start, "Starting line (defaults to the first line)", :optional_argument => true, :as => Integer opt.on :e, :end, "Ending line (defaults to the last line)", :optional_argument => true, :as => Integer opt.on :l, :'line-numbers', "Show line numbers" opt.on :t, :type, "The file type for syntax highlighting (e.g., 'ruby' or 'python')", :argument => true, :as => Symbol end def process output = case when opts.present?(:ex) ExceptionFormatter.new(_pry_.last_exception, _pry_, opts).format when opts.present?(:in) InputExpressionFormatter.new(_pry_.input_array, opts).format else FileFormatter.new(args.first, _pry_, opts).format end stagger_output(output) end def complete(search) super + Bond::Rc.files(search.split(" ").last || '') end end Pry::Commands.add_command(Pry::Command::Cat) end pry-0.9.12.6/lib/pry/commands/disable_pry.rb0000644000004100000410000000153512272154172020623 0ustar www-datawww-dataclass Pry class Command::DisablePry < Pry::ClassCommand match 'disable-pry' group 'Navigating Pry' description 'Stops all future calls to pry and exits the current session.' banner <<-'BANNER' Usage: disable-pry After this command is run any further calls to pry will immediately return `nil` without interrupting the flow of your program. This is particularly useful when you've debugged the problem you were having, and now wish the program to run to the end. As alternatives, consider using `exit!` to force the current Ruby process to quit immediately; or using `edit-method -p` to remove the `binding.pry` from the code. BANNER def process ENV['DISABLE_PRY'] = 'true' _pry_.run_command "exit" end end Pry::Commands.add_command(Pry::Command::DisablePry) end pry-0.9.12.6/lib/pry/commands/edit/0000755000004100000410000000000012272154172016722 5ustar www-datawww-datapry-0.9.12.6/lib/pry/commands/edit/file_and_line_locator.rb0000644000004100000410000000243212272154172023543 0ustar www-datawww-dataclass Pry class Command::Edit module FileAndLineLocator class << self def from_binding(target) [target.eval("__FILE__"), target.eval("__LINE__")] end def from_code_object(code_object, filename_argument) if File.exists?(code_object.source_file.to_s) [code_object.source_file, code_object.source_line] else raise CommandError, "Cannot find a file for #{filename_argument}!" end end def from_exception(exception, backtrace_level) raise CommandError, "No exception found." if exception.nil? file_name, line = exception.bt_source_location_for(backtrace_level) raise CommandError, "Exception has no associated file." if file_name.nil? raise CommandError, "Cannot edit exceptions raised in REPL." if Pry.eval_path == file_name file_name = RbxPath.convert_path_to_full(file_name) if RbxPath.is_core_path?(file_name) [file_name, line] end # when file and line are passed as a single arg, e.g my_file.rb:30 def from_filename_argument(filename_argument) f = File.expand_path(filename_argument) l = f.sub!(/:(\d+)$/, "") ? $1.to_i : 1 [f, l] end end end end end pry-0.9.12.6/lib/pry/commands/edit/method_patcher.rb0000644000004100000410000001040212272154172022232 0ustar www-datawww-dataclass Pry class Command::Edit class MethodPatcher attr_accessor :_pry_ attr_accessor :code_object def initialize(_pry_, code_object) @_pry_ = _pry_ @code_object = code_object end # perform the patch def perform_patch if code_object.alias? with_method_transaction do _pry_.evaluate_ruby patched_code end else _pry_.evaluate_ruby patched_code end end private def patched_code @patched_code ||= wrap(Pry::Editor.edit_tempfile_with_content(adjusted_lines)) end # The method code adjusted so that the first line is rewritten # so that def self.foo --> def foo def adjusted_lines lines = code_object.source.lines.to_a lines[0] = definition_line_for_owner(lines.first) lines end # Run some code ensuring that at the end target#meth_name will not have changed. # # When we're redefining aliased methods we will overwrite the method at the # unaliased name (so that super continues to work). By wrapping that code in a # transation we make that not happen, which means that alias_method_chains, etc. # continue to work. # # @param [String] meth_name The method name before aliasing # @param [Module] target The owner of the method def with_method_transaction temp_name = "__pry_#{code_object.original_name}__" co = code_object code_object.owner.class_eval do alias_method temp_name, co.original_name yield alias_method co.name, co.original_name alias_method co.original_name, temp_name end ensure co.send(:remove_method, temp_name) rescue nil end # Update the definition line so that it can be eval'd directly on the Method's # owner instead of from the original context. # # In particular this takes `def self.foo` and turns it into `def foo` so that we # don't end up creating the method on the singleton class of the singleton class # by accident. # # This is necessarily done by String manipulation because we can't find out what # syntax is needed for the argument list by ruby-level introspection. # # @param String The original definition line. e.g. def self.foo(bar, baz=1) # @return String The new definition line. e.g. def foo(bar, baz=1) def definition_line_for_owner(line) if line =~ /^def (?:.*?\.)?#{Regexp.escape(code_object.original_name)}(?=[\(\s;]|$)/ "def #{code_object.original_name}#{$'}" else raise CommandError, "Could not find original `def #{code_object.original_name}` line to patch." end end # Apply wrap_for_owner and wrap_for_nesting successively to `source` # @param [String] source # @return [String] The wrapped source. def wrap(source) wrap_for_nesting(wrap_for_owner(source)) end # Update the source code so that when it has the right owner when eval'd. # # This (combined with definition_line_for_owner) is backup for the case that # wrap_for_nesting fails, to ensure that the method will stil be defined in # the correct place. # # @param [String] source The source to wrap # @return [String] def wrap_for_owner(source) Pry.current[:pry_owner] = code_object.owner "Pry.current[:pry_owner].class_eval do\n#{source}\nend" end # Update the new source code to have the correct Module.nesting. # # This method uses syntactic analysis of the original source file to determine # the new nesting, so that we can tell the difference between: # # class A; def self.b; end; end # class << A; def b; end; end # # The resulting code should be evaluated in the TOPLEVEL_BINDING. # # @param [String] source The source to wrap. # @return [String] def wrap_for_nesting(source) nesting = Pry::Code.from_file(code_object.source_file).nesting_at(code_object.source_line) (nesting + [source] + nesting.map{ "end" } + [""]).join("\n") rescue Pry::Indent::UnparseableNestingError => e source end end end end pry-0.9.12.6/lib/pry/commands/edit/exception_patcher.rb0000644000004100000410000000121112272154172022746 0ustar www-datawww-dataclass Pry class Command::Edit class ExceptionPatcher attr_accessor :_pry_ attr_accessor :state attr_accessor :file_and_line def initialize(_pry_, state, exception_file_and_line) @_pry_ = _pry_ @state = state @file_and_line = exception_file_and_line end # perform the patch def perform_patch file_name, line = file_and_line lines = state.dynamical_ex_file || File.read(file_name) source = Pry::Editor.edit_tempfile_with_content(lines) _pry_.evaluate_ruby source state.dynamical_ex_file = source.split("\n") end end end end pry-0.9.12.6/lib/pry/commands/bang_pry.rb0000644000004100000410000000056612272154172020132 0ustar www-datawww-dataclass Pry class Command::BangPry < Pry::ClassCommand match '!pry' group 'Navigating Pry' description 'Start a Pry session on current self.' banner <<-'BANNER' Start a Pry session on current self. Also works mid multi-line expression. BANNER def process target.pry end end Pry::Commands.add_command(Pry::Command::BangPry) end pry-0.9.12.6/lib/pry/commands/easter_eggs.rb0000644000004100000410000000624512272154172020621 0ustar www-datawww-dataclass Pry Pry::Commands.instance_eval do command "nyan-cat", "", :requires_gem => ["nyancat"] do run ".nyancat" end command(/!s\/(.*?)\/(.*?)/, "") do |source, dest| eval_string.gsub!(/#{source}/) { dest } run "show-input" end command "get-naked", "" do text = %{ -- We dont have to take our clothes off to have a good time. We could dance & party all night And drink some cherry wine. -- Jermaine Stewart } output.puts text text end command "east-coker", "" do text = %{ -- Now the light falls Across the open field, leaving the deep lane Shuttered with branches, dark in the afternoon, Where you lean against a bank while a van passes, And the deep lane insists on the direction Into the village, in the electric heat Hypnotised. In a warm haze the sultry light Is absorbed, not refracted, by grey stone. The dahlias sleep in the empty silence. Wait for the early owl. -- T.S Eliot } output.puts text text end command "cohen-poem", "" do text = %{ -- When this American woman, whose thighs are bound in casual red cloth, comes thundering past my sitting place like a forest-burning Mongol tribe, the city is ravished and brittle buildings of a hundred years splash into the street; and my eyes are burnt for the embroidered Chinese girls, already old, and so small between the thin pines on these enormous landscapes, that if you turn your head they are lost for hours. -- Leonard Cohen } output.puts text text end command "pessoa-poem", "" do output.puts <<-TEXT -- I've gone to bed with every feeling, I've been the pimp of every emotion, All felt sensations have bought me drinks, I've traded glances with every motive for every act, I've held hands with every urge to depart, .. Rage, foam, the vastness that doesn't fit in my handkerchief, The dog in heat howling in the night, The pond from the farm going in circles around my insomnia, The woods as they were, on our late-afternoon walks, the rose, The indifferent tuft of hair, the moss, the pines, The rage of not containing all this, not retaining all this, O abstract hunger for things, impotent libido for moments, Intellectual orgy of feeling life! -- Fernando Pessoa TEXT end command "test-ansi", "" do prev_color = Pry.color Pry.color = true picture = unindent <<-'EOS'.gsub(/[[:alpha:]!]/) { |s| text.red(s) } ____ _______________________ / \ | A W G | / O O \ | N I O N ! | | | | S S R I ! | \ \__/ / __| I K ! | \____/ \________________________| EOS if windows_ansi? move_up = proc { |n| "\e[#{n}F" } else move_up = proc { |n| "\e[#{n}A\e[0G" } end output.puts "\n" * 6 output.puts picture.lines.map(&:chomp).reverse.join(move_up[1]) output.puts "\n" * 6 output.puts "** ENV['TERM'] is #{ENV['TERM']} **\n\n" Pry.color = prev_color end end end pry-0.9.12.6/lib/pry/commands/pry_version.rb0000644000004100000410000000054012272154172020700 0ustar www-datawww-dataclass Pry class Command::Version < Pry::ClassCommand match 'pry-version' group 'Misc' description 'Show Pry version.' banner <<-'BANNER' Show Pry version. BANNER def process output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}." end end Pry::Commands.add_command(Pry::Command::Version) end pry-0.9.12.6/lib/pry/commands/bang.rb0000644000004100000410000000073112272154172017232 0ustar www-datawww-dataclass Pry class Command::Bang < Pry::ClassCommand match '!' group 'Editing' description 'Clear the input buffer.' command_options :use_prefix => false banner <<-'BANNER' Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop. BANNER def process output.puts 'Input buffer cleared!' eval_string.replace('') end end Pry::Commands.add_command(Pry::Command::Bang) end pry-0.9.12.6/lib/pry/commands/hist.rb0000644000004100000410000001200012272154172017262 0ustar www-datawww-dataclass Pry class Command::Hist < Pry::ClassCommand match 'hist' group 'Editing' description 'Show and replay Readline history.' banner <<-'BANNER' Usage: hist [--head|--tail] hist --head N hist --tail N hist --show START..END hist --grep PATTERN hist --clear hist --replay START..END hist --save [START..END] FILE Aliases: history Show and replay Readline history. BANNER def options(opt) opt.on :H, :head, "Display the first N items", :optional_argument => true, :as => Integer opt.on :T, :tail, "Display the last N items", :optional_argument => true, :as => Integer opt.on :s, :show, "Show the given range of lines", :optional_argument => true, :as => Range opt.on :G, :grep, "Show lines matching the given pattern", :argument => true, :as => String opt.on :c, :clear , "Clear the current session's history" opt.on :r, :replay, "Replay a line or range of lines", :argument => true, :as => Range opt.on :save, "Save history to a file", :argument => true, :as => Range opt.on :e, :'exclude-pry', "Exclude Pry commands from the history" opt.on :n, :'no-numbers', "Omit line numbers" opt.on :f, :flood, "Do not use a pager to view text longer than one screen" end def process @history = Pry::Code(Pry.history.to_a) if opts.present?(:show) @history = @history.between(opts[:show]) end if opts.present?(:grep) @history = @history.grep(opts[:grep]) end @history = case when opts.present?(:head) @history.take_lines(1, opts[:head] || 10) when opts.present?(:tail) @history.take_lines(-(opts[:tail] || 10), opts[:tail] || 10) when opts.present?(:show) @history.between(opts[:show]) else @history end if opts.present?(:'exclude-pry') @history = @history.select { |l, ln| !command_set.valid_command?(l) } end if opts.present?(:save) process_save elsif opts.present?(:clear) process_clear elsif opts.present?(:replay) process_replay else process_display end end private def process_display unless opts.present?(:'no-numbers') @history = @history.with_line_numbers end render_output(@history, opts) end def process_save case opts[:save] when Range @history = @history.between(opts[:save]) unless args.first raise CommandError, "Must provide a file name." end file_name = File.expand_path(args.first) when String file_name = File.expand_path(opts[:save]) end output.puts "Saving history in #{file_name}..." File.open(file_name, 'w') { |f| f.write(@history.raw) } output.puts "History saved." end def process_clear Pry.history.clear output.puts "History cleared." end def process_replay @history = @history.between(opts[:r]) replay_sequence = @history.raw # If we met follow-up "hist" call, check for the "--replay" option # presence. If "hist" command is called with other options, proceed # further. check_for_juxtaposed_replay(replay_sequence) _pry_.input_stack.push _pry_.input _pry_.input = StringIO.new(replay_sequence) # eval_string << "#{@history.raw}\n" # run "show-input" unless _pry_.complete_expression?(eval_string) end # Checks +replay_sequence+ for the presence of neighboring replay calls. # @example # [1] pry(main)> hist --show 46894 # 46894: hist --replay 46675..46677 # [2] pry(main)> hist --show 46675..46677 # 46675: 1+1 # 46676: a = 100 # 46677: hist --tail # [3] pry(main)> hist --replay 46894 # Error: Replay index 46894 points out to another replay call: `hist -r 46675..46677` # [4] pry(main)> # # @raise [Pry::CommandError] If +replay_sequence+ contains another # "hist --replay" call # @param [String] replay_sequence The sequence of commands to be replayed # (per saltum) # @return [Boolean] `false` if +replay_sequence+ does not contain another # "hist --replay" call def check_for_juxtaposed_replay(replay_sequence) if replay_sequence =~ /\Ahist(?:ory)?\b/ # Create *fresh* instance of Options for parsing of "hist" command. _slop = self.slop _slop.parse replay_sequence.split(' ')[1..-1] if _slop.present?(:r) replay_sequence = replay_sequence.split("\n").join('; ') index = opts[:r] index = index.min if index.min == index.max || index.max.nil? raise CommandError, "Replay index #{ index } points out to another replay call: `#{ replay_sequence }`" end else false end end end Pry::Commands.add_command(Pry::Command::Hist) Pry::Commands.alias_command 'history', 'hist' end pry-0.9.12.6/lib/pry/commands/toggle_color.rb0000644000004100000410000000065712272154172021011 0ustar www-datawww-dataclass Pry class Command::ToggleColor < Pry::ClassCommand match 'toggle-color' group 'Misc' description 'Toggle syntax highlighting.' banner <<-'BANNER' Usage: toggle-color Toggle syntax highlighting. BANNER def process Pry.color = !Pry.color output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}" end end Pry::Commands.add_command(Pry::Command::ToggleColor) end pry-0.9.12.6/lib/pry/commands/exit_all.rb0000644000004100000410000000130212272154172020117 0ustar www-datawww-dataclass Pry class Command::ExitAll < Pry::ClassCommand match 'exit-all' group 'Navigating Pry' description 'End the current Pry session.' banner <<-'BANNER' Usage: exit-all [--help] Aliases: !!@ End the current Pry session (popping all bindings and returning to caller). Accepts optional return value. BANNER def process # calculate user-given value exit_value = target.eval(arg_string) # clear the binding stack _pry_.binding_stack.clear # break out of the repl loop throw(:breakout, exit_value) end end Pry::Commands.add_command(Pry::Command::ExitAll) Pry::Commands.alias_command '!!@', 'exit-all' end pry-0.9.12.6/lib/pry/commands/gem_list.rb0000644000004100000410000000161712272154172020132 0ustar www-datawww-dataclass Pry class Command::GemList < Pry::ClassCommand match 'gem-list' group 'Gems' description 'List and search installed gems.' banner <<-'BANNER' Usage: gem-list [REGEX] List all installed gems, when a regex is provided, limit the output to those that match the regex. BANNER def process(pattern = nil) pattern = Regexp.compile(pattern || '') gems = Rubygem.list(pattern).group_by(&:name) gems.each do |gem, specs| specs.sort! do |a,b| Gem::Version.new(b.version) <=> Gem::Version.new(a.version) end versions = specs.each_with_index.map do |spec, index| index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s) end output.puts "#{text.default gem} (#{versions.join ', '})" end end end Pry::Commands.add_command(Pry::Command::GemList) end pry-0.9.12.6/lib/pry/commands/shell_mode.rb0000644000004100000410000000150512272154172020436 0ustar www-datawww-dataclass Pry class Command::ShellMode < Pry::ClassCommand match 'shell-mode' group 'Input and Output' description 'Toggle shell mode. Bring in pwd prompt and file completion.' banner <<-'BANNER' Toggle shell mode. Bring in pwd prompt and file completion. BANNER def process case _pry_.prompt when Pry::SHELL_PROMPT _pry_.pop_prompt _pry_.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS else _pry_.push_prompt Pry::SHELL_PROMPT _pry_.custom_completions = Pry::FILE_COMPLETIONS Readline.completion_proc = Pry::InputCompleter.build_completion_proc target, _pry_.instance_eval(&Pry::FILE_COMPLETIONS) end end end Pry::Commands.add_command(Pry::Command::ShellMode) Pry::Commands.alias_command 'file-mode', 'shell-mode' end pry-0.9.12.6/lib/pry/commands/stat.rb0000644000004100000410000000213512272154172017276 0ustar www-datawww-dataclass Pry class Command::Stat < Pry::ClassCommand match 'stat' group 'Introspection' description 'View method information and set _file_ and _dir_ locals.' command_options :shellwords => false banner <<-'BANNER' Usage: stat [OPTIONS] [METH] Show method information for method METH and set _file_ and _dir_ locals. stat hello_method BANNER def options(opt) method_options(opt) end def process meth = method_object aliases = meth.aliases output.puts unindent <<-EOS Method Information: -- Name: #{meth.name} Alias#{ "es" if aliases.length > 1 }: #{ aliases.any? ? aliases.join(", ") : "None." } Owner: #{meth.owner ? meth.owner : "Unknown"} Visibility: #{meth.visibility} Type: #{meth.is_a?(::Method) ? "Bound" : "Unbound"} Arity: #{meth.arity} Method Signature: #{meth.signature} Source Location: #{meth.source_location ? meth.source_location.join(":") : "Not found."} EOS end end Pry::Commands.add_command(Pry::Command::Stat) end pry-0.9.12.6/lib/pry/commands/whereami.rb0000644000004100000410000001113112272154172020120 0ustar www-datawww-dataclass Pry class Command::Whereami < Pry::ClassCommand class << self attr_accessor :method_size_cutoff end @method_size_cutoff = 30 match 'whereami' description 'Show code surrounding the current context.' group 'Context' banner <<-'BANNER' Usage: whereami [-qn] [LINES] Describe the current location. If you use `binding.pry` inside a method then whereami will print out the source for that method. If a number is passed, then LINES lines before and after the current line will be shown instead of the method itself. The `-q` flag can be used to suppress error messages in the case that there's no code to show. This is used by pry in the default before_session hook to show you when you arrive at a `binding.pry`. The `-n` flag can be used to hide line numbers so that code can be copy/pasted effectively. When pry was started on an Object and there is no associated method, whereami will instead output a brief description of the current object. BANNER def setup @file = expand_path(target.eval('__FILE__')) @line = target.eval('__LINE__') @method = Pry::Method.from_binding(target) end def options(opt) opt.on :q, :quiet, "Don't display anything in case of an error" opt.on :n, :"no-line-numbers", "Do not display line numbers" opt.on :m, :"method", "Show the complete source for the current method." opt.on :c, :"class", "Show the complete source for the current class or module." opt.on :f, :"file", "Show the complete source for the current file." end def code @code ||= if opts.present?(:m) method_code or raise CommandError, "Cannot find method code." elsif opts.present?(:c) class_code or raise CommandError, "Cannot find class code." elsif opts.present?(:f) Pry::Code.from_file(@file) elsif args.any? code_window else default_code end end def code? !!code rescue MethodSource::SourceNotFoundError false end def bad_option_combination? [opts.present?(:m), opts.present?(:f), opts.present?(:c), args.any?].count(true) > 1 end def location "#{@file} @ line #{@line} #{@method && @method.name_with_owner}" end def process if bad_option_combination? raise CommandError, "Only one of -m, -c, -f, and LINES may be specified." end if nothing_to_do? return elsif internal_binding?(target) handle_internal_binding return end set_file_and_dir_locals(@file) out = "\n#{text.bold('From:')} #{location}:\n\n" + code.with_line_numbers(use_line_numbers?).with_marker(marker).to_s + "\n" stagger_output(out) end private def nothing_to_do? opts.quiet? && (internal_binding?(target) || !code?) end def use_line_numbers? !opts.present?(:n) end def marker !opts.present?(:n) && @line end def top_level? target_self == TOPLEVEL_BINDING.eval("self") end def handle_internal_binding if top_level? output.puts "At the top level." else output.puts "Inside #{Pry.view_clip(target_self)}." end end def small_method? @method.source_range.count < self.class.method_size_cutoff end def default_code if method_code && small_method? method_code else code_window end end def code_window Pry::Code.from_file(@file).around(@line, window_size) end def method_code return @method_code if @method_code if valid_method? @method_code = Pry::Code.from_method(@method) end end def class_code return @class_code if @class_code if valid_method? mod = Pry::WrappedModule(@method.owner) idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file } @class_code = idx && Pry::Code.from_module(mod, idx) end end def valid_method? @method && @method.source? && expand_path(@method.source_file) == @file && @method.source_range.include?(@line) end def expand_path(f) return if !f if Pry.eval_path == f f else File.expand_path(f) end end def window_size if args.empty? Pry.config.default_window_size else args.first.to_i end end end Pry::Commands.add_command(Pry::Command::Whereami) end pry-0.9.12.6/lib/pry/commands/ls.rb0000644000004100000410000003247712272154172016755 0ustar www-datawww-dataclass Pry class Command::Ls < Pry::ClassCommand match 'ls' group 'Context' description 'Show the list of vars and methods in the current scope.' command_options :shellwords => false, :interpolate => false def options(opt) opt.banner unindent <<-'BANNER' Usage: ls [-m|-M|-p|-pM] [-q|-v] [-c|-i] [Object] ls [-g] [-l] ls shows you which methods, constants and variables are accessible to Pry. By default it shows you the local variables defined in the current shell, and any public methods or instance variables defined on the current object. The colours used are configurable using Pry.config.ls.*_color, and the separator is Pry.config.ls.separator. Pry.config.ls.ceiling is used to hide methods defined higher up in the inheritance chain, this is by default set to [Object, Module, Class] so that methods defined on all Objects are omitted. The -v flag can be used to ignore this setting and show all methods, while the -q can be used to set the ceiling much lower and show only methods defined on the object or its direct class. BANNER opt.on :m, :methods, "Show public methods defined on the Object (default)" opt.on :M, "instance-methods", "Show methods defined in a Module or Class" opt.on :p, :ppp, "Show public, protected (in yellow) and private (in green) methods" opt.on :q, :quiet, "Show only methods defined on object.singleton_class and object.class" opt.on :v, :verbose, "Show methods and constants on all super-classes (ignores Pry.config.ls.ceiling)" opt.on :g, :globals, "Show global variables, including those builtin to Ruby (in cyan)" opt.on :l, :locals, "Show hash of local vars, sorted by descending size" opt.on :c, :constants, "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" + " " * 32 + "Constants that are pending autoload? are also shown (in yellow)" opt.on :i, :ivars, "Show instance variables (in blue) and class variables (in bright blue)" opt.on :G, :grep, "Filter output by regular expression", :argument => true if jruby? opt.on :J, "all-java", "Show all the aliases for methods from java (default is to show only prettiest)" end end attr_reader :object_to_interrogate, :has_user_specified_any_options, :grep, :grep_regex def process @object_to_interrogate = args.empty? ? target_self : target.eval(args.join(" ")) # exclude -q, -v and --grep because they don't specify what the user wants to see. @has_user_specified_any_options = (opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) || opts.present?(:globals) || opts.present?(:locals) || opts.present?(:constants) || opts.present?(:ivars)) @grep_regex, @grep = [Regexp.new(opts[:G] || "."), lambda{ |x| x.grep(@grep_regex) }] raise_errors_if_arguments_are_weird all_output = [ write_out_globals, write_out_constants, write_out_methods, write_out_self_methods, write_out_ivars, write_out_local_names, write_out_locals, ].compact.join("") stagger_output(all_output) end private # http://ruby.runpaint.org/globals, and running "puts global_variables.inspect". BUILTIN_GLOBALS = %w($" $$ $* $, $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w $. $/ $\\ $: $; $< $= $> $0 $ARGV $CONSOLE $DEBUG $DEFAULT_INPUT $DEFAULT_OUTPUT $FIELD_SEPARATOR $FILENAME $FS $IGNORECASE $INPUT_LINE_NUMBER $INPUT_RECORD_SEPARATOR $KCODE $LOADED_FEATURES $LOAD_PATH $NR $OFS $ORS $OUTPUT_FIELD_SEPARATOR $OUTPUT_RECORD_SEPARATOR $PID $PROCESS_ID $PROGRAM_NAME $RS $VERBOSE $deferr $defout $stderr $stdin $stdout) # $SAFE and $? are thread-local, the exception stuff only works in a rescue clause, # everything else is basically a local variable with a $ in its name. PSEUDO_GLOBALS = %w($! $' $& $` $@ $? $+ $_ $~ $1 $2 $3 $4 $5 $6 $7 $8 $9 $CHILD_STATUS $SAFE $ERROR_INFO $ERROR_POSITION $LAST_MATCH_INFO $LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH) # Get all the methods that we'll want to output def all_methods(obj, instance_methods=false) methods = if instance_methods || opts.present?(:'instance-methods') Pry::Method.all_from_class(obj) else Pry::Method.all_from_obj(obj) end if jruby? && !opts.present?(:J) methods = trim_jruby_aliases(methods) end methods.select{ |method| opts.present?(:ppp) || method.visibility == :public } end # JRuby creates lots of aliases for methods imported from java in an attempt to # make life easier for ruby programmers. # (e.g. getFooBar becomes get_foo_bar and foo_bar, and maybe foo_bar? if it # returns a Boolean). # The full transformations are in the assignAliases method of: # https://github.com/jruby/jruby/blob/master/src/org/jruby/javasupport/JavaClass.java # # This has the unfortunate side-effect of making the output of ls even more # incredibly verbose than it normally would be for these objects; and so we filter # out all but the nicest of these aliases here. # # TODO: This is a little bit vague, better heuristics could be used. # JRuby also has a lot of scala-specific logic, which we don't copy. # def trim_jruby_aliases(methods) grouped = methods.group_by do |m| m.name.sub(/\A(is|get|set)(?=[A-Z_])/, '').gsub(/[_?=]/, '').downcase end grouped.map do |key, values| values = values.sort_by do |m| rubbishness(m.name) end found = [] values.select do |x| (!found.any?{ |y| x == y }) && found << x end end.flatten(1) end # When removing jruby aliases, we want to keep the alias that is "least rubbish" # according to this metric. def rubbishness(name) name.each_char.map{ |x| case x when /[A-Z]/ 1 when '?', '=', '!' -2 else 0 end }.inject(&:+) + (name.size / 100.0) end def resolution_order(obj) opts.present?(:'instance-methods') ? Pry::Method.instance_resolution_order(obj) : Pry::Method.resolution_order(obj) end # Get a lambda that can be used with .take_while to prevent over-eager # traversal of the Object's ancestry graph. def below_ceiling(obj) ceiling = if opts.present?(:quiet) [opts.present?(:'instance-methods') ? obj.ancestors[1] : obj.class.ancestors[1]] + Pry.config.ls.ceiling elsif opts.present?(:verbose) [] else Pry.config.ls.ceiling.dup end lambda { |klass| !ceiling.include?(klass) } end def raise_errors_if_arguments_are_weird [ ["-l does not make sense with a specified Object", :locals, !args.empty?], ["-g does not make sense with a specified Object", :globals, !args.empty?], ["-q does not make sense with -v", :quiet, opts.present?(:verbose)], ["-M only makes sense with a Module or a Class", :'instance-methods', !interrogating_a_module?], ["-c only makes sense with a Module or a Class", :constants, !args.empty? && !interrogating_a_module?], ].each do |message, option, expression| raise Pry::CommandError, message if opts.present?(option) && expression end end def interrogating_a_module? (Module === object_to_interrogate) end def write_out_globals return unless opts.present?(:globals) output_section("global variables", grep[format_globals(target.eval("global_variables"))]) end def write_out_constants return unless opts.present?(:constants) || (!has_user_specified_any_options && interrogating_a_module?) mod = interrogating_a_module? ? object_to_interrogate : Object constants = WrappedModule.new(mod).constants(opts.present?(:verbose)) output_section("constants", grep[format_constants(mod, constants)]) end def write_out_methods return unless opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) || !has_user_specified_any_options # methods is a hash {Module/Class => [Pry::Methods]} methods = all_methods(object_to_interrogate).group_by(&:owner) output = "" # reverse the resolution order so that the most useful information appears right by the prompt resolution_order(object_to_interrogate).take_while(&below_ceiling(object_to_interrogate)).reverse.each do |klass| methods_here = format_methods((methods[klass] || []).select{ |m| m.name =~ grep_regex }) output << output_section("#{Pry::WrappedModule.new(klass).method_prefix}methods", methods_here) end output end def write_out_self_methods return unless (!has_user_specified_any_options && interrogating_a_module?) methods = all_methods(object_to_interrogate, true).select{ |m| m.owner == object_to_interrogate && m.name =~ grep_regex } output_section("#{Pry::WrappedModule.new(object_to_interrogate).method_prefix}methods", format_methods(methods)) end def write_out_ivars return unless opts.present?(:ivars) || !has_user_specified_any_options klass = (interrogating_a_module? ? object_to_interrogate : object_to_interrogate.class) ivars = Pry::Method.safe_send(object_to_interrogate, :instance_variables) kvars = Pry::Method.safe_send(klass, :class_variables) output_section("instance variables", format_variables(:instance_var, ivars)) + output_section("class variables", format_variables(:class_var, kvars)) end def write_out_local_names return unless !has_user_specified_any_options && args.empty? output_section("locals", format_local_names(grep[target.eval("local_variables")])) end def write_out_locals return unless opts.present?(:locals) loc_names = target.eval('local_variables').reject do |e| _pry_.sticky_locals.keys.include? e.to_sym end name_value_pairs = loc_names.map do |name| [name, (target.eval name.to_s)] end format_locals(name_value_pairs).join("") end # Format and colourise a list of methods. def format_methods(methods) methods.sort_by(&:name).map do |method| if method.name == 'method_missing' color(:method_missing, 'method_missing') elsif method.visibility == :private color(:private_method, method.name) elsif method.visibility == :protected color(:protected_method, method.name) else color(:public_method, method.name) end end end def format_variables(type, vars) vars.sort_by(&:downcase).map{ |var| color(type, var) } end def format_constants(mod, constants) constants.sort_by(&:downcase).map do |name| if const = (!mod.autoload?(name) && (mod.const_get(name) || true) rescue nil) if (const < Exception rescue false) color(:exception_constant, name) elsif (Module === mod.const_get(name) rescue false) color(:class_constant, name) else color(:constant, name) end else color(:unloaded_constant, name) end end end def format_globals(globals) globals.sort_by(&:downcase).map do |name| if PSEUDO_GLOBALS.include?(name) color(:pseudo_global, name) elsif BUILTIN_GLOBALS.include?(name) color(:builtin_global, name) else color(:global_var, name) end end end def format_local_names(locals) locals.sort_by(&:downcase).map do |name| if _pry_.sticky_locals.include?(name.to_sym) color(:pry_var, name) else color(:local_var, name) end end end def format_locals(name_value_pairs) name_value_pairs.sort_by do |name, value| value.to_s.size end.reverse.map do |name, value| colorized_assignment_style(name, format_value(value)) end end def colorized_assignment_style(lhs, rhs, desired_width = 7) colorized_lhs = color(:local_var, lhs) color_escape_padding = colorized_lhs.size - lhs.size pad = desired_width + color_escape_padding "%-#{pad}s = %s" % [color(:local_var, colorized_lhs), rhs] end def format_value(value) accumulator = StringIO.new Pry.output_with_default_format(accumulator, value, :hashrocket => false) accumulator.string end # Add a new section to the output. Outputs nothing if the section would be empty. def output_section(heading, body) return "" if body.compact.empty? fancy_heading = text.bold(color(:heading, heading)) Pry::Helpers.tablify_or_one_line(fancy_heading, body) end # Color output based on config.ls.*_color def color(type, str) text.send(Pry.config.ls.send(:"#{type}_color"), str) end end Pry::Commands.add_command(Pry::Command::Ls) end pry-0.9.12.6/lib/pry/commands/nesting.rb0000644000004100000410000000116412272154172017773 0ustar www-datawww-dataclass Pry class Command::Nesting < Pry::ClassCommand match 'nesting' group 'Navigating Pry' description 'Show nesting information.' banner <<-'BANNER' Show nesting information. BANNER def process output.puts 'Nesting status:' output.puts '--' _pry_.binding_stack.each_with_index do |obj, level| if level == 0 output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))} (Pry top level)" else output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))}" end end end end Pry::Commands.add_command(Pry::Command::Nesting) end pry-0.9.12.6/lib/pry/commands/show_input.rb0000644000004100000410000000071412272154172020523 0ustar www-datawww-dataclass Pry class Command::ShowInput < Pry::ClassCommand match 'show-input' group 'Editing' description 'Show the contents of the input buffer for the current multi-line expression.' banner <<-'BANNER' Show the contents of the input buffer for the current multi-line expression. BANNER def process output.puts Code.new(eval_string).with_line_numbers end end Pry::Commands.add_command(Pry::Command::ShowInput) end pry-0.9.12.6/lib/pry/commands/exit_program.rb0000644000004100000410000000114512272154172021023 0ustar www-datawww-dataclass Pry class Command::ExitProgram < Pry::ClassCommand match 'exit-program' group 'Navigating Pry' description 'End the current program.' banner <<-'BANNER' Usage: exit-program [--help] Aliases: quit-program !!! End the current program. BANNER def process Pry.save_history if Pry.config.history.should_save Kernel.exit target.eval(arg_string).to_i end end Pry::Commands.add_command(Pry::Command::ExitProgram) Pry::Commands.alias_command 'quit-program', 'exit-program' Pry::Commands.alias_command '!!!', 'exit-program' end pry-0.9.12.6/lib/pry/commands/save_file.rb0000644000004100000410000000266312272154172020266 0ustar www-datawww-datarequire 'pry/commands/code_collector' class Pry class Command::SaveFile < Pry::ClassCommand match 'save-file' group 'Input and Output' description 'Export to a file using content from the REPL.' banner <<-'BANNER' Usage: save-file [OPTIONS] --to [FILE] Export to a file using content from the REPL. save-file my_method --to hello.rb save-file -i 1..10 --to hello.rb --append save-file show-method --to my_command.rb save-file sample_file.rb --lines 2..10 --to output_file.rb BANNER def options(opt) CodeCollector.inject_options(opt) opt.on :to=, "Specify the output file path" opt.on :a, :append, "Append output to file" end def process @cc = CodeCollector.new(args, opts, _pry_) raise CommandError, "Found no code to save." if @cc.content.empty? if !file_name display_content else save_file end end def file_name opts[:to] || nil end def save_file File.open(file_name, mode) do |f| f.puts @cc.content end output.puts "#{file_name} successfully saved" end def display_content output.puts @cc.content output.puts "\n\n--\nPlease use `--to FILE` to export to a file." output.puts "No file saved!\n--" end def mode opts.present?(:append) ? "a" : "w" end end Pry::Commands.add_command(Pry::Command::SaveFile) end pry-0.9.12.6/lib/pry/commands/show_doc.rb0000644000004100000410000000460612272154172020135 0ustar www-datawww-datarequire 'pry/commands/show_info' class Pry class Command::ShowDoc < Command::ShowInfo include Pry::Helpers::DocumentationHelpers match 'show-doc' group 'Introspection' description 'Show the documentation for a method or class.' banner <<-BANNER Usage: show-doc [OPTIONS] [METH] Aliases: ? Show the documentation for a method or class. Tries instance methods first and then methods by default. show-doc hi_method # docs for hi_method show-doc Pry # for Pry class show-doc Pry -a # for all definitions of Pry class (all monkey patches) BANNER # The docs for code_object prepared for display. def content_for(code_object) Code.new(render_doc_markup_for(code_object), start_line_for(code_object), :text). with_line_numbers(use_line_numbers?).to_s end # process the markup (if necessary) and apply colors def render_doc_markup_for(code_object) docs = docs_for(code_object) if code_object.command? # command '--help' shouldn't use markup highlighting docs else process_comment_markup(docs) end end # Return docs for the code_object, adjusting for whether the code_object # has yard docs available, in which case it returns those. # (note we only have to check yard docs for modules since they can # have multiple docs, but methods can only be doc'd once so we # dont need to check them) def docs_for(code_object) if code_object.module_with_yard_docs? # yard docs code_object.yard_doc else # normal docs (i.e comments above method/module/command) code_object.doc end end # Which sections to include in the 'header', can toggle: :owner, # :signature and visibility. def header_options super.merge :signature => true end # figure out start line of docs by back-calculating based on # number of lines in the comment and the start line of the code_object # @return [Fixnum] start line of docs def start_line_for(code_object) if code_object.command? || opts.present?(:'base-one') 1 else code_object.source_line.nil? ? 1 : (code_object.source_line - code_object.doc.lines.count) end end end Pry::Commands.add_command(Pry::Command::ShowDoc) Pry::Commands.alias_command '?', 'show-doc' end pry-0.9.12.6/lib/pry/rbx_method.rb0000644000004100000410000000031512272154172016653 0ustar www-datawww-dataclass Pry module RbxMethod private def core_code MethodSource.source_helper(source_location) end def core_doc MethodSource.comment_helper(source_location) end end end pry-0.9.12.6/lib/pry/rubygem.rb0000644000004100000410000000413112272154172016172 0ustar www-datawww-datarequire 'rubygems' class Pry module Rubygem class << self def installed?(name) if Gem::Specification.respond_to?(:find_all_by_name) Gem::Specification.find_all_by_name(name).any? else Gem.source_index.find_name(name).first end end # Get the gem spec object for the given gem name. # # @param [String] name # @return [Gem::Specification] def spec(name) specs = if Gem::Specification.respond_to?(:each) Gem::Specification.find_all_by_name(name) else Gem.source_index.find_name(name) end spec = specs.sort_by{ |spec| Gem::Version.new(spec.version) }.first spec or raise CommandError, "Gem `#{name}` not found" end # List gems matching a pattern. # # @param [Regexp] pattern # @return [Array] def list(pattern = /.*/) if Gem::Specification.respond_to?(:each) Gem::Specification.select{|spec| spec.name =~ pattern } else Gem.source_index.gems.values.select{|spec| spec.name =~ pattern } end end # Completion function for gem-cd and gem-open. # # @param [String] so_far what the user's typed so far # @return [Array] completions def complete(so_far) if so_far =~ / ([^ ]*)\z/ self.list(%r{\A#{$2}}).map(&:name) else self.list.map(&:name) end end # Installs a gem with all its dependencies. # # @param [String] name # @return [void] def install(name) destination = File.writable?(Gem.dir) ? Gem.dir : Gem.user_dir installer = Gem::DependencyInstaller.new(:install_dir => destination) installer.install(name) rescue Errno::EACCES raise CommandError, "Insufficient permissions to install `#{ text.green(name) }`." rescue Gem::GemNotFoundException raise CommandError, "Gem `#{ text.green(name) }` not found." else Gem.refresh end end end end pry-0.9.12.6/lib/pry/command_set.rb0000644000004100000410000003455012272154172017021 0ustar www-datawww-dataclass Pry class NoCommandError < StandardError def initialize(match, owner) super "Command '#{match}' not found in command set #{owner}" end end # This class is used to create sets of commands. Commands can be imported from # different sets, aliased, removed, etc. class CommandSet include Enumerable include Pry::Helpers::BaseHelpers attr_reader :commands attr_reader :helper_module # @param [Array] imported_sets Sets which will be imported # automatically # @yield Optional block run to define commands def initialize(*imported_sets, &block) @commands = {} @helper_module = Module.new import(*imported_sets) instance_eval(&block) if block end # Defines a new Pry command. # @param [String, Regexp] match The start of invocations of this command. # @param [String] description A description of the command. # @param [Hash] options The optional configuration parameters. # @option options [Boolean] :keep_retval Whether or not to use return value # of the block for return of `command` or just to return `nil` # (the default). # @option options [Array] :requires_gem Whether the command has # any gem dependencies, if it does and dependencies not met then # command is disabled and a stub proc giving instructions to # install command is provided. # @option options [Boolean] :interpolate Whether string #{} based # interpolation is applied to the command arguments before # executing the command. Defaults to true. # @option options [String] :listing The listing name of the # command. That is the name by which the command is looked up by # help and by show-command. Necessary for commands with regex matches. # @option options [Boolean] :use_prefix Whether the command uses # `Pry.config.command_prefix` prefix (if one is defined). Defaults # to true. # @option options [Boolean] :shellwords Whether the command's arguments # should be split using Shellwords instead of just split on spaces. # Defaults to true. # @yield The action to perform. The parameters in the block # determines the parameters the command will receive. All # parameters passed into the block will be strings. Successive # command parameters are separated by whitespace at the Pry prompt. # @example # MyCommands = Pry::CommandSet.new do # command "greet", "Greet somebody" do |name| # puts "Good afternoon #{name.capitalize}!" # end # end # # # From pry: # # pry(main)> _pry_.commands = MyCommands # # pry(main)> greet john # # Good afternoon John! # # pry(main)> help greet # # Greet somebody # @example Regexp command # MyCommands = Pry::CommandSet.new do # command /number-(\d+)/, "number-N regex command", :listing => "number" do |num, name| # puts "hello #{name}, nice number: #{num}" # end # end # # # From pry: # # pry(main)> _pry_.commands = MyCommands # # pry(main)> number-10 john # # hello john, nice number: 10 # # pry(main)> help number # # number-N regex command def block_command(match, description="No description.", options={}, &block) description, options = ["No description.", description] if description.is_a?(Hash) options = Pry::Command.default_options(match).merge!(options) commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block) end alias_method :command, :block_command # Defines a new Pry command class. # # @param [String, Regexp] match The start of invocations of this command. # @param [String] description A description of the command. # @param [Hash] options The optional configuration parameters, see {#command} # @yield The class body's definition. # # @example # Pry::Commands.create_command "echo", "echo's the input", :shellwords => false do # def options(opt) # opt.banner "Usage: echo [-u | -d] " # opt.on :u, :upcase, "ensure the output is all upper-case" # opt.on :d, :downcase, "ensure the output is all lower-case" # end # # def process # raise Pry::CommandError, "-u and -d makes no sense" if opts.present?(:u) && opts.present?(:d) # result = args.join(" ") # result.downcase! if opts.present?(:downcase) # result.upcase! if opts.present?(:upcase) # output.puts result # end # end # def create_command(match, description="No description.", options={}, &block) description, options = ["No description.", description] if description.is_a?(Hash) options = Pry::Command.default_options(match).merge!(options) commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block) commands[match].class_eval(&block) commands[match] end # Execute a block of code before a command is invoked. The block also # gets access to parameters that will be passed to the command and # is evaluated in the same context. # @param [String, Regexp] search The match or listing of the command. # @yield The block to be run before the command. # @example Display parameter before invoking command # Pry.commands.before_command("whereami") do |n| # output.puts "parameter passed was #{n}" # end def before_command(search, &block) cmd = find_command_by_match_or_listing(search) cmd.hooks[:before].unshift block end # Execute a block of code after a command is invoked. The block also # gets access to parameters that will be passed to the command and # is evaluated in the same context. # @param [String, Regexp] search The match or listing of the command. # @yield The block to be run after the command. # @example Display text 'command complete' after invoking command # Pry.commands.after_command("whereami") do |n| # output.puts "command complete!" # end def after_command(search, &block) cmd = find_command_by_match_or_listing(search) cmd.hooks[:after] << block end def each(&block) @commands.each(&block) end # Add a given command object to this set. # @param [Command] command The subclass of Pry::Command you wish to add. def add_command(command) commands[command.match] = command end # Removes some commands from the set # @param [Array] searches the matches or listings of the commands to remove def delete(*searches) searches.each do |search| cmd = find_command_by_match_or_listing(search) commands.delete cmd.match end end # Imports all the commands from one or more sets. # @param [Array] sets Command sets, all of the commands of which # will be imported. # @return [Pry::CommandSet] Returns the reciever (a command set). def import(*sets) sets.each do |set| commands.merge! set.commands helper_module.send :include, set.helper_module end self end # Imports some commands from a set # @param [CommandSet] set Set to import commands from # @param [Array] matches Commands to import # @return [Pry::CommandSet] Returns the reciever (a command set). def import_from(set, *matches) helper_module.send :include, set.helper_module matches.each do |match| cmd = set.find_command_by_match_or_listing(match) commands[cmd.match] = cmd end self end # @param [String, Regexp] match_or_listing The match or listing of a command. # of the command to retrieve. # @return [Command] The command object matched. def find_command_by_match_or_listing(match_or_listing) cmd = (commands[match_or_listing] || Pry::Helpers::BaseHelpers.find_command(match_or_listing, commands)) cmd or raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!" end # Aliases a command # @param [String, Regex] match The match of the alias (can be a regex). # @param [String] action The action to be performed (typically # another command). # @param [Hash] options The optional configuration parameters, # accepts the same as the `command` method, but also allows the # command description to be passed this way too as `:desc` # @example Creating an alias for `ls -M` # Pry.config.commands.alias_command "lM", "ls -M" # @example Pass explicit description (overriding default). # Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie" def alias_command(match, action, options={}) cmd = find_command(action) or fail "Command: `#{action}` not found" original_options = cmd.options.dup options = original_options.merge!({ :desc => "Alias for `#{action}`", :listing => match }).merge!(options) # ensure default description is used if desc is nil desc = options.delete(:desc).to_s c = block_command match, desc, options do |*args| run action, *args end c.class_eval do define_method(:complete) do |input| cmd.new(context).complete(input) end end c.group "Aliases" c end # Rename a command. Accepts either match or listing for the search. # # @param [String, Regexp] new_match The new match for the command. # @param [String, Regexp] search The command's current match or listing. # @param [Hash] options The optional configuration parameters, # accepts the same as the `command` method, but also allows the # command description to be passed this way too. # @example Renaming the `ls` command and changing its description. # Pry.config.commands.rename "dir", "ls", :description => "DOS friendly ls" def rename_command(new_match, search, options={}) cmd = find_command_by_match_or_listing(search) options = { :listing => new_match, :description => cmd.description }.merge!(options) commands[new_match] = cmd.dup commands[new_match].match = new_match commands[new_match].description = options.delete(:description) commands[new_match].options.merge!(options) commands.delete(cmd.match) end def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command) create_command name_of_disabled_command do match matcher description "" define_method(:process) do output.puts "DISABLED: #{message}" end end end # Sets or gets the description for a command (replacing the old # description). Returns current description if no description # parameter provided. # @param [String, Regexp] search The command match. # @param [String?] description (nil) The command description. # @example Setting # MyCommands = Pry::CommandSet.new do # desc "help", "help description" # end # @example Getting # Pry.config.commands.desc "amend-line" def desc(search, description=nil) cmd = find_command_by_match_or_listing(search) return cmd.description if !description cmd.description = description end # Defines helpers methods for this command sets. # Those helpers are only defined in this command set. # # @yield A block defining helper methods # @example # helpers do # def hello # puts "Hello!" # end # # include OtherModule # end def helpers(&block) helper_module.class_eval(&block) end # @return [Array] The list of commands provided by the command set. def list_commands commands.keys end # Find a command that matches the given line # @param [String] val The line that might be a command invocation # @return [Pry::Command, nil] def find_command(val) commands.values.select{ |c| c.matches?(val) }.sort_by{ |c| c.match_score(val) }.last end alias_method :[], :find_command # Find the command that the user might be trying to refer to. # @param [String] search The user's search. # @return [Pry::Command?] def find_command_for_help(search) find_command(search) || (begin find_command_by_match_or_listing(search) rescue ArgumentError nil end) end # Is the given line a command invocation? # @param [String] val # @return [Boolean] def valid_command?(val) !!find_command(val) end # Process the given line to see whether it needs executing as a command. # @param [String] val The line to execute # @param [Hash] context The context to execute the commands with # @return [CommandSet::Result] def process_line(val, context={}) if command = find_command(val) context = context.merge(:command_set => self) retval = command.new(context).process_line(val) Result.new(true, retval) else Result.new(false) end end # @private (used for testing) def run_command(context, match, *args) command = commands[match] or raise NoCommandError.new(match, self) command.new(context).call_safely(*args) end # Generate completions for the user's search. # @param [String] search The line to search for # @param [Hash] context The context to create the command with # @return [Array] def complete(search, context={}) if command = find_command(search) command.new(context).complete(search) else commands.keys.select do |x| String === x && x.start_with?(search) end.map{ |command| command + " " } + Bond::DefaultMission.completions end end end # Wraps the return result of process_commands, indicates if the # result IS a command and what kind of command (e.g void) class Result attr_reader :retval def initialize(is_command, retval = nil) @is_command, @retval = is_command, retval end # Is the result a command? # @return [Boolean] def command? @is_command end # Is the result a command and if it is, is it a void command? # (one that does not return a value) # @return [Boolean] def void_command? retval == Command::VOID_VALUE end end end pry-0.9.12.6/lib/pry/module_candidate.rb0000644000004100000410000001301212272154172017777 0ustar www-datawww-datarequire 'pry/helpers/documentation_helpers' require 'forwardable' class Pry class WrappedModule # This class represents a single candidate for a module/class definition. # It provides access to the source, documentation, line and file # for a monkeypatch (reopening) of a class/module. class Candidate include Pry::Helpers::DocumentationHelpers include Pry::CodeObject::Helpers extend Forwardable # @return [String] The file where the module definition is located. attr_reader :file alias_method :source_file, :file # @return [Fixnum] The line where the module definition is located. attr_reader :line alias_method :source_line, :line # Methods to delegate to associated `Pry::WrappedModule # instance`. private_delegates = [:lines_for_file, :method_candidates, :yard_docs?] public_delegates = [:wrapped, :module?, :class?, :name, :nonblank_name, :number_of_candidates] def_delegators :@wrapper, *(private_delegates + public_delegates) private *private_delegates public *public_delegates # @raise [Pry::CommandError] If `rank` is out of bounds. # @param [Pry::WrappedModule] wrapper The associated # `Pry::WrappedModule` instance that owns the candidates. # @param [Fixnum] rank The rank of the candidate to # retrieve. Passing 0 returns 'primary candidate' (the candidate with largest # number of methods), passing 1 retrieves candidate with # second largest number of methods, and so on, up to # `Pry::WrappedModule#number_of_candidates() - 1` def initialize(wrapper, rank) @wrapper = wrapper if number_of_candidates <= 0 raise CommandError, "Cannot find a definition for #{name} module!" elsif rank > (number_of_candidates - 1) raise CommandError, "No such module candidate. Allowed candidates range is from 0 to #{number_of_candidates - 1}" end @rank = rank @file, @line = source_location end # @raise [Pry::CommandError] If source code cannot be found. # @return [String] The source for the candidate, i.e the # complete module/class definition. def source return nil if file.nil? return @source if @source @source = strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line, number_of_lines_in_first_chunk)) end # @raise [Pry::CommandError] If documentation cannot be found. # @return [String] The documentation for the candidate. def doc return nil if file.nil? return @doc if @doc @doc = get_comment_content(Pry::Code.from_file(file).comment_describing(line)) end # @return [Array, nil] A `[String, Fixnum]` pair representing the # source location (file and line) for the candidate or `nil` # if no source location found. def source_location return @source_location if @source_location file, line = first_method_source_location return nil if !file.is_a?(String) @source_location = [file, first_line_of_module_definition(file, line)] rescue Pry::RescuableException nil end private # Locate the first line of the module definition. # @param [String] file The file that contains the module # definition (somewhere). # @param [Fixnum] line The module definition should appear # before this line (if it exists). # @return [Fixnum] The line where the module is defined. This # line number is one-indexed. def first_line_of_module_definition(file, line) searchable_lines = lines_for_file(file)[0..(line - 2)] searchable_lines.rindex { |v| class_regexes.any? { |r| r =~ v } } + 1 end def class_regexes mod_type_string = wrapped.class.to_s.downcase [/^\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped.name.split(/::/).last}/, /^\s*(::)?#{wrapped.name.split(/::/).last}\s*?=\s*?#{wrapped.class}/, /^\s*(::)?#{wrapped.name.split(/::/).last}\.(class|instance)_eval/] end # This method is used by `Candidate#source_location` as a # starting point for the search for the candidate's definition. # @return [Array] The source location of the base method used to # calculate the source location of the candidate. def first_method_source_location @first_method_source_location ||= adjusted_source_location(method_candidates[@rank].first.source_location) end # @return [Array] The source location of the last method in this # candidate's module definition. def last_method_source_location @end_method_source_location ||= adjusted_source_location(method_candidates[@rank].last.source_location) end # Return the number of lines between the start of the class definition # and the start of the last method. We use this value so we can # quickly grab these lines from the file (without having to # check each intervening line for validity, which is expensive) speeding up source extraction. # @return [Fixum] Number of lines. def number_of_lines_in_first_chunk end_method_line = last_method_source_location.last end_method_line - line end def adjusted_source_location(sl) file, line = sl if file && RbxPath.is_core_path?(file) file = RbxPath.convert_path_to_full(file) end [file, line] end end end end pry-0.9.12.6/lib/pry/command.rb0000644000004100000410000005234012272154172016143 0ustar www-datawww-datarequire 'delegate' require 'pry/helpers/documentation_helpers' class Pry # The super-class of all commands, new commands should be created by calling # {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command} # which creates a ClassCommand. Please don't use this class directly. class Command extend Helpers::DocumentationHelpers extend CodeObject::Helpers # represents a void return value for a command VOID_VALUE = Object.new # give it a nice inspect def VOID_VALUE.inspect() "void" end # Properties of the command itself (as passed as arguments to # {CommandSet#command} or {CommandSet#create_command}). class << self attr_writer :block attr_writer :description attr_writer :command_options attr_writer :match def match(arg=nil) if arg @command_options ||= default_options(arg) @command_options[:listing] = arg.is_a?(String) ? arg : arg.inspect @match = arg end @match end # Define or get the command's description def description(arg=nil) @description = arg if arg @description end # Define or get the command's options def command_options(arg=nil) @command_options ||= default_options(match) @command_options.merge!(arg) if arg @command_options end # backward compatibility alias_method :options, :command_options alias_method :options=, :command_options= # Define or get the command's banner def banner(arg=nil) @banner = arg if arg @banner || description end def block @block || instance_method(:process) end def source file, line = block.source_location strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line)) end def doc new.help end def source_location block.source_location end def source_file Array(block.source_location).first end alias_method :file, :source_file def source_line Array(block.source_location).last end alias_method :line, :source_line def default_options(match) { :requires_gem => [], :keep_retval => false, :argument_required => false, :interpolate => true, :shellwords => true, :listing => (String === match ? match : match.inspect), :use_prefix => true, :takes_block => false } end end # Make those properties accessible to instances def name; self.class.name; end def match; self.class.match; end def description; self.class.description; end def block; self.class.block; end def command_options; self.class.options; end def command_name; self.class.command_name; end def source; self.class.source; end def source_location; self.class.source_location; end class << self def name super.to_s == "" ? "#" : super end def inspect name end def command_name self.options[:listing] end # Create a new command with the given properties. # @param [String, Regex] match The thing that triggers this command # @param [String] description The description to appear in `help` # @param [Hash] options Behavioral options (see {Pry::CommandSet#command}) # @param [Module] helpers A module of helper functions to be included. # @yield optional, used for BlockCommands # @return [Class] (a subclass of {Pry::Command}) def subclass(match, description, options, helpers, &block) klass = Class.new(self) klass.send(:include, helpers) klass.match = match klass.description = description klass.command_options = options klass.block = block klass end # Should this command be called for the given line? # @param [String] val A line input at the REPL # @return [Boolean] def matches?(val) command_regex =~ val end # How well does this command match the given line? # # Higher scores are better because they imply that this command matches # the line more closely. # # The score is calculated by taking the number of characters at the start # of the string that are used only to identify the command, not as part of # the arguments. # # @example # /\.(.*)/.match_score(".foo") #=> 1 # /\.*(.*)/.match_score("...foo") #=> 3 # 'hi'.match_score("hi there") #=> 2 # # @param [String] val A line input at the REPL # @return [Fixnum] def match_score(val) if command_regex =~ val Regexp.last_match.size > 1 ? Regexp.last_match.begin(1) : Regexp.last_match.end(0) else -1 end end # Store hooks to be run before or after the command body. # @see {Pry::CommandSet#before_command} # @see {Pry::CommandSet#after_command} def hooks @hooks ||= {:before => [], :after => []} end def command_regex pr = defined?(Pry.config.command_prefix) ? Pry.config.command_prefix : "" prefix = convert_to_regex(pr) prefix = "(?:#{prefix})?" unless options[:use_prefix] /^#{prefix}#{convert_to_regex(match)}(?!\S)/ end def convert_to_regex(obj) case obj when String Regexp.escape(obj) else obj end end # The group in which the command should be displayed in "help" output. # This is usually auto-generated from directory naming, but it can be # manually overridden if necessary. def group(name=nil) @group ||= if name name else case Pry::Method(block).source_file when %r{/pry/.*_commands/(.*).rb} $1.capitalize.gsub(/_/, " ") when %r{(pry-\w+)-([\d\.]+([\w\d\.]+)?)} name, version = $1, $2 "#{name.to_s} (v#{version.to_s})" when /pryrc/ "~/.pryrc" else "(other)" end end end end # Properties of one execution of a command (passed by {Pry#run_command} as a hash of # context and expanded in `#initialize` attr_accessor :output attr_accessor :target attr_accessor :captures attr_accessor :eval_string attr_accessor :arg_string attr_accessor :context attr_accessor :command_set attr_accessor :_pry_ # The block we pass *into* a command so long as `:takes_block` is # not equal to `false` # @example # my-command | do # puts "block content" # end attr_accessor :command_block # Run a command from another command. # @param [String] command_string The string that invokes the command # @param [Array] args Further arguments to pass to the command # @example # run "show-input" # @example # run ".ls" # @example # run "amend-line", "5", 'puts "hello world"' def run(command_string, *args) complete_string = "#{command_string} #{args.join(" ")}".rstrip command_set.process_line(complete_string, context) end def commands command_set.commands end def text Pry::Helpers::Text end def void VOID_VALUE end include Pry::Helpers::BaseHelpers include Pry::Helpers::CommandHelpers # Instantiate a command, in preparation for calling it. # @param [Hash] context The runtime context to use with this command. def initialize(context={}) self.context = context self.target = context[:target] self.output = context[:output] self.eval_string = context[:eval_string] self.command_set = context[:command_set] self._pry_ = context[:pry_instance] end # @return [Object] The value of `self` inside the `target` binding. def target_self; target.eval('self'); end # @return [Hash] Pry commands can store arbitrary state # here. This state persists between subsequent command invocations. # All state saved here is unique to the command, it does not # need to be namespaced. # @example # state.my_state = "my state" # this will not conflict with any # # `state.my_state` used in another command. def state _pry_.command_state[match] ||= OpenStruct.new end # Revaluate the string (str) and perform interpolation. # @param [String] str The string to reevaluate with interpolation. # # @return [String] The reevaluated string with interpolations # applied (if any). def interpolate_string(str) dumped_str = str.dump if dumped_str.gsub!(/\\\#\{/, '#{') target.eval(dumped_str) else str end end # Display a warning if a command collides with a local/method in # the current scope. def check_for_command_collision(command_match, arg_string) collision_type = target.eval("defined?(#{command_match})") collision_type ||= 'local-variable' if arg_string.match(%r{\A\s*[-+*/%&|^]*=}) if collision_type output.puts "#{text.bold('WARNING:')} Calling Pry command '#{command_match}'," + "which conflicts with a #{collision_type}.\n\n" end rescue Pry::RescuableException end # Extract necessary information from a line that Command.matches? this # command. # # Returns an array of four elements: # # ``` # [String] the portion of the line that matched with the Command match # [String] a string of all the arguments (i.e. everything but the match) # [Array] the captures caught by the command_regex # [Array] the arguments obtained by splitting the arg_string # ``` # # @param [String] val The line of input # @return [Array] def tokenize(val) val.replace(interpolate_string(val)) if command_options[:interpolate] self.class.command_regex =~ val # please call Command.matches? before Command#call_safely raise CommandError, "fatal: called a command which didn't match?!" unless Regexp.last_match captures = Regexp.last_match.captures pos = Regexp.last_match.end(0) arg_string = val[pos..-1] # remove the one leading space if it exists arg_string.slice!(0) if arg_string.start_with?(" ") # process and pass a block if one is found pass_block(arg_string) if command_options[:takes_block] if arg_string args = command_options[:shellwords] ? Shellwords.shellwords(arg_string) : arg_string.split(" ") else args = [] end [val[0..pos].rstrip, arg_string, captures, args] end # Process a line that Command.matches? this command. # @param [String] line The line to process # @return [Object, Command::VOID_VALUE] def process_line(line) command_match, arg_string, captures, args = tokenize(line) check_for_command_collision(command_match, arg_string) if Pry.config.collision_warning self.arg_string = arg_string self.captures = captures call_safely(*(captures + args)) end # Pass a block argument to a command. # @param [String] arg_string The arguments (as a string) passed to the command. # We inspect these for a '| do' or a '| {' and if we find it we use it # to start a block input sequence. Once we have a complete # block, we save it to an accessor that can be retrieved from the command context. # Note that if we find the '| do' or '| {' we delete this and the # elements following it from `arg_string`. def pass_block(arg_string) # Workaround for weird JRuby bug where rindex in this case can return nil # even when there's a match. arg_string.scan(/\| *(?:do|\{)/) block_index = $~ && $~.offset(0)[0] return if !block_index block_init_string = arg_string.slice!(block_index..-1)[1..-1] prime_string = "proc #{block_init_string}\n" if !Pry::Code.complete_expression?(prime_string) block_string = _pry_.r(target, prime_string) else block_string = prime_string end begin self.command_block = target.eval(block_string) rescue Pry::RescuableException raise CommandError, "Incomplete block definition." end end private :pass_block # Run the command with the given `args`. # # This is a public wrapper around `#call` which ensures all preconditions # are met. # # @param [Array] args The arguments to pass to this command. # @return [Object] The return value of the `#call` method, or # {Command::VOID_VALUE}. def call_safely(*args) unless dependencies_met? gems_needed = Array(command_options[:requires_gem]) gems_not_installed = gems_needed.select { |g| !Rubygem.installed?(g) } output.puts "\nThe command '#{command_name}' is #{text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}" output.puts "-" output.puts "Type `install-command #{command_name}` to install the required gems and activate this command." return void end if command_options[:argument_required] && args.empty? raise CommandError, "The command '#{command_name}' requires an argument." end ret = call_with_hooks(*args) command_options[:keep_retval] ? ret : void end # Are all the gems required to use this command installed? # # @return Boolean def dependencies_met? @dependencies_met ||= command_dependencies_met?(command_options) end # Generate completions for this command # # @param [String] search The line typed so far # @return [Array] Completion words def complete(search); Bond::DefaultMission.completions; end private # Run the `#call` method and all the registered hooks. # @param [Array] args The arguments to `#call` # @return [Object] The return value from `#call` def call_with_hooks(*args) self.class.hooks[:before].each do |block| instance_exec(*args, &block) end ret = call(*args) self.class.hooks[:after].each do |block| ret = instance_exec(*args, &block) end ret end # Fix the number of arguments we pass to a block to avoid arity warnings. # @param [Fixnum] arity The arity of the block # @param [Array] args The arguments to pass # @return [Array] A (possibly shorter) array of the arguments to pass def correct_arg_arity(arity, args) case when arity < 0 args when arity == 0 [] when arity > 0 args.values_at(*(0..(arity - 1)).to_a) end end end # A super-class for Commands that are created with a single block. # # This class ensures that the block is called with the correct number of arguments # and the right context. # # Create subclasses using {Pry::CommandSet#command}. class BlockCommand < Command # backwards compatibility alias_method :opts, :context # Call the block that was registered with this command. # @param [Array] args The arguments passed # @return [Object] The return value of the block def call(*args) instance_exec(*correct_arg_arity(block.arity, args), &block) end def help "#{command_options[:listing].to_s.ljust(18)} #{description}" end end # A super-class of Commands with structure. # # This class implements the bare-minimum functionality that a command should # have, namely a --help switch, and then delegates actual processing to its # subclasses. # # Create subclasses using {Pry::CommandSet#create_command}, and override the # `options(opt)` method to set up an instance of Slop, and the `process` # method to actually run the command. If necessary, you can also override # `setup` which will be called before `options`, for example to require any # gems your command needs to run, or to set up state. class ClassCommand < Command class << self # Ensure that subclasses inherit the options, description and # match from a ClassCommand super class. def inherited(klass) klass.match match klass.description description klass.command_options options end def source source_object.source end def doc new.help end def source_location source_object.source_location end def source_file source_object.source_file end alias_method :file, :source_file def source_line source_object.source_line end alias_method :line, :source_line private # The object used to extract the source for the command. # # This should be a `Pry::Method(block)` for a command made with `create_command` # and a `Pry::WrappedModule(self)` for a command that's a standard class. # @return [Pry::WrappedModule, Pry::Method] def source_object @source_object ||= if name =~ /^[A-Z]/ Pry::WrappedModule(self) else Pry::Method(block) end end end attr_accessor :opts attr_accessor :args # Set up `opts` and `args`, and then call `process`. # # This method will display help if necessary. # # @param [Array] args The arguments passed # @return [Object] The return value of `process` or VOID_VALUE def call(*args) setup self.opts = slop self.args = self.opts.parse!(args) if opts.present?(:help) output.puts slop.help void else process(*correct_arg_arity(method(:process).arity, args)) end end # Return the help generated by Slop for this command. def help slop.help end # Return an instance of Slop that can parse either subcommands or the # options that this command accepts. def slop Slop.new do |opt| opt.banner(unindent(self.class.banner)) subcommands(opt) options(opt) opt.on :h, :help, 'Show this message.' end end # Generate shell completions # @param [String] search The line typed so far # @return [Array] the words to complete def complete(search) slop.map do |opt| [opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"] end.flatten(1).compact + super end # A method called just before `options(opt)` as part of `call`. # # This method can be used to set up any context your command needs to run, # for example requiring gems, or setting default values for options. # # @example # def setup # require 'gist' # @action = :method # end def setup; end # A method to setup Slop commands so it can parse the subcommands your # command expects. If you need to set up default values, use `setup` # instead. # # @example A minimal example # def subcommands(cmd) # cmd.command :download do |opt| # description 'Downloads a content from a server' # # opt.on :verbose, 'Use verbose output' # # run do |options, arguments| # ContentDownloader.download(options, arguments) # end # end # end # # @example Define the invokation block anywhere you want # def subcommands(cmd) # cmd.command :download do |opt| # description 'Downloads a content from a server' # # opt.on :verbose, 'Use verbose output' # end # end # # def process # # Perform calculations... # opts.fetch_command(:download).run do |options, arguments| # ContentDownloader.download(options, arguments) # end # # More calculations... # end def subcommands(cmd); end # A method to setup Slop so it can parse the options your command expects. # # @note Please don't do anything side-effecty in the main part of this # method, as it may be called by Pry at any time for introspection reasons. # If you need to set up default values, use `setup` instead. # # @example # def options(opt) # opt.banner "Gists methods or classes" # opt.on(:c, :class, "gist a class") do # @action = :class # end # end def options(opt); end # The actual body of your command should go here. # # The `opts` mehod can be called to get the options that Slop has passed, # and `args` gives the remaining, unparsed arguments. # # The return value of this method is discarded unless the command was # created with `:keep_retval => true`, in which case it is returned to the # repl. # # @example # def process # if opts.present?(:class) # gist_class # else # gist_method # end # end def process; raise CommandError, "command '#{command_name}' not implemented" end end end pry-0.9.12.6/lib/pry/terminal.rb0000644000004100000410000000434412272154172016341 0ustar www-datawww-dataclass Pry::Terminal class << self # Return a pair of [rows, columns] which gives the size of the window. # # If the window size cannot be determined, return nil. def screen_size rows, cols = actual_screen_size if rows && cols [rows.to_i, cols.to_i] else nil end end # Return a screen size or a default if that fails. def size! default = [27, 80] screen_size || default end # Return a screen width or the default if that fails. def width! size![1] end # Return a screen height or the default if that fails. def height! size![0] end def actual_screen_size # The best way, if possible (requires non-jruby ≥1.9 or io-console gem) screen_size_according_to_io_console or # Fall back to the old standby, though it might be stale: screen_size_according_to_env or # Fall further back, though this one is also out of date without something # calling Readline.set_screen_size screen_size_according_to_readline or # Windows users can otherwise run ansicon and get a decent answer: screen_size_according_to_ansicon_env end def screen_size_according_to_io_console return if Pry::Helpers::BaseHelpers.jruby? require 'io/console' $stdout.winsize if $stdout.tty? and $stdout.respond_to?(:winsize) rescue LoadError # They're probably on 1.8 without the io-console gem. We'll keep trying. end def screen_size_according_to_env size = [ENV['LINES'] || ENV['ROWS'], ENV['COLUMNS']] size if nonzero_column?(size) end def screen_size_according_to_readline if defined?(Readline) && Readline.respond_to?(:get_screen_size) size = Readline.get_screen_size size if nonzero_column?(size) end rescue Java::JavaLang::NullPointerException # This rescue won't happen on jrubies later than: # https://github.com/jruby/jruby/pull/436 nil end def screen_size_according_to_ansicon_env return unless ENV['ANSICON'] =~ /\((.*)x(.*)\)/ size = [$2, $1] size if nonzero_column?(size) end private def nonzero_column?(size) size[1].to_i > 0 end end end pry-0.9.12.6/lib/pry/test/0000755000004100000410000000000012272154172015153 5ustar www-datawww-datapry-0.9.12.6/lib/pry/test/helper.rb0000644000004100000410000001013712272154172016761 0ustar www-datawww-datarequire 'pry' # in case the tests call reset_defaults, ensure we reset them to # amended (test friendly) values class << Pry alias_method :orig_reset_defaults, :reset_defaults 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 end Pry.reset_defaults # A global space for storing temporary state during tests. module PryTestHelpers module_function # inject a variable into a binding def inject_var(name, value, b) Pry.current[:pry_local] = value b.eval("#{name} = ::Pry.current[:pry_local]") ensure Pry.current[:pry_local] = nil end def constant_scope(*names) names.each do |name| Object.remove_const name if Object.const_defined?(name) end yield ensure names.each do |name| Object.remove_const name if Object.const_defined?(name) end end def mri18_and_no_real_source_location? Pry::Helpers::BaseHelpers.mri_18? && !(Method.instance_method(:source_location).owner == Method) end # Open a temp file and yield it to the block, closing it after # @return [String] The path of the temp file def temp_file(ext='.rb') file = Tempfile.new(['pry', ext]) yield file ensure file.close(true) if file File.unlink("#{file.path}c") if File.exists?("#{file.path}c") # rbx end def unindent(*args) Pry::Helpers::CommandHelpers.unindent(*args) end def mock_command(cmd, args=[], opts={}) output = StringIO.new ret = cmd.new(opts.merge(:output => output)).call_safely(*args) Struct.new(:output, :return).new(output.string, ret) end def mock_exception(*mock_backtrace) e = StandardError.new("mock exception") (class << e; self; end).class_eval do define_method(:backtrace) { mock_backtrace } end e end end def pry_tester(*args, &block) if args.length == 0 || args[0].is_a?(Hash) args.unshift(Pry.toplevel_binding) end PryTester.new(*args).tap do |t| (class << t; self; end).class_eval(&block) if block end end def pry_eval(*eval_strs) if eval_strs.first.is_a? String binding = Pry.toplevel_binding else binding = Pry.binding_for(eval_strs.shift) end pry_tester(binding).eval(*eval_strs) end class PryTester attr_reader :pry, :out def initialize(context = TOPLEVEL_BINDING, options = {}) @pry = Pry.new(options) if context target = Pry.binding_for(context) @pry.binding_stack << target @pry.inject_sticky_locals(target) end @pry.input_array << nil # TODO: shouldn't need this reset_output end def eval(*strs) reset_output result = nil strs.flatten.each do |str| str = "#{str.strip}\n" if @pry.process_command(str) result = last_command_result_or_output else result = @pry.evaluate_ruby(str) end end result end def context=(context) @pry.binding_stack << Pry.binding_for(context) end # TODO: eliminate duplication with Pry#repl def simulate_repl didnt_exit = nil break_data = nil didnt_exit = catch(:didnt_exit) do break_data = catch(:breakout) do yield self throw(:didnt_exit, true) end nil end raise "Failed to exit REPL" if didnt_exit break_data end def last_output @out.string if @out end def process_command(command_str, eval_str = '') @pry.process_command(command_str, eval_str) or raise "Not a valid command" last_command_result_or_output end protected def last_command_result result = Pry.current[:pry_cmd_result] result.retval if result end def last_command_result_or_output result = last_command_result if result != Pry::Command::VOID_VALUE result else last_output end end def reset_output @out = StringIO.new @pry.output = @out end end pry-0.9.12.6/lib/pry/cli.rb0000644000004100000410000001172012272154172015271 0ustar www-datawww-data class Pry # Manage the processing of command line options class CLI NoOptionsError = Class.new(StandardError) class << self # @return [Proc] The Proc defining the valid command line options. attr_accessor :options # @return [Array] The Procs that process the parsed options. attr_accessor :option_processors # @return [Array] The input array of strings to process # as CLI options. attr_accessor :input_args # Add another set of CLI options (a Slop block) def add_options(&block) if options old_options = options self.options = proc do instance_exec(&old_options) instance_exec(&block) end else self.options = block end self end # Bring in options defined in plugins def add_plugin_options Pry.plugins.values.each do |plugin| plugin.load_cli_options end self end # Add a block responsible for processing parsed options. def process_options(&block) self.option_processors ||= [] option_processors << block self end # Clear `options` and `option_processors` def reset self.options = nil self.option_processors = nil end def parse_options(args=ARGV.dup) unless options raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options." end self.input_args = args opts = Slop.parse!(args, :help => true, :multiple_switches => false, &options) # Option processors are optional. if option_processors option_processors.each { |processor| processor.call(opts) } end self end end reset end end # String that is built to be executed on start (created by -e and -exec switches) exec_string = "" # Bring in options defined by plugins Slop.new do on "no-plugins" do Pry.config.should_load_plugins = false end end.parse(ARGV.dup) if Pry.config.should_load_plugins Pry::CLI.add_plugin_options end # The default Pry command line options (before plugin options are included) Pry::CLI.add_options do banner %{Usage: pry [OPTIONS] Start a Pry session. See: `https://github.com/pry` for more information. Copyright (c) 2013 John Mair (banisterfiend) -- } on :e, :exec=, "A line of code to execute in context before the session starts" do |input| exec_string << input + "\n" end on "no-pager", "Disable pager for long output" do Pry.config.pager = false end on "no-history", "Disable history loading" do Pry.config.history.should_load = false end on "no-color", "Disable syntax highlighting for session" do Pry.color = false end on :f, "Suppress loading of ~/.pryrc and ./.pryrc" do Pry.config.should_load_rc = false Pry.config.should_load_local_rc = false end on :s, "select-plugin=", "Only load specified plugin (and no others)." do |plugin_name| Pry.config.should_load_plugins = false Pry.plugins[plugin_name].activate! end on :d, "disable-plugin=", "Disable a specific plugin." do |plugin_name| Pry.plugins[plugin_name].disable! end on "no-plugins", "Suppress loading of plugins." do Pry.config.should_load_plugins = false end on "installed-plugins", "List installed plugins." do puts "Installed Plugins:" puts "--" Pry.locate_plugins.each do |plugin| puts "#{plugin.name}".ljust(18) + plugin.spec.summary end exit end on "simple-prompt", "Enable simple prompt mode" do Pry.config.prompt = Pry::SIMPLE_PROMPT end on :r, :require=, "`require` a Ruby script at startup" do |file| Pry.config.requires << file end on :I=, "Add a path to the $LOAD_PATH", :as => Array, :delimiter => ":" do |load_path| load_path.map! do |path| /\A\.\// =~ path ? path : File.expand_path(path) end $LOAD_PATH.unshift(*load_path) end on "gem", "Shorthand for -I./lib -rgemname" do |load_path| $LOAD_PATH.unshift("./lib") Dir["./lib/*.rb"].each do |file| Pry.config.requires << file end end on :v, :version, "Display the Pry version" do puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}" exit end on(:c, :context=, "Start the session in the specified context. Equivalent to `context.pry` in a session.", :default => "Pry.toplevel_binding" ) end.process_options do |opts| exit if opts.help? # invoked via cli Pry.cli = true # create the actual context context = Pry.binding_for(eval(opts[:context])) if Pry::CLI.input_args.any? && Pry::CLI.input_args != ["pry"] full_name = File.expand_path(Pry::CLI.input_args.first) Pry.load_file_through_repl(full_name) exit end if Pry.config.should_load_plugins parser = Slop.new end # Start the session (running any code passed with -e, if there is any) Pry.start(context, :input => StringIO.new(exec_string)) end pry-0.9.12.6/lib/pry/code/0000755000004100000410000000000012272154172015106 5ustar www-datawww-datapry-0.9.12.6/lib/pry/code/code_range.rb0000644000004100000410000000341712272154172017526 0ustar www-datawww-dataclass Pry class Code # Represents a range of lines in a code listing. # # @api private class CodeRange # @param [Integer] start_line # @param [Integer?] end_line def initialize(start_line, end_line = nil) @start_line = start_line @end_line = end_line force_set_end_line end # @param [Array] lines # @return [Range] def indices_range(lines) Range.new(*indices(lines)) end private attr_reader :start_line, :end_line # If `end_line` is equal to `nil`, then calculate it from the first # parameter, `start_line`. Otherwise, leave it as it is. # @return [void] def force_set_end_line if start_line.is_a?(Range) set_end_line_from_range else @end_line ||= start_line end end # Finds indices of `start_line` and `end_line` in the given Array of # +lines+. # # @param [Array] lines # @return [Array] def indices(lines) [find_start_index(lines), find_end_index(lines)] end # @return [Integer] def find_start_index(lines) return start_line if start_line < 0 lines.index { |loc| loc.lineno >= start_line } || lines.length end # @return [Integer] def find_end_index(lines) return end_line if end_line < 0 (lines.index { |loc| loc.lineno > end_line } || 0) - 1 end # For example, if the range is 4..10, then `start_line` would be equal to # 4 and `end_line` to 10. # @return [void] def set_end_line_from_range @end_line = start_line.last @end_line -= 1 if start_line.exclude_end? @start_line = start_line.first end end end end pry-0.9.12.6/lib/pry/code/loc.rb0000644000004100000410000000437212272154172016216 0ustar www-datawww-dataclass Pry class Code # Represents a line of code. A line of code is a tuple, which consists of a # line and a line number. A `LOC` object's state (namely, the line # parameter) can be changed via instance methods. `Pry::Code` heavily uses # this class. # # @api private # @example # loc = LOC.new("def example\n :example\nend", 1) # puts loc.line # def example # :example # end # #=> nil # # loc.indent(3) # loc.line #=> " def example\n :example\nend" class LOC # @return [Array] attr_reader :tuple # @param [String] line The line of code. # @param [Integer] lineno The position of the +line+. def initialize(line, lineno) @tuple = [line.chomp, lineno.to_i] end # @return [Boolean] def ==(other) other.tuple == tuple end def dup self.class.new(line, lineno) end # @return [String] def line tuple.first end # @return [Integer] def lineno tuple.last end # Paints the `line` of code. # # @param [Symbol] code_type # @return [void] def colorize(code_type) tuple[0] = CodeRay.scan(line, code_type).term end # Prepends the line number `lineno` to the `line`. # # @param [Integer] max_width # @return [void] def add_line_number(max_width = 0) padded = lineno.to_s.rjust(max_width) colorized_lineno = Pry::Helpers::BaseHelpers.colorize_code(padded) tuple[0] = "#{ colorized_lineno }: #{ line }" end # Prepends a marker "=>" or an empty marker to the +line+. # # @param [Integer] marker_lineno If it is equal to the `lineno`, then # prepend a hashrocket. Otherwise, an empty marker. # @return [void] def add_marker(marker_lineno) tuple[0] = if lineno == marker_lineno " => #{ line }" else " #{ line }" end end # Indents the `line` with +distance+ spaces. # # @param [Integer] distance # @return [void] def indent(distance) tuple[0] = "#{ ' ' * distance }#{ line }" end end end end pry-0.9.12.6/lib/pry/helpers.rb0000644000004100000410000000024612272154172016165 0ustar www-datawww-datarequire "pry/helpers/base_helpers" require "pry/helpers/options_helpers" require "pry/helpers/command_helpers" require "pry/helpers/text" require "pry/helpers/table" pry-0.9.12.6/lib/pry/version.rb0000644000004100000410000000004512272154172016205 0ustar www-datawww-dataclass Pry VERSION = "0.9.12.6" end pry-0.9.12.6/lib/pry/code.rb0000644000004100000410000002670412272154172015444 0ustar www-datawww-datarequire 'pry/code/loc' require 'pry/code/code_range' class Pry class << self # 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 def Code(obj) case obj when Code obj when ::Method, UnboundMethod, Proc, Pry::Method Code.from_method(obj) else Code.new(obj) end end end # `Pry::Code` is a class that encapsulates lines of source code and their # line numbers and formats them for terminal output. It can read from a file # or method definition or be instantiated with a `String` or an `Array`. # # In general, the formatting methods in `Code` return a new `Code` object # which will format the text as specified when `#to_s` is called. This allows # arbitrary chaining of formatting methods without mutating the original # object. class Code # List of all supported languages. # @return [Hash] EXTENSIONS = { %w(.py) => :python, %w(.js) => :javascript, %w(.css) => :css, %w(.xml) => :xml, %w(.php) => :php, %w(.html) => :html, %w(.diff) => :diff, %w(.java) => :java, %w(.json) => :json, %w(.c .h) => :c, %w(.rhtml) => :rhtml, %w(.yaml .yml) => :yaml, %w(.cpp .hpp .cc .h cxx) => :cpp, %w(.rb .ru .irbrc .gemspec .pryrc) => :ruby, } class << self include MethodSource::CodeHelpers # Instantiate a `Code` object containing code loaded from a file or # Pry's line buffer. # # @param [String] filename The name of a file, or "(pry)". # @param [Symbol] code_type The type of code the file contains. # @return [Code] def from_file(filename, code_type = type_from_filename(filename)) code = if filename == Pry.eval_path Pry.line_buffer.drop(1) else File.read(abs_path(filename)) end new(code, 1, code_type) end # Instantiate a `Code` object containing code extracted from a # `::Method`, `UnboundMethod`, `Proc`, or `Pry::Method` object. # # @param [::Method, UnboundMethod, Proc, Pry::Method] meth The method # object. # @param [Integer, nil] start_line The line number to start on, or nil to # use the method's original line numbers. # @return [Code] def from_method(meth, start_line = nil) meth = Pry::Method(meth) start_line ||= meth.source_line || 1 new(meth.source, start_line, meth.source_type) end # Attempt to extract the source code for module (or class) `mod`. # # @param [Module, Class] mod The module (or class) of interest. # @param [Integer] candidate_rank The module candidate (by rank) # to use (see `Pry::WrappedModule::Candidate` for more information). # @param [Integer, nil] start_line The line number to start on, or nil to # use the method's original line numbers. # @return [Code] def from_module(mod, candidate_rank = 0, start_line=nil) candidate = Pry::WrappedModule(mod).candidate(candidate_rank) start_line ||= candidate.line new(candidate.source, start_line, :ruby) end protected # Guess the CodeRay type of a file from its extension, or nil if # unknown. # # @param [String] filename # @param [Symbol] default (:ruby) the file type to assume if none could be # detected. # @return [Symbol, nil] def type_from_filename(filename, default = :ruby) _, type = Pry::Code::EXTENSIONS.find do |k, _| k.any? { |ext| ext == File.extname(filename) } end type || default end # @param [String] filename # @raise [MethodSource::SourceNotFoundError] if the +filename+ is not # readable for some reason. # @return [String] absolute path for the given +filename+. def abs_path(filename) abs_path = [File.expand_path(filename, Dir.pwd), File.expand_path(filename, Pry::INITIAL_PWD) ].detect { |abs_path| File.readable?(abs_path) } abs_path or raise MethodSource::SourceNotFoundError, "Cannot open #{filename.inspect} for reading." end end # @return [Symbol] The type of code stored in this wrapper. attr_accessor :code_type # Instantiate a `Code` object containing code from the given `Array`, # `String`, or `IO`. The first line will be line 1 unless specified # otherwise. If you need non-contiguous line numbers, you can create an # empty `Code` object and then use `#push` to insert the lines. # # @param [Array, String, IO] lines # @param [Integer?] start_line # @param [Symbol?] code_type def initialize(lines = [], start_line = 1, code_type = :ruby) if lines.is_a? String lines = lines.lines end @lines = lines.each_with_index.map { |line, lineno| LOC.new(line, lineno + start_line.to_i) } @code_type = code_type end # Append the given line. +lineno+ is one more than the last existing # line, unless specified otherwise. # # @param [String] line # @param [Integer?] lineno # @return [String] The inserted line. def push(line, lineno = nil) if lineno.nil? lineno = @lines.last.lineno + 1 end @lines.push(LOC.new(line, lineno)) line end alias << push # Filter the lines using the given block. # # @yield [LOC] # @return [Code] def select(&block) alter do @lines = @lines.select(&block) end end # Remove all lines that aren't in the given range, expressed either as a # `Range` object or a first and last line number (inclusive). Negative # indices count from the end of the array of lines. # # @param [Range, Integer] start_line # @param [Integer?] end_line # @return [Code] def between(start_line, end_line = nil) return self unless start_line code_range = CodeRange.new(start_line, end_line) alter do @lines = @lines[code_range.indices_range(@lines)] || [] end end # Take `num_lines` from `start_line`, forward or backwards. # # @param [Integer] start_line # @param [Integer] num_lines # @return [Code] def take_lines(start_line, num_lines) start_idx = if start_line >= 0 @lines.index { |loc| loc.lineno >= start_line } || @lines.length else @lines.length + start_line end alter do @lines = @lines.slice(start_idx, num_lines) end end # Remove all lines except for the +lines+ up to and excluding +lineno+. # # @param [Integer] lineno # @param [Integer] lines # @return [Code] def before(lineno, lines = 1) return self unless lineno select do |loc| loc.lineno >= lineno - lines && loc.lineno < lineno end end # Remove all lines except for the +lines+ on either side of and including # +lineno+. # # @param [Integer] lineno # @param [Integer] lines # @return [Code] def around(lineno, lines = 1) return self unless lineno select do |loc| loc.lineno >= lineno - lines && loc.lineno <= lineno + lines end end # Remove all lines except for the +lines+ after and excluding +lineno+. # # @param [Integer] lineno # @param [Integer] lines # @return [Code] def after(lineno, lines = 1) return self unless lineno select do |loc| loc.lineno > lineno && loc.lineno <= lineno + lines end end # Remove all lines that don't match the given `pattern`. # # @param [Regexp] pattern # @return [Code] def grep(pattern) return self unless pattern pattern = Regexp.new(pattern) select do |loc| loc.line =~ pattern end end # Format output with line numbers next to it, unless `y_n` is falsy. # # @param [Boolean?] y_n # @return [Code] def with_line_numbers(y_n = true) alter do @with_line_numbers = y_n end end # Format output with a marker next to the given +lineno+, unless +lineno+ is # falsy. # # @param [Integer?] lineno # @return [Code] def with_marker(lineno = 1) alter do @with_marker = !!lineno @marker_lineno = lineno end end # Format output with the specified number of spaces in front of every line, # unless `spaces` is falsy. # # @param [Integer?] spaces # @return [Code] def with_indentation(spaces = 0) alter do @with_indentation = !!spaces @indentation_num = spaces end end # @return [String] def inspect Object.instance_method(:to_s).bind(self).call end # @return [Integer] the number of digits in the last line. def max_lineno_width @lines.length > 0 ? @lines.last.lineno.to_s.length : 0 end # @return [String] a formatted representation (based on the configuration of # the object). def to_s @lines.map { |loc| loc = loc.dup loc.colorize(@code_type) if Pry.color loc.add_line_number(max_lineno_width) if @with_line_numbers loc.add_marker(@marker_lineno) if @with_marker loc.indent(@indentation_num) if @with_indentation loc.line }.join("\n") + "\n" end # Get the comment that describes the expression on the given line number. # # @param [Integer] line_number (1-based) # @return [String] the code. def comment_describing(line_number) self.class.comment_describing(raw, line_number) end # Get the multiline expression that starts on the given line number. # # @param [Integer] line_number (1-based) # @return [String] the code. def expression_at(line_number, consume = 0) self.class.expression_at(raw, line_number, :consume => consume) end # Get the (approximate) Module.nesting at the give line number. # # @param [Integer] line_number line number starting from 1 # @param [Module] top_module the module in which this code exists # @return [Array] a list of open modules. def nesting_at(line_number, top_module = Object) Pry::Indent.nesting_at(raw, line_number) end # Return an unformatted String of the code. # # @return [String] def raw @lines.map(&:line).join("\n") + "\n" end # Return the number of lines stored. # # @return [Integer] def length @lines ? @lines.length : 0 end # Two `Code` objects are equal if they contain the same lines with the same # numbers. Otherwise, call `to_s` and `chomp` and compare as Strings. # # @param [Code, Object] other # @return [Boolean] def ==(other) if other.is_a?(Code) other_lines = other.instance_variable_get(:@lines) @lines.each_with_index.all? { |loc, i| loc == other_lines[i] } else to_s.chomp == other.to_s.chomp end end # Forward any missing methods to the output of `#to_s`. def method_missing(name, *args, &block) to_s.send(name, *args, &block) end undef =~ protected # An abstraction of the `dup.instance_eval` pattern used throughout this # class. def alter(&block) dup.tap { |o| o.instance_eval(&block) } end end end pry-0.9.12.6/lib/pry/config.rb0000644000004100000410000002471612272154172016000 0ustar www-datawww-datarequire 'ostruct' class Pry class Config < OpenStruct # Get/Set the object to use for input by default by all Pry instances. # Pry.config.input is an option determining the input object - the object from # which Pry retrieves its lines of input. Pry accepts any object that # implements the readline method. This includes IO objects, StringIO, # Readline, File and custom objects. It can also be a Proc which returns an # object implementing the readline method. # @return [#readline] The object to use for input by default by all # Pry instances. # @example # Pry.config.input = StringIO.new("@x = 10\nexit") def input @reified_input ||= if @input.respond_to?(:call) @input.call else @input end end def input=(input) @reified_input = nil @input = input end # Get/Set the object to use for output by default by all Pry instances. # Pry.config.output is an option determining the output object - the object to which # Pry writes its output. Pry accepts any object that implements the puts method. This # includes IO objects, StringIO, File and custom objects. # @return [#puts] The object to use for output by default by all # Pry instances. # @example # Pry.config.output = StringIO.new attr_accessor :output # Get/Set the object to use for commands by default by all Pry instances. # @return [Pry::CommandBase] The object to use for commands by default by all # Pry instances. # @example # Pry.config.commands = Pry::CommandSet.new do # import_from Pry::Commands, "ls" # # command "greet" do |name| # output.puts "hello #{name}" # end # end attr_accessor :commands # Get/Set the Proc to use for printing by default by all Pry # instances. # Two parameters are passed to the print Proc: these are (1) the # output object for the current session and (2) the expression value to print. It is important # that you write to the output object instead of just stdout so that all Pry output can be redirected if necessary. # This is the 'print' component of the REPL. # @return [Proc] The Proc to use for printing by default by all # Pry instances. # @example # Pry.config.print = proc { |output, value| output.puts "=> #{value.inspect}" } attr_accessor :print # Pry.config.exception_handler is an option determining the exception handler object - the # Proc responsible for dealing with exceptions raised by user input to the REPL. # Three parameters are passed to the exception handler Proc: these # are (1) the output object for the current session, (2) the # exception object that was raised inside the Pry session, and (3) # a reference to the associated Pry instance. # @return [Proc] The Proc to use for printing exceptions by default by all # Pry instances. # @example # Pry.config.exception_handler = proc do |output, exception, _| # output.puts "#{exception.class}: #{exception.message}" # output.puts "from #{exception.backtrace.first}" # end attr_accessor :exception_handler # @return [Array] The classes of exception that will not be caught by Pry. # @example # Pry.config.exception_whitelist = [SystemExit, SignalException] attr_accessor :exception_whitelist # @return [Fixnum] The number of lines of context to show before and after # exceptions, etc. # @example # Pry.config.default_window_size = 10 attr_accessor :default_window_size # Get/Set the `Pry::Hooks` instance that defines Pry hooks used by default by all Pry # instances. # @return [Pry::Hooks] The hooks used by default by all Pry instances. # @example # Pry.config.hooks = Pry::Hooks.new.add_hook(:before_session, # :default) { |output, target, _pry_| output.puts "Good morning!" } attr_reader :hooks # FIXME: # This is a hack to alert people of the new API. # @param [Pry::Hooks] v Only accept `Pry::Hooks` now! 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 # Get/Set the stack of input objects that a Pry instance switches # to when its current input object encounters EOF. # @return [Array] The array of input objects. # @example # Pry.config.input_stack = [StringIO.new("puts 'hello world'\nexit")] attr_accessor :input_stack # Get the array of Procs (or single Proc) to be used for the prompts by default by # all Pry instances. # Three parameters are passed into the prompt procs, (1) the # object that is the target of the session, (2) the current # nesting level, and (3) a reference to the associated Pry instance. These objects can be used in the prompt, if desired. # @return [Array, Proc] The array of Procs to be used for the # prompts by default by all Pry instances. # @example # Pry.config.prompt = proc { |obj, nest_level, _pry_| "#{obj}:#{nest_level}> " } attr_accessor :prompt # The display name that is part of the prompt. Default is 'pry'. # You can set your own name so you can identify which project your current pry session # is using. This is useful if you have a local pryrc file in a Rails project for example. # @return [String] # @example # Pry.config.prompt_name = 'my_rails_project' attr_accessor :prompt_name # The default editor to use. Defaults to $VISUAL, $EDITOR, or a sensible fallback # for the platform. # If `editor` is a String then that string is used as the shell # command to invoke the editor. If `editor` is callable (e.g a # Proc) then `file`, `line`, and `reloading` are passed in as parameters and the # return value of that callable invocation is used as the exact # shell command to invoke the editor. `reloading` indicates whether Pry will be # reloading code after the shell command returns. Any or all of these parameters # can be omitted from the callable's signature. # @example String # Pry.config.editor = "emacsclient" # @example Callable # Pry.config.editor = proc { |file, line| "emacsclient #{file} +#{line}" } # @example Callable waiting only if reloading # Pry.config.editor = proc { |file, line, reloading| "subl #{'--wait' if reloading} #{file}:#{line}" } # @return [String, #call] attr_accessor :editor # A string that must precede all Pry commands (e.g., if command_prefix is # set to "%", the "cd" command must be invoked as "%cd"). # @return [String] attr_accessor :command_prefix # @return [Boolean] Toggle Pry color on and off. attr_accessor :color # @return [Boolean] Toggle paging on and off. attr_accessor :pager # Determines whether the rc file (~/.pryrc) should be loaded. # @return [Boolean] attr_accessor :should_load_rc # Determines whether the local rc file (./.pryrc) should be loaded. # @return [Boolean] attr_accessor :should_load_local_rc # Determines whether plugins should be loaded. # @return [Boolean] attr_accessor :should_load_plugins # Determines whether to load files specified with the -r flag. # @return [Boolean] attr_accessor :should_load_requires # Determines whether to disable edit-method's auto-reloading behavior. # @return [Boolean] attr_accessor :disable_auto_reload # Determines whether Pry should trap SIGINT and cause it to raise an # Interrupt exception. This is only useful on jruby, MRI does this # for us. # @return [Boolean] attr_accessor :should_trap_interrupts # Config option for history. # sub-options include history.file, history.load, and history.save # history.file is the file to save/load history to, e.g # Pry.config.history.file = "~/.pry_history". # history.should_load is a boolean that determines whether history will be # loaded from history.file at session start. # history.should_save is a boolean that determines whether history will be # saved to history.file at session end. # @return [OpenStruct] attr_accessor :history # Config option for plugins: # sub-options include: # `plugins.strict_loading` (Boolean) which toggles whether referring to a non-existent plugin should raise an exception (defaults to `false`) # @return [OpenStruct] attr_accessor :plugins # @return [Array] Ruby files to be required after loading any plugins. attr_accessor :requires # @return [Integer] Amount of results that will be stored into out attr_accessor :memory_size # @return [Proc] The proc that manages ^D presses in the REPL. # The proc is passed the current eval_string and the current pry instance. attr_accessor :control_d_handler # @return [Proc] The proc that runs system commands # The proc is passed the pry output object, the command string # to eval, and a reference to the pry instance attr_accessor :system # @return [Boolean] Whether or not code should be indented # using Pry::Indent. attr_accessor :auto_indent # @return [Boolean] Whether or not indentation should be corrected # after hitting enter. This feature is not supported by all terminals. attr_accessor :correct_indent # @return [Boolean] Whether or not a warning will be displayed when # a command name collides with a method/local in the current context. attr_accessor :collision_warning # Config option for gist. # sub-options include `gist.inspecter`, # `gist.inspecter` is a callable that defines how the expression output # will be displayed when using the `gist -i` command. # @example Pretty inspect output # Pry.config.gist.inspecter = proc { |v| v.pretty_inspect } # @example Regular inspect # Pry.config.gist.inspecter = proc &:inspect # @return [OpenStruct] attr_accessor :gist # @return [Hash] Additional sticky locals (to the standard ones) to use in Pry sessions. # @example Inject `random_number` sticky local into Pry session # Pry.config.extra_sticky_locals = { :random_number => proc { # rand(10) } } attr_accessor :extra_sticky_locals # @return [#build_completion_proc] A completer to use. attr_accessor :completer end end pry-0.9.12.6/lib/pry/pry_class.rb0000644000004100000410000003456612272154172016536 0ustar www-datawww-datarequire 'ostruct' require 'forwardable' require 'pry/config' class Pry # The RC Files to load. HOME_RC_FILE = "~/.pryrc" LOCAL_RC_FILE = "./.pryrc" # @return [Hash] Pry's `Thread.current` hash def self.current Thread.current[:__pry__] ||= {} end # class accessors class << self extend Forwardable # convenience method def self.delegate_accessors(delagatee, *names) def_delegators delagatee, *names def_delegators delagatee, *names.map { |v| "#{v}=" } end # Get/Set the Proc that defines extra Readline completions (on top # of the ones defined for IRB). # @return [Proc] The Proc that defines extra Readline completions (on top # @example Add file names to completion list # Pry.custom_completions = proc { Dir.entries('.') } attr_accessor :custom_completions # @return [Fixnum] The current input line. attr_accessor :current_line # @return [Array] The Array of evaluated expressions. attr_accessor :line_buffer # @return [String] The __FILE__ for the `eval()`. Should be "(pry)" # by default. attr_accessor :eval_path # @return [OpenStruct] Return Pry's config object. attr_accessor :config # @return [History] Return Pry's line history object. attr_accessor :history # @return [Boolean] Whether Pry was activated from the command line. attr_accessor :cli # @return [Boolean] Whether Pry sessions are quiet by default. attr_accessor :quiet # @return [Binding] A top level binding with no local variables attr_accessor :toplevel_binding # @return [Exception, nil] The last pry internal error. # (a CommandError in most cases) attr_accessor :last_internal_error # plugin forwardables def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins delegate_accessors :@config, :input, :output, :commands, :prompt, :print, :exception_handler, :hooks, :color, :pager, :editor, :memory_size, :input_stack, :extra_sticky_locals end # Load the given file in the context of `Pry.toplevel_binding` # @param [String] file_name The unexpanded file path. 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 # 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. def self.load_rc load_file_at_toplevel(HOME_RC_FILE) end # Load the local RC file (./.pryrc) 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 any Ruby files specified with the -r flag on the command line. 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. def self.load_traps trap('INT'){ raise Interrupt } end # Do basic setup for initial session. # Including: loading .pryrc, loading plugins, loading requires, and # loading history. def self.initial_session_setup return unless 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 # 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) 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 # Execute the file through the REPL loop, non-interactively. # @param [String] file_name File name to load through the REPL. def self.load_file_through_repl(file_name) require "pry/repl_file_loader" REPLFileLoader.new(file_name).load end # An inspector that clips the output to `max_length` chars. # In case of > `max_length` chars the `# 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`. 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 # Load Readline history if required. def self.load_history Pry.history.load end # Save new lines of Readline history if required. def self.save_history Pry.history.save end # @return [Boolean] Whether this is the first time a Pry session has # been started since loading the Pry class. def self.initial_session? @initial_session end # Run a Pry command from outside a session. The commands available are # those referenced by `Pry.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 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 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 def self.auto_resize! Pry.require_readline ver = Readline::VERSION if ver[/edit/i] 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 def self.set_config_defaults config.input = proc { Pry.require_readline; 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 = "=> " config.completer = Pry::BondCompleter 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 # Set all the configurable options back to their default values def self.reset_defaults set_config_defaults @initial_session = true self.custom_completions = DEFAULT_CUSTOM_COMPLETIONS self.cli = false self.current_line = 1 self.line_buffer = [""] self.eval_path = "(pry)" fix_coderay_colors end # To avoid mass-confusion, we change the default colour of "white" to # "blue" enabling global legibility def self.fix_coderay_colors colors = CodeRay::Encoders::Terminal::TOKEN_COLORS if colors[:comment].is_a?(String) colors[:comment] = "0;34" end end # Basic initialization. def self.init @plugin_manager ||= PluginManager.new self.config ||= Config.new self.history ||= History.new reset_defaults locate_plugins 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. def self.binding_for(target) if Binding === target target else if TOPLEVEL_BINDING.eval('self') == target TOPLEVEL_BINDING else target.__binding__ end end end def self.toplevel_binding unless @toplevel_binding # Grab a copy of the TOPLEVEL_BINDING without any local variables. # This binding has a default definee of Object, and new methods are # private (just as in TOPLEVEL_BINDING). TOPLEVEL_BINDING.eval <<-RUBY def self.__pry__ binding end Pry.toplevel_binding = __pry__ class << self; undef __pry__; end RUBY end @toplevel_binding.eval('private') @toplevel_binding end def self.in_critical_section? @critical_section.to_i > 0 end def self.critical_section(&block) @critical_section = @critical_section.to_i + 1 yield ensure @critical_section -= 1 end end Pry.init pry-0.9.12.6/lib/pry/core_extensions.rb0000644000004100000410000000765412272154172017744 0ustar www-datawww-dataclass Pry # @return [Array] Code of the method used when implementing Pry's # __binding__, along with line indication to be used with instance_eval (and # friends). # # @see Object#__binding__ BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1] # Get a binding with 'self' set to self, and no locals. # # The default definee is determined by the context in which the # definition is eval'd. # # Please don't call this method directly, see {__binding__}. # # @return [Binding] def __pry__ binding end METHOD end class Object # Start a Pry REPL on self. # # If `self` is a Binding then that will be used to evaluate expressions; # otherwise a new binding will be created. # # @param [Object] object the object or binding to pry # (__deprecated__, use `object.pry`) # @param [Hash] hash the options hash # @example With a binding # binding.pry # @example On any object # "dummy".pry # @example With options # def my_method # binding.pry :quiet => true # end # my_method() # @see Pry.start def pry(object=nil, hash={}) if object.nil? || Hash === object Pry.start(self, object || {}) else Pry.start(object, hash) end end # Return a binding object for the receiver. # # The `self` of the binding is set to the current object, and it contains no # local variables. # # The default definee (http://yugui.jp/articles/846) is set such that: # # * If `self` is a class or module, then new methods created in the binding # will be defined in that class or module (as in `class Foo; end`). # * If `self` is a normal object, then new methods created in the binding will # be defined on its singleton class (as in `class << self; end`). # * If `self` doesn't have a real singleton class (i.e. it is a Fixnum, Float, # Symbol, nil, true, or false), then new methods will be created on the # object's class (as in `self.class.class_eval{ }`) # # Newly created constants, including classes and modules, will also be added # to the default definee. # # @return [Binding] def __binding__ # If you ever feel like changing this method, be careful about variables # that you use. They shouldn't be inserted into the binding that will # eventually be returning. # When you're cd'd into a class, methods you define should be added to it. if is_a?(Module) # class_eval sets both self and the default definee to this class. return class_eval "binding" end unless respond_to?(:__pry__) # The easiest way to check whether an object has a working singleton class # is to try and define a method on it. (just checking for the presence of # the singleton class gives false positives for `true` and `false`). # __pry__ is just the closest method we have to hand, and using # it has the nice property that we can memoize this check. begin # instance_eval sets the default definee to the object's singleton class instance_eval *Pry::BINDING_METHOD_IMPL # If we can't define methods on the Object's singleton_class. Then we fall # back to setting the default definee to be the Object's class. That seems # nicer than having a REPL in which you can't define methods. rescue TypeError # class_eval sets the default definee to self.class self.class.class_eval *Pry::BINDING_METHOD_IMPL end end __pry__ end end # There's a splat bug on jruby in 1.9 emulation mode, which breaks the # pp library. # # * http://jira.codehaus.org/browse/JRUBY-6687 # * https://github.com/pry/pry/issues/568 # # Until that gets fixed upstream, let's monkey-patch here: if [[1, 2]].pretty_inspect == "[1]\n" class Array def pretty_print(q) q.group(1, '[', ']') { i = 0 q.seplist(self) { |*| q.pp self[i] i += 1 } } end end end pry-0.9.12.6/lib/pry/rbx_path.rb0000644000004100000410000000073712272154172016337 0ustar www-datawww-dataclass Pry module RbxPath module_function def is_core_path?(path) path.start_with?("kernel") || path.start_with?("lib") end def convert_path_to_full(path) if path.start_with?("kernel") File.join File.dirname(Rubinius::KERNEL_PATH), path elsif path.start_with?("lib") File.join File.dirname(Rubinius::LIB_PATH), path else path end end def rvm_ruby?(path) !!(path =~ /\.rvm/) end end end pry-0.9.12.6/lib/pry/commands.rb0000644000004100000410000000024012272154172016316 0ustar www-datawww-data# Default commands used by Pry. Pry::Commands = Pry::CommandSet.new Dir[File.expand_path('../commands', __FILE__) + '/*.rb'].each do |file| require file end pry-0.9.12.6/lib/pry/method.rb0000644000004100000410000004614412272154172016012 0ustar www-datawww-data# -*- coding: utf-8 -*- require 'pry/helpers/documentation_helpers' class Pry class << self # If the given object is a `Pry::Method`, return it unaltered. If it's # anything else, return it wrapped in a `Pry::Method` instance. def Method(obj) if obj.is_a? Pry::Method obj else Pry::Method.new(obj) end end end # This class wraps the normal `Method` and `UnboundMethod` classes # to provide extra functionality useful to Pry. class Method require 'pry/method/weird_method_locator' require 'pry/method/disowned' extend Helpers::BaseHelpers include Helpers::BaseHelpers include RbxMethod if rbx? include Helpers::DocumentationHelpers include CodeObject::Helpers class << self # Given a string representing a method name and optionally a binding to # search in, find and return the requested method wrapped in a `Pry::Method` # instance. # # @param [String, nil] name The name of the method to retrieve, or `nil` to # delegate to `from_binding` instead. # @param [Binding] target The context in which to search for the method. # @param [Hash] options # @option options [Boolean] :instance Look for an instance method if `name` doesn't # contain any context. # @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't # contain any context. # @return [Pry::Method, nil] A `Pry::Method` instance containing the requested # method, or `nil` if no method could be located matching the parameters. def from_str(name, target=TOPLEVEL_BINDING, options={}) if name.nil? from_binding(target) elsif name.to_s =~ /(.+)\#(\S+)\Z/ context, meth_name = $1, $2 from_module(target.eval(context), meth_name, target) elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/ context, meth_name = $1, $3 from_obj(target.eval(context), meth_name, target) elsif options[:instance] from_module(target.eval("self"), name, target) elsif options[:methods] from_obj(target.eval("self"), name, target) else from_str(name, target, :instance => true) or from_str(name, target, :methods => true) end rescue Pry::RescuableException nil end # Given a `Binding`, try to extract the `::Method` it originated from and # use it to instantiate a `Pry::Method`. Return `nil` if this isn't # possible. # # @param [Binding] b # @return [Pry::Method, nil] # def from_binding(b) meth_name = b.eval('::Kernel.__method__') if [:__script__, nil].include?(meth_name) nil else method = begin if Object === b.eval('self') new(Kernel.instance_method(:method).bind(b.eval("self")).call(meth_name)) else new(b.eval('class << self; self; end.instance_method(::Kernel.__method__).bind(self)')) end rescue NameError, NoMethodError Disowned.new(b.eval('self'), meth_name.to_s) end if WeirdMethodLocator.weird_method?(method, b) WeirdMethodLocator.new(method, b).get_method || method else method end end end # In order to support 2.0 Refinements we need to look up methods # inside the relevant Binding. # @param [Object] obj The owner/receiver of the method. # @param [Symbol] method_name The name of the method. # @param [Symbol] method_type The type of method: :method or :instance_method # @param [Binding] target The binding where the method is looked up. # @return [Method, UnboundMethod] The 'refined' method object. def lookup_method_via_binding(obj, method_name, method_type, target=TOPLEVEL_BINDING) Pry.current[:obj] = obj Pry.current[:name] = method_name receiver = obj.is_a?(Module) ? "Module" : "Kernel" target.eval("::#{receiver}.instance_method(:#{method_type}).bind(Pry.current[:obj]).call(Pry.current[:name])") ensure Pry.current[:obj] = Pry.current[:name] = nil end # Given a `Class` or `Module` and the name of a method, try to # instantiate a `Pry::Method` containing the instance method of # that name. Return `nil` if no such method exists. # # @param [Class, Module] klass # @param [String] name # @param [Binding] target The binding where the method is looked up. # @return [Pry::Method, nil] def from_class(klass, name, target=TOPLEVEL_BINDING) new(lookup_method_via_binding(klass, name, :instance_method, target)) rescue nil end alias from_module from_class # Given an object and the name of a method, try to instantiate # a `Pry::Method` containing the method of that name bound to # that object. Return `nil` if no such method exists. # # @param [Object] obj # @param [String] name # @param [Binding] target The binding where the method is looked up. # @return [Pry::Method, nil] def from_obj(obj, name, target=TOPLEVEL_BINDING) new(lookup_method_via_binding(obj, name, :method, target)) rescue nil end # Get all of the instance methods of a `Class` or `Module` # @param [Class,Module] klass # @param [Boolean] include_super Whether to include methods from ancestors. # @return [Array[Pry::Method]] def all_from_class(klass, include_super=true) all_from_common(klass, :instance_method, include_super) end # Get all of the methods on an `Object` # @param [Object] obj # @param [Boolean] include_super Whether to include methods from ancestors. # @return [Array[Pry::Method]] def all_from_obj(obj, include_super=true) all_from_common(obj, :method, include_super) end # Get every `Class` and `Module`, in order, that will be checked when looking # for an instance method to call on this object. # @param [Object] obj # @return [Array[Class, Module]] def resolution_order(obj) if Class === obj singleton_class_resolution_order(obj) + instance_resolution_order(Class) else klass = singleton_class(obj) rescue obj.class instance_resolution_order(klass) end end # Get every `Class` and `Module`, in order, that will be checked when looking # for methods on instances of the given `Class` or `Module`. # This does not treat singleton classes of classes specially. # @param [Class, Module] klass # @return [Array[Class, Module]] def instance_resolution_order(klass) # include klass in case it is a singleton class, ([klass] + klass.ancestors).uniq end def method_definition?(name, definition_line) singleton_method_definition?(name, definition_line) || instance_method_definition?(name, definition_line) end def singleton_method_definition?(name, definition_line) /^define_singleton_method\(?\s*[:\"\']#{name}|^def\s*self\.#{name}/ =~ definition_line.strip end def instance_method_definition?(name, definition_line) /^define_method\(?\s*[:\"\']#{name}|^def\s*#{name}/ =~ definition_line.strip end private # See all_from_class and all_from_obj. # If method_type is :instance_method, obj must be a `Class` or a `Module` # If method_type is :method, obj can be any `Object` # # N.B. we pre-cache the visibility here to avoid O(N²) behaviour in "ls". def all_from_common(obj, method_type, include_super=true) %w(public protected private).map do |visibility| safe_send(obj, :"#{visibility}_#{method_type}s", include_super).map do |method_name| new(safe_send(obj, method_type, method_name), :visibility => visibility.to_sym) end end.flatten(1) end # Get the singleton classes of superclasses that could define methods on # the given class object, and any modules they include. # If a module is included at multiple points in the ancestry, only # the lowest copy will be returned. def singleton_class_resolution_order(klass) resolution_order = klass.ancestors.map do |anc| [singleton_class(anc)] + singleton_class(anc).included_modules if anc.is_a?(Class) end.compact.flatten(1) resolution_order.reverse.uniq.reverse - Class.included_modules end def singleton_class(obj); class << obj; self; end end end # A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`. # # @param [::Method, UnboundMethod, Proc] method # @param [Hash] known_info Can be used to pre-cache expensive to compute stuff. # @return [Pry::Method] def initialize(method, known_info={}) @method = method @visibility = known_info[:visibility] end # Get the name of the method as a String, regardless of the underlying Method#name type. # @return [String] def name @method.name.to_s end # Get the owner of the method as a Pry::Module # @return [Pry::Module] def wrapped_owner @wrapped_owner ||= Pry::WrappedModule.new(owner) end # Get underlying object wrapped by this Pry::Method instance # @return [Method, UnboundMethod, Proc] def wrapped @method end # Is the method undefined? (aka `Disowned`) # @return [Boolean] false def undefined? false end # Get the name of the method including the class on which it was defined. # @example # method(:puts).method_name # => "Kernel.puts" # @return [String] def name_with_owner "#{wrapped_owner.method_prefix}#{name}" end # @return [String, nil] The source code of the method, or `nil` if it's unavailable. def source @source ||= case source_type when :c info = pry_doc_info if info and info.source code = strip_comments_from_c_code(info.source) end when :ruby # clone of MethodSource.source_helper that knows to use our # hacked version of source_location for rbx core methods, and # our input buffer for methods defined in (pry) file, line = *source_location raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!" unless file begin code = Pry::Code.from_file(file).expression_at(line) rescue SyntaxError => e raise MethodSource::SourceNotFoundError.new(e.message) end strip_leading_whitespace(code) end end # Can we get the source code for this method? # @return [Boolean] def source? !!source rescue MethodSource::SourceNotFoundError false end # @return [String, nil] The documentation for the method, or `nil` if it's # unavailable. # @raise [CommandError] Raises when the method was defined in the REPL. def doc @doc ||= case source_type when :c info = pry_doc_info info.docstring if info when :ruby if rbx? && !pry_method? get_comment_content(core_doc) elsif pry_method? get_comment_content(doc_for_pry_method) else get_comment_content(@method.comment) end end end # @return [Symbol] The source type of the method. The options are # `:ruby` for Ruby methods or `:c` for methods written in C. def source_type source_location.nil? ? :c : :ruby end def source_location if @method.source_location && rbx? file, line = @method.source_location [RbxPath.convert_path_to_full(file), line] else @method.source_location end end # @return [String, nil] The name of the file the method is defined in, or # `nil` if the filename is unavailable. def source_file if source_location.nil? if !rbx? and source_type == :c info = pry_doc_info info.file if info end else source_location.first end end # @return [Fixnum, nil] The line of code in `source_file` which begins # the method's definition, or `nil` if that information is unavailable. def source_line source_location.nil? ? nil : source_location.last end # @return [Range, nil] The range of lines in `source_file` which contain # the method's definition, or `nil` if that information is unavailable. def source_range source_location.nil? ? nil : (source_line)..(source_line + source.lines.count - 1) end # @return [Symbol] The visibility of the method. May be `:public`, # `:protected`, or `:private`. def visibility @visibility ||= if owner.public_instance_methods.any? { |m| m.to_s == name } :public elsif owner.protected_instance_methods.any? { |m| m.to_s == name } :protected elsif owner.private_instance_methods.any? { |m| m.to_s == name } :private else :none end end # @return [String] A representation of the method's signature, including its # name and parameters. Optional and "rest" parameters are marked with `*` # and block parameters with `&`. If the parameter names are unavailable, # they're given numbered names instead. # Paraphrased from `awesome_print` gem. def signature if respond_to?(:parameters) args = parameters.inject([]) do |arr, (type, name)| name ||= (type == :block ? 'block' : "arg#{arr.size + 1}") arr << case type when :req then name.to_s when :opt then "#{name}=?" when :rest then "*#{name}" when :block then "&#{name}" else '?' end end else args = (1..arity.abs).map { |i| "arg#{i}" } args[-1] = "*#{args[-1]}" if arity < 0 end "#{name}(#{args.join(', ')})" end # @return [Pry::Method, nil] The wrapped method that is called when you # use "super" in the body of this method. def super(times=1) if UnboundMethod === @method sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times) else sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times) sup &&= sup.bind(receiver) end Pry::Method.new(sup) if sup end # @return [String, nil] The original name the method was defined under, # before any aliasing, or `nil` if it can't be determined. def original_name return nil if source_type != :ruby method_name_from_first_line(source.lines.first) end # @return [Boolean] Was the method defined outside a source file? def dynamically_defined? !!(source_file and source_file =~ /(\(.*\))|<.*>/) end # @return [Boolean] Whether the method is unbound. def unbound_method? is_a?(::UnboundMethod) end # @return [Boolean] Whether the method is bound. def bound_method? is_a?(::Method) end # @return [Boolean] Whether the method is a singleton method. def singleton_method? wrapped_owner.singleton_class? end # @return [Boolean] Was the method defined within the Pry REPL? def pry_method? source_file == Pry.eval_path end # @return [Array] All known aliases for the method. # @note On Ruby 1.8 this method always returns an empty Array for methods # implemented in C. def aliases owner = @method.owner # Avoid using `to_sym` on {Method#name}, which returns a `String`, because # it won't be garbage collected. name = @method.name alias_list = owner.instance_methods.combination(2).select do |pair| pair.include?(name) && owner.instance_method(pair.first) == owner.instance_method(pair.last) end.flatten alias_list.delete(name) alias_list.map(&:to_s) end # @return [Boolean] Is the method definitely an alias? def alias? name != original_name end # @return [Boolean] def ==(obj) if obj.is_a? Pry::Method obj == @method else @method == obj end end # @param [Class] klass # @return [Boolean] def is_a?(klass) klass == Pry::Method or @method.is_a?(klass) end alias kind_of? is_a? # @param [String, Symbol] method_name # @return [Boolean] def respond_to?(method_name) super or @method.respond_to?(method_name) end # Delegate any unknown calls to the wrapped method. def method_missing(method_name, *args, &block) @method.send(method_name, *args, &block) end private # @return [YARD::CodeObjects::MethodObject] # @raise [CommandError] when the method can't be found or `pry-doc` isn't installed. def pry_doc_info if Pry.config.has_pry_doc Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)" else fail_msg = "Cannot locate this method: #{name}." if mri_18? || mri_19? fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.' end raise CommandError, fail_msg end end # FIXME: a very similar method to this exists on WrappedModule: extract_doc_for_candidate def doc_for_pry_method _, line_num = source_location buffer = "" Pry.line_buffer[0..(line_num - 1)].each do |line| # Add any line that is a valid ruby comment, # but clear as soon as we hit a non comment line. if (line =~ /^\s*#/) || (line =~ /^\s*$/) buffer << line.lstrip else buffer.replace("") end end buffer end # @param [Class, Module] ancestors The ancestors to investigate # @return [Method] The unwrapped super-method def super_using_ancestors(ancestors, times=1) next_owner = self.owner times.times do i = ancestors.index(next_owner) + 1 while ancestors[i] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name)) i += 1 end next_owner = ancestors[i] or return nil end safe_send(next_owner, :instance_method, name) rescue nil end # @param [String] first_ln The first line of a method definition. # @return [String, nil] def method_name_from_first_line(first_ln) return nil if first_ln.strip !~ /^def / tokens = CodeRay.scan(first_ln, :ruby) tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens) tokens.each_cons(2) do |t1, t2| if t2.last == :method || t2.last == :ident && t1 == [".", :operator] return t2.first end end nil end end end pry-0.9.12.6/lib/pry/indent.rb0000644000004100000410000003274112272154172016011 0ustar www-datawww-datarequire 'coderay' class Pry ## # Pry::Indent is a class that can be used to indent a number of lines # containing Ruby code similar as to how IRB does it (but better). The class # works by tokenizing a string using CodeRay and then looping over those # tokens. Based on the tokens in a line of code that line (or the next one) # will be indented or un-indented by correctly. # class Indent include Helpers::BaseHelpers # Raised if {#module_nesting} would not work. class UnparseableNestingError < StandardError; end # @return [String] String containing the spaces to be inserted before the next line. attr_reader :indent_level # @return [Array] The stack of open tokens. attr_reader :stack # The amount of spaces to insert for each indent level. SPACES = ' ' # Hash containing all the tokens that should increase the indentation # level. The keys of this hash are open tokens, the values the matching # tokens that should prevent a line from being indented if they appear on # the same line. OPEN_TOKENS = { 'def' => 'end', 'class' => 'end', 'module' => 'end', 'do' => 'end', 'if' => 'end', 'unless' => 'end', 'while' => 'end', 'until' => 'end', 'for' => 'end', 'case' => 'end', 'begin' => 'end', '[' => ']', '{' => '}', '(' => ')' } # Which tokens can either be open tokens, or appear as modifiers on # a single-line. SINGLELINE_TOKENS = %w(if while until unless rescue) # Which tokens can be followed by an optional "do" keyword. OPTIONAL_DO_TOKENS = %w(for while until) # Collection of token types that should be ignored. Without this list # keywords such as "class" inside strings would cause the code to be # indented incorrectly. # # :pre_constant and :preserved_constant are the CodeRay 0.9.8 and 1.0.0 # classifications of "true", "false", and "nil". IGNORE_TOKENS = [:space, :content, :string, :method, :ident, :constant, :pre_constant, :predefined_constant] # Tokens that indicate the end of a statement (i.e. that, if they appear # directly before an "if" indicates that that if applies to the same line, # not the next line) # # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively # classifications of "super", "next", "return", etc. STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float, :keyword, :delimiter, :reserved] # Collection of tokens that should appear dedented even though they # don't affect the surrounding code. MIDWAY_TOKENS = %w(when else elsif ensure rescue) # Clean the indentation of a fragment of ruby. # # @param [String] str # @return [String] def self.indent(str) new.indent(str) end # Get the module nesting at the given point in the given string. # # NOTE If the line specified contains a method definition, then the nesting # at the start of the method definition is used. Otherwise the nesting from # the end of the line is used. # # @param [String] str The ruby code to analyze # @param [Fixnum] line_number The line number (starting from 1) # @return [Array] def self.nesting_at(str, line_number) indent = new lines = str.split("\n") n = line_number - 1 to_indent = lines[0...n] + (lines[n] || "").split("def").first(1) indent.indent(to_indent.join("\n") + "\n") indent.module_nesting end def initialize reset end # reset internal state def reset @stack = [] @indent_level = '' @heredoc_queue = [] @close_heredocs = {} @string_start = nil @awaiting_class = false @module_nesting = [] self end # Indents a string and returns it. This string can either be a single line # or multiple ones. # # @example # str = <] def module_nesting @module_nesting.map do |(kind, token)| raise UnparseableNestingError, @module_nesting.inspect if token.nil? "#{kind} #{token}" end end # Return a string which, when printed, will rewrite the previous line with # the correct indentation. Mostly useful for fixing 'end'. # # @param [String] prompt The user's prompt # @param [String] code The code the user just typed in. # @param [Fixnum] overhang (0) The number of chars to erase afterwards (i.e., # the difference in length between the old line and the new one). # @return [String] def correct_indentation(prompt, code, overhang=0) prompt = prompt.delete("\001\002") full_line = prompt + code whitespace = ' ' * overhang _, cols = Terminal.screen_size cols = cols.to_i lines = cols != 0 ? (full_line.length / cols + 1) : 1 if Pry::Helpers::BaseHelpers.windows_ansi? move_up = "\e[#{lines}F" move_down = "\e[#{lines}E" else move_up = "\e[#{lines}A\e[0G" move_down = "\e[#{lines}B\e[0G" end "#{move_up}#{prompt}#{colorize_code(code)}#{whitespace}#{move_down}" end end end pry-0.9.12.6/lib/pry/code_object.rb0000644000004100000410000001034012272154172016757 0ustar www-datawww-dataclass Pry class CodeObject module Helpers # we need this helper as some Pry::Method objects can wrap Procs # @return [Boolean] def real_method_object? is_a?(::Method) || is_a?(::UnboundMethod) end def c_method? real_method_object? && source_type == :c end def module_with_yard_docs? is_a?(WrappedModule) && yard_docs? end def command? is_a?(Module) && self <= Pry::Command end end include Pry::Helpers::CommandHelpers class << self def lookup(str, _pry_, options={}) co = new(str, _pry_, options) co.default_lookup || co.method_or_class_lookup || co.command_lookup || co.empty_lookup end end attr_accessor :str attr_accessor :target attr_accessor :pry attr_accessor :super_level def initialize(str, _pry_, options={}) options = { :super => 0, }.merge!(options) @str = str @pry = _pry_ @target = _pry_.current_context @super_level = options[:super] end def command_lookup # TODO: just make it so find_command_by_match_or_listing doesn't # raise? pry.commands.find_command_by_match_or_listing(str) rescue nil end def empty_lookup return nil if str && !str.empty? if internal_binding?(target) mod = target_self.is_a?(Module) ? target_self : target_self.class Pry::WrappedModule(mod) else Pry::Method.from_binding(target) end end # lookup variables and constants and `self` that are not modules def default_lookup # we skip instance methods as we want those to fall through to method_or_class_lookup() if safe_to_evaluate?(str) && !looks_like_an_instance_method?(str) obj = target.eval(str) # restrict to only objects we KNOW for sure support the full API # Do NOT support just any object that responds to source_location if sourcable_object?(obj) Pry::Method(obj) elsif !obj.is_a?(Module) Pry::WrappedModule(obj.class) else nil end end rescue Pry::RescuableException nil end def method_or_class_lookup # we need this here because stupid Pry::Method.from_str() does a # Pry::Method.from_binding when str is nil. # Once we refactor Pry::Method.from_str() so it doesnt lookup # from bindings, we can get rid of this check return nil if str.to_s.empty? obj = if str =~ /::(?:\S+)\Z/ Pry::WrappedModule.from_str(str,target) || Pry::Method.from_str(str, target) else Pry::Method.from_str(str,target) || Pry::WrappedModule.from_str(str, target) end lookup_super(obj, super_level) end private def sourcable_object?(obj) [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) } end # Returns true if `str` looks like a method, i.e Klass#method # We need to consider this case because method lookups should fall # through to the `method_or_class_lookup()` method but a # defined?() on a "Klass#method` string will see the `#` as a # comment and only evaluate the `Klass` part. # @param [String] str # @return [Boolean] Whether the string looks like an instance method. def looks_like_an_instance_method?(str) str =~ /\S#\S/ end # We use this method to decide whether code is safe to eval. Method's are # generally not, but everything else is. # TODO: is just checking != "method" enough?? # TODO: see duplication of this method in Pry::WrappedModule # @param [String] str The string to lookup # @return [Boolean] def safe_to_evaluate?(str) return true if str.strip == "self" kind = target.eval("defined?(#{str})") kind =~ /variable|constant/ end def target_self target.eval('self') end # grab the nth (`super_level`) super of `obj # @param [Object] obj # @param [Fixnum] super_level How far up the super chain to ascend. def lookup_super(obj, super_level) return nil if !obj sup = obj.super(super_level) if !sup raise Pry::CommandError, "No superclass found for #{obj.wrapped}" else sup end end end end pry-0.9.12.6/lib/pry/completion.rb0000644000004100000410000002335212272154172016677 0ustar www-datawww-data# taken from irb class Pry module BondCompleter def self.build_completion_proc(target, pry=nil, commands=[""]) Pry.require_readline # If we're using libedit or bond gem not installed, don't use Bond. if Readline::VERSION =~ /editline/i || !defined?(Bond) Pry.config.completer = InputCompleter return InputCompleter.build_completion_proc(target, pry, commands) end if !@started @started = true start end Pry.current[:pry] = pry proc{ |*a| Bond.agent.call(*a) } end def self.start Bond.start(:eval_binding => lambda{ Pry.current[:pry].current_context }) Bond.complete(:on => /\A/) do |input| Pry.commands.complete(input.line, :pry_instance => Pry.current[:pry], :target => Pry.current[:pry].current_context, :command_set => Pry.current[:pry].commands) end end end # Implements tab completion for Readline in Pry module InputCompleter ReservedWords = [ "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" ] Operators = [ "%", "&", "*", "**", "+", "-", "/", "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", "[]", "[]=", "^", "!", "!=", "!~" ] # If we haven't configured Readline for completion yet, do it now. # @private def self.initialize_readline Pry.require_readline return if @initialized_readline if Readline.respond_to?("basic_word_break_characters=") Readline.basic_word_break_characters = " \t\n\"\\'`><=;|&{(" end Readline.completion_append_character = nil @initialized_readline = true end # Return a new completion proc for use by Readline. # @param [Binding] target The current binding context. # @param [Array] commands The array of Pry commands. def self.build_completion_proc(target, pry=nil, commands=[""]) initialize_readline proc do |input| # if there are multiple contexts e.g. cd 1/2/3 # get new target for 1/2 and find candidates for 3 path, input = build_path(input) # We silence warnings here or Ruby 1.8 cries about "multiple values for # block 0 for 1". Helpers::BaseHelpers.silence_warnings do unless path.call.empty? target = begin ctx = Helpers::BaseHelpers.context_from_object_path(path.call, pry) ctx.first rescue Pry::CommandError [] end target = target.last end end begin bind = target case input # Complete stdlib symbols when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp receiver = $1 message = Regexp.quote($2) candidates = Regexp.instance_methods.collect(&:to_s) select_message(path, receiver, message, candidates) when /^([^\]]*\])\.([^.]*)$/ # Array receiver = $1 message = Regexp.quote($2) candidates = Array.instance_methods.collect(&:to_s) select_message(path, receiver, message, candidates) when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash receiver = $1 message = Regexp.quote($2) candidates = Proc.instance_methods.collect(&:to_s) candidates |= Hash.instance_methods.collect(&:to_s) select_message(path, receiver, message, candidates) when /^(:[^:.]*)$/ # Symbol if Symbol.respond_to?(:all_symbols) sym = Regexp.quote($1) candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name} candidates.grep(/^#{sym}/) else [] end when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods receiver = $1 candidates = Object.constants.collect(&:to_s) candidates.grep(/^#{receiver}/).collect{|e| "::" + e} # Complete target symbols when /^([A-Z][A-Za-z0-9]*)$/ # Constant message = $1 begin context = target.eval("self") context = context.class unless context.respond_to? :constants candidates = context.constants.collect(&:to_s) rescue candidates = [] end candidates = candidates.grep(/^#{message}/).collect(&path) when /^([A-Z].*)::([^:.]*)$/ # Constant or class methods receiver = $1 message = Regexp.quote($2) begin candidates = eval("#{receiver}.constants.collect(&:to_s)", bind) candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind) rescue RescuableException candidates = [] end candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e} when /^(:[^:.]+)\.([^.]*)$/ # Symbol receiver = $1 message = Regexp.quote($2) candidates = Symbol.instance_methods.collect(&:to_s) select_message(path, receiver, message, candidates) when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/ # Numeric receiver = $1 message = Regexp.quote($5) begin candidates = eval(receiver, bind).methods.collect(&:to_s) rescue RescuableException candidates = [] end select_message(path, receiver, message, candidates) when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/# # Numeric(0xFFFF) receiver = $1 message = Regexp.quote($2) begin candidates = eval(receiver, bind).methods.collect(&:to_s) rescue RescuableException candidates = [] end select_message(path, receiver, message, candidates) when /^(\$[^.]*)$/ # Global variables regmessage = Regexp.new(Regexp.quote($1)) candidates = global_variables.collect(&:to_s).grep(regmessage) when /^([^."].*)\.([^.]*)$/ # Variable receiver = $1 message = Regexp.quote($2) gv = eval("global_variables", bind).collect(&:to_s) lv = eval("local_variables", bind).collect(&:to_s) cv = eval("self.class.constants", bind).collect(&:to_s) if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver # foo.func and foo is local var. OR # Foo::Bar.func begin candidates = eval("#{receiver}.methods", bind).collect(&:to_s) rescue RescuableException candidates = [] end else # func1.func2 candidates = [] ObjectSpace.each_object(Module){|m| begin name = m.name.to_s rescue RescuableException name = "" end next if name != "IRB::Context" and /^(IRB|SLex|RubyLex|RubyToken)/ =~ name # jruby doesn't always provide #instance_methods() on each # object. if m.respond_to?(:instance_methods) candidates.concat m.instance_methods(false).collect(&:to_s) end } candidates.sort! candidates.uniq! end select_message(path, receiver, message, candidates) when /^\.([^.]*)$/ # Unknown(maybe String) receiver = "" message = Regexp.quote($1) candidates = String.instance_methods(true).collect(&:to_s) select_message(path, receiver, message, candidates) else candidates = eval( "methods | private_methods | local_variables | " \ "self.class.constants | instance_variables", bind ).collect(&:to_s) if eval("respond_to?(:class_variables)", bind) candidates += eval("class_variables", bind).collect(&:to_s) end candidates = (candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/) candidates.collect(&path) end rescue RescuableException [] end end end def self.select_message(path, receiver, message, candidates) candidates.grep(/^#{message}/).collect { |e| case e when /^[a-zA-Z_]/ path.call(receiver + "." + e) when /^[0-9]/ when *Operators #receiver + " " + e end }.compact end # build_path seperates the input into two parts: path and input. # input is the partial string that should be completed # path is a proc that takes an input and builds a full path. def self.build_path(input) # check to see if the input is a regex return proc {|input| input.to_s }, input if input[/\/\./] trailing_slash = input.end_with?('/') contexts = input.chomp('/').split(/\//) input = contexts[-1] path = Proc.new do |input| p = contexts[0..-2].push(input).join('/') p += '/' if trailing_slash && !input.nil? p end return path, input end end end pry-0.9.12.6/lib/pry/hooks.rb0000644000004100000410000002040712272154172015647 0ustar www-datawww-dataclass Pry # Implements a hooks system for Pry. A hook is a callable that is # associated with an event. A number of events are currently # provided by Pry, these include: `:when_started`, `:before_session`, `:after_session`. # A hook must have a name, and is connected with an event by the # `Pry::Hooks#add_hook` method. # @example Adding a hook for the `:before_session` event. # Pry.config.hooks.add_hook(:before_session, :say_hi) do # puts "hello" # end class Hooks # Converts a hash to a `Pry::Hooks` instance. All hooks defined # this way are anonymous. This functionality is primarily to # provide backwards-compatibility with the old hash-based hook # system in Pry versions < 0.9.8 # @param [Hash] hash The hash to convert to `Pry::Hooks`. # @return [Pry::Hooks] The resulting `Pry::Hooks` instance. def self.from_hash(hash) instance = new hash.each do |k, v| instance.add_hook(k, nil, v) end instance end def initialize @hooks = {} end # Ensure that duplicates have their @hooks object def initialize_copy(orig) hooks_dup = @hooks.dup @hooks.each do |k, v| hooks_dup[k] = v.dup end @hooks = hooks_dup end def hooks @hooks end protected :hooks def errors @errors ||= [] end # FIXME: # This is a hack to alert people of the new API. def [](event_name) warn "`Pry.hooks[]` is deprecated! Please use the new `Pry::Hooks` API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks" get_hook(event_name, nil) end # FIXME: # This is a hack to alert people of the new API. def []=(event_name, callable) warn "`Pry.hooks[]=` is deprecated! Please use the new `Pry::Hooks` API! http://rubydoc.info/github/pry/pry/master/Pry/Hooks" add_hook(event_name, nil, callable) end # Destructively merge the contents of two `Pry:Hooks` instances. # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge # @return [Pry:Hooks] Returns the receiver. # @example # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # Pry::Hooks.new.merge!(hooks) def merge!(other) @hooks.merge!(other.dup.hooks) do |key, v1, v2| merge_arrays(v1, v2) end self end def merge_arrays(array1, array2) uniq_keeping_last(array1 + array2, &:first) end private :merge_arrays def uniq_keeping_last(input, &block) hash, output = {}, [] input.reverse.each{ |i| hash[block[i]] ||= (output.unshift i) } output end private :uniq_keeping_last # Return a new `Pry::Hooks` instance containing a merge of the contents of two `Pry:Hooks` instances, # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge # @return [Pry::Hooks] The new hash. # @example # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # Pry::Hooks.new.merge(hooks) def merge(other) self.dup.tap do |v| v.merge!(other) end end # Add a new hook to be executed for the `name` even. # @param [Symbol] event_name The name of the event. # @param [Symbol] hook_name The name of the hook. # @param [#call] callable The callable. # @yield The block to use as the callable (if `callable` parameter not provided) # @return [Pry:Hooks] Returns the receiver. # @example # Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } def add_hook(event_name, hook_name, callable=nil, &block) @hooks[event_name] ||= [] # do not allow duplicates, but allow multiple `nil` hooks # (anonymous hooks) if hook_exists?(event_name, hook_name) && !hook_name.nil? raise ArgumentError, "Hook with name '#{hook_name}' already defined!" end if !block && !callable raise ArgumentError, "Must provide a block or callable." end # ensure we only have one anonymous hook @hooks[event_name].delete_if { |h, k| h.nil? } if hook_name.nil? if block @hooks[event_name] << [hook_name, block] elsif callable @hooks[event_name] << [hook_name, callable] end self end # Execute the list of hooks for the `event_name` event. # @param [Symbol] event_name The name of the event. # @param [Array] args The arguments to pass to each hook function. # @return [Object] The return value of the last executed hook. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.exec_hook(:before_session) #=> OUTPUT: "hi!" def exec_hook(event_name, *args, &block) @hooks[event_name] ||= [] # silence warnings to get rid of 1.8's "warning: multiple values # for a block parameter" warnings Pry::Helpers::BaseHelpers.silence_warnings do @hooks[event_name].map do |hook_name, callable| begin callable.call(*args, &block) rescue RescuableException => e errors << e e end end.last end end # Return the number of hook functions registered for the `event_name` event. # @param [Symbol] event_name The name of the event. # @return [Fixnum] The number of hook functions for `event_name`. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.count(:before_session) #=> 1 def hook_count(event_name) @hooks[event_name] ||= [] @hooks[event_name].size end # Return a specific hook for a given event. # @param [Symbol] event_name The name of the event. # @param [Symbol] hook_name The name of the hook # @return [#call] The requested hook. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.get_hook(:before_session, :say_hi).call #=> "hi!" def get_hook(event_name, hook_name) @hooks[event_name] ||= [] hook = @hooks[event_name].find { |current_hook_name, callable| current_hook_name == hook_name } hook.last if hook end # Return the hash of hook names / hook functions for a # given event. (Note that modifying the returned hash does not # alter the hooks, use add_hook/delete_hook for that). # @param [Symbol] event_name The name of the event. # @return [Hash] The hash of hook names / hook functions. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.get_hooks(:before_session) #=> {:say_hi=>#} def get_hooks(event_name) @hooks[event_name] ||= [] Hash[@hooks[event_name]] end # Delete a hook for an event. # @param [Symbol] event_name The name of the event. # @param [Symbol] hook_name The name of the hook. # to delete. # @return [#call] The deleted hook. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.delete_hook(:before_session, :say_hi) def delete_hook(event_name, hook_name) @hooks[event_name] ||= [] deleted_callable = nil @hooks[event_name].delete_if do |current_hook_name, callable| if current_hook_name == hook_name deleted_callable = callable true else false end end deleted_callable end # Clear all hooks functions for a given event. # @param [String] event_name The name of the event. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.delete_hook(:before_session) def delete_hooks(event_name) @hooks[event_name] = [] end alias_method :clear, :delete_hooks # Remove all events and hooks, clearing out the Pry::Hooks # instance completely. # @example # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } # my_hooks.clear_all def clear_all @hooks = {} end # @param [Symbol] event_name Name of the event. # @param [Symbol] hook_name Name of the hook. # @return [Boolean] Whether the hook by the name `hook_name` def hook_exists?(event_name, hook_name) !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name }) end end end pry-0.9.12.6/lib/pry/helpers/0000755000004100000410000000000012272154172015636 5ustar www-datawww-datapry-0.9.12.6/lib/pry/helpers/text.rb0000644000004100000410000000565112272154172017156 0ustar www-datawww-dataclass Pry module Helpers # The methods defined on {Text} are available to custom commands via {Pry::Command#text}. module Text COLORS = { "black" => 0, "red" => 1, "green" => 2, "yellow" => 3, "blue" => 4, "purple" => 5, "magenta" => 5, "cyan" => 6, "white" => 7 } class << self COLORS.each_pair do |color, value| define_method color do |text| Pry.color ? "\033[0;#{30+value}m#{text}\033[0m" : text.to_s end define_method "bright_#{color}" do |text| Pry.color ? "\033[1;#{30+value}m#{text}\033[0m" : text.to_s end end # Remove any color codes from _text_. # # @param [String, #to_s] text # @return [String] _text_ stripped of any color codes. def strip_color(text) text.to_s.gsub(/\e\[.*?(\d)+m/ , '') end # Returns _text_ as bold text for use on a terminal. # _Pry.color_ must be true for this method to perform any transformations. # # @param [String, #to_s] text # @return [String] _text_ def bold(text) Pry.color ? "\e[1m#{text}\e[0m" : text.to_s end # Returns `text` in the default foreground colour. # Use this instead of "black" or "white" when you mean absence of colour. # # @param [String, #to_s] text # @return [String] def default(text) text.to_s end alias_method :bright_default, :bold # Executes the block with `Pry.color` set to false. # @yield # @return [void] def no_color(&block) boolean = Pry.config.color Pry.config.color = false yield ensure Pry.config.color = boolean end # Executes the block with `Pry.config.pager` set to false. # @yield # @return [void] def no_pager(&block) boolean = Pry.config.pager Pry.config.pager = false yield ensure Pry.config.pager = boolean end # Returns _text_ in a numbered list, beginning at _offset_. # # @param [#each_line] text # @param [Fixnum] offset # @return [String] def with_line_numbers(text, offset, color=:blue) lines = text.each_line.to_a max_width = (offset + lines.count).to_s.length lines.each_with_index.map do |line, index| adjusted_index = (index + offset).to_s.rjust(max_width) "#{self.send(color, adjusted_index)}: #{line}" end.join end # Returns _text_ indented by _chars_ spaces. # # @param [String] text # @param [Fixnum] chars def indent(text, chars) text.lines.map { |l| "#{' ' * chars}#{l}" }.join end end end end end pry-0.9.12.6/lib/pry/helpers/table.rb0000644000004100000410000000545512272154172017263 0ustar www-datawww-dataclass Pry module Helpers def self.tablify_or_one_line(heading, things) plain_heading = Pry::Helpers::Text.strip_color(heading) attempt = Table.new(things, :column_count => things.size) if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2) "#{heading}: #{attempt}\n" else "#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n" end end def self.tablify_to_screen_width(things, options = {}) things = things.compact if indent = options[:indent] usable_width = Terminal.width! - indent.size tablify(things, usable_width).to_s.gsub(/^/, indent) else tablify(things, Terminal.width!).to_s end end def self.tablify(things, line_length) table = Table.new(things, :column_count => things.size) table.column_count -= 1 until 1 == table.column_count or table.fits_on_line?(line_length) table end class Table attr_reader :items, :column_count def initialize items, args = {} @column_count = args[:column_count] self.items = items end def to_s rows_to_s.join("\n") end def rows_to_s style = :color_on widths = columns.map{|e| _max_width(e)} @rows_without_colors.map do |r| padded = [] r.each_with_index do |e,i| next unless e item = e.ljust(widths[i]) item.sub! e, _recall_color_for(e) if :color_on == style padded << item end padded.join(Pry.config.ls.separator) end end def items= items @items = items _rebuild_colorless_cache _recolumn items end def column_count= n @column_count = n _recolumn end def fits_on_line? line_length _max_width(rows_to_s :no_color) <= line_length end def columns @rows_without_colors.transpose end def ==(other); items == other.to_a end def to_a; items.to_a end private def _max_width(things) things.compact.map(&:size).max || 0 end def _rebuild_colorless_cache @colorless_cache = {} @plain_items = [] items.map do |e| plain = Pry::Helpers::Text.strip_color(e) @colorless_cache[plain] = e @plain_items << plain end end def _recolumn @rows_without_colors = [] return if items.size.zero? row_count = (items.size.to_f/column_count).ceil row_count.times do |i| row_indices = (0...column_count).map{|e| row_count*e+i} @rows_without_colors << row_indices.map{|e| @plain_items[e]} end end def _recall_color_for thing @colorless_cache[thing] end end end end pry-0.9.12.6/lib/pry/helpers/base_helpers.rb0000644000004100000410000001371212272154172020623 0ustar www-datawww-dataclass Pry module Helpers module BaseHelpers module_function def silence_warnings old_verbose = $VERBOSE $VERBOSE = nil begin yield ensure $VERBOSE = old_verbose end end # Acts like send but ignores any methods defined below Object or Class in the # inheritance hierarchy. # This is required to introspect methods on objects like Net::HTTP::Get that # have overridden the `method` method. def safe_send(obj, method, *args, &block) (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block) end public :safe_send def find_command(name, set = Pry::Commands) command_match = set.find do |_, command| (listing = command.options[:listing]) == name && listing != nil end command_match.last if command_match end def not_a_real_file?(file) file =~ /(\(.*\))|<.*>/ || file =~ /__unknown__/ || file == "" || file == "-e" end def command_dependencies_met?(options) return true if !options[:requires_gem] Array(options[:requires_gem]).all? do |g| Rubygem.installed?(g) end end def set_file_and_dir_locals(file_name, _pry_=_pry_(), target=target()) return if !target or !file_name _pry_.last_file = File.expand_path(file_name) _pry_.inject_local("_file_", _pry_.last_file, target) _pry_.last_dir = File.dirname(_pry_.last_file) _pry_.inject_local("_dir_", _pry_.last_dir, target) end def use_ansi_codes? windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb" end def colorize_code(code) if Pry.color CodeRay.scan(code, :ruby).term else code end end def highlight(string, regexp, highlight_color=:bright_yellow) string.gsub(regexp) { |match| "<#{highlight_color}>#{match}" } end # formatting def heading(text) text = "#{text}\n--" Pry.color ? "\e[1m#{text}\e[0m": text end # have fun on the Windows platform. def windows? RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ end # are we able to use ansi on windows? def windows_ansi? defined?(Win32::Console) || ENV['ANSICON'] end def jruby? RbConfig::CONFIG['ruby_install_name'] == 'jruby' end def jruby_19? RbConfig::CONFIG['ruby_install_name'] == 'jruby' && RbConfig::CONFIG['ruby_version'] == '1.9' end def rbx? RbConfig::CONFIG['ruby_install_name'] == 'rbx' end def mri_18? RUBY_VERSION =~ /1.8/ && RbConfig::CONFIG['ruby_install_name'] == 'ruby' end def mri_19? RUBY_VERSION =~ /1.9/ && RbConfig::CONFIG['ruby_install_name'] == 'ruby' end # Try to use `less` for paging, if it fails then use # simple_pager. Also do not page if Pry.pager is falsey def stagger_output(text, out = nil) out ||= case when respond_to?(:output) # Mixin. output when Pry.respond_to?(:output) # Parent. Pry.output else # Sys. $stdout end if text.lines.count < Pry::Pager.page_size || !Pry.pager out.puts text else Pry::Pager.page(text) end rescue Errno::ENOENT Pry::Pager.page(text, :simple) rescue Errno::EPIPE end # @param [String] arg_string The object path expressed as a string. # @param [Pry] _pry_ The relevant Pry instance. # @param [Array] old_stack The state of the old binding stack # @return [Array, Array>] An array # containing two elements: The new `binding_stack` and the old `binding_stack`. def context_from_object_path(arg_string, _pry_=nil, old_stack=[]) # Extract command arguments. Delete blank arguments like " ", but # don't delete empty strings like "". path = arg_string.split(/\//).delete_if { |a| a =~ /\A\s+\z/ } stack = _pry_.binding_stack.dup state_old_stack = old_stack # Special case when we only get a single "/", return to root. if path.empty? state_old_stack = stack.dup unless old_stack.empty? stack = [stack.first] end path.each_with_index do |context, i| begin case context.chomp when "" state_old_stack = stack.dup stack = [stack.first] when "::" state_old_stack = stack.dup stack.push(TOPLEVEL_BINDING) when "." next when ".." unless stack.size == 1 # Don't rewrite old_stack if we're in complex expression # (e.g.: `cd 1/2/3/../4). state_old_stack = stack.dup if path.first == ".." stack.pop end when "-" unless old_stack.empty? # Interchange current stack and old stack with each other. stack, state_old_stack = state_old_stack, stack end else state_old_stack = stack.dup if i == 0 stack.push(Pry.binding_for(stack.last.eval(context))) end rescue RescuableException => e # Restore old stack to its initial values. state_old_stack = old_stack msg = [ "Bad object path: #{arg_string}.", "Failed trying to resolve: #{context}.", e.inspect ].join(' ') CommandError.new(msg).tap do |err| err.set_backtrace e.backtrace raise err end end end return stack, state_old_stack end end end end pry-0.9.12.6/lib/pry/helpers/options_helpers.rb0000644000004100000410000000212712272154172021402 0ustar www-datawww-dataclass Pry module Helpers module OptionsHelpers module_function # Add method options to the Slop instance def method_options(opt) @method_target = target opt.on :M, "instance-methods", "Operate on instance methods." opt.on :m, :methods, "Operate on methods." opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors.", :as => :count opt.on :c, :context, "Select object context to run under.", :argument => true do |context| @method_target = Pry.binding_for(target.eval(context)) end end # Get the method object parsed by the slop instance def method_object @method_object ||= get_method_or_raise(args.empty? ? nil : args.join(" "), @method_target, :super => opts[:super], :instance => opts.present?(:'instance-methods') && !opts.present?(:'methods'), :methods => opts.present?(:'methods') && !opts.present?(:'instance-methods') ) end end end end pry-0.9.12.6/lib/pry/helpers/documentation_helpers.rb0000644000004100000410000000475512272154172022571 0ustar www-datawww-dataclass Pry module Helpers # This class contains methods useful for extracting # documentation from methods and classes. module DocumentationHelpers module_function def process_rdoc(comment) return comment unless Pry.color comment = comment.dup comment.gsub(/(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }. gsub(/(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }. gsub(/(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }. gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }. gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }. gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" } end def process_yardoc_tag(comment, tag) in_tag_block = nil comment.lines.map do |v| if in_tag_block && v !~ /^\S/ Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v) elsif in_tag_block in_tag_block = false v else in_tag_block = true if v =~ /^@#{tag}/ v end end.join end def process_yardoc(comment) yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer", "deprecate", "example", "raise"] (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }. gsub(/^@(#{yard_tags.join("|")})/) { Pry.color ? "\e[33m#{$1}\e[0m": $1 } end def process_comment_markup(comment) process_yardoc process_rdoc(comment) end # @param [String] code # @return [String] def strip_comments_from_c_code(code) code.sub(/\A\s*\/\*.*?\*\/\s*/m, '') end # Given a string that makes up a comment in a source-code file parse out the content # that the user is intended to read. (i.e. without leading indentation, #-characters # or shebangs) # # @param [String] comment # @return [String] def get_comment_content(comment) comment = comment.dup # Remove #!/usr/bin/ruby comment.gsub!(/\A\#!.*$/, '') # Remove leading empty comment lines comment.gsub!(/\A\#+?$/, '') comment.gsub!(/^\s*#/, '') strip_leading_whitespace(comment) end # @param [String] text # @return [String] def strip_leading_whitespace(text) Pry::Helpers::CommandHelpers.unindent(text) end end end end pry-0.9.12.6/lib/pry/helpers/command_helpers.rb0000644000004100000410000001147412272154172021332 0ustar www-datawww-dataclass Pry module Helpers module CommandHelpers include OptionsHelpers module_function # Open a temp file and yield it to the block, closing it after # @return [String] The path of the temp file def temp_file(ext='.rb') file = Tempfile.new(['pry', ext]) yield file ensure file.close(true) if file end def render_output(str, opts={}) if opts[:flood] output.puts str else stagger_output str end end def internal_binding?(target) m = target.eval("::Kernel.__method__").to_s # class_eval is here because of http://jira.codehaus.org/browse/JRUBY-6753 ["__binding__", "__pry__", "class_eval"].include?(m) end def get_method_or_raise(name, target, opts={}, omit_help=false) meth = Pry::Method.from_str(name, target, opts) if name && !meth command_error("The method '#{name}' could not be found.", omit_help, MethodNotFound) end (opts[:super] || 0).times do if meth.super meth = meth.super else command_error("'#{meth.name_with_owner}' has no super method.", omit_help, MethodNotFound) end end if !meth || (!name && internal_binding?(target)) command_error("No method name given, and context is not a method.", omit_help, MethodNotFound) end set_file_and_dir_locals(meth.source_file) meth end def command_error(message, omit_help, klass=CommandError) message += " Type `#{command_name} --help` for help." unless omit_help raise klass, message end # Remove any common leading whitespace from every line in `text`. # # This can be used to make a HEREDOC line up with the left margin, without # sacrificing the indentation level of the source code. # # e.g. # opt.banner unindent <<-USAGE # Lorem ipsum dolor sit amet, consectetur adipisicing elit, # sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. # "Ut enim ad minim veniam." # USAGE # # Heavily based on textwrap.dedent from Python, which is: # Copyright (C) 1999-2001 Gregory P. Ward. # Copyright (C) 2002, 2003 Python Software Foundation. # Written by Greg Ward # # Licensed under # From # # @param [String] text The text from which to remove indentation # @return [String] The text with indentation stripped. def unindent(text, left_padding = 0) # Empty blank lines text = text.sub(/^[ \t]+$/, '') # Find the longest common whitespace to all indented lines # Ignore lines containing just -- or ++ as these seem to be used by # comment authors as delimeters. margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent| if next_indent.start_with?(current_margin) current_margin elsif current_margin.start_with?(next_indent) next_indent else "" end end text.gsub(/^#{margin}/, ' ' * left_padding) end # Restrict a string to the given range of lines (1-indexed) # @param [String] content The string. # @param [Range, Fixnum] lines The line(s) to restrict it to. # @return [String] The resulting string. def restrict_to_lines(content, lines) line_range = one_index_range_or_number(lines) Array(content.lines.to_a[line_range]).join end def one_index_number(line_number) if line_number > 0 line_number - 1 else line_number end end # convert a 1-index range to a 0-indexed one def one_index_range(range) Range.new(one_index_number(range.begin), one_index_number(range.end)) end def one_index_range_or_number(range_or_number) case range_or_number when Range one_index_range(range_or_number) else one_index_number(range_or_number) end end def absolute_index_number(line_number, array_length) if line_number >= 0 line_number else [array_length + line_number, 0].max end end def absolute_index_range(range_or_number, array_length) case range_or_number when Range a = absolute_index_number(range_or_number.begin, array_length) b = absolute_index_number(range_or_number.end, array_length) else a = b = absolute_index_number(range_or_number, array_length) end Range.new(a, b) end end end end pry-0.9.12.6/lib/pry/wrapped_module.rb0000644000004100000410000003170412272154172017535 0ustar www-datawww-datarequire 'pry/module_candidate' class Pry class << self # If the given object is a `Pry::WrappedModule`, return it unaltered. If it's # anything else, return it wrapped in a `Pry::WrappedModule` instance. def WrappedModule(obj) if obj.is_a? Pry::WrappedModule obj else Pry::WrappedModule.new(obj) end end end class WrappedModule include Helpers::BaseHelpers include CodeObject::Helpers attr_reader :wrapped # Convert a string to a module. # # @param [String] mod_name # @param [Binding] target The binding where the lookup takes place. # @return [Module, nil] The module or `nil` (if conversion failed). # @example # Pry::WrappedModule.from_str("Pry::Code") def self.from_str(mod_name, target=TOPLEVEL_BINDING) if safe_to_evaluate?(mod_name, target) Pry::WrappedModule.new(target.eval(mod_name)) else nil end rescue RescuableException nil end class << self private # We use this method to decide whether code is safe to eval. Method's are # generally not, but everything else is. # TODO: is just checking != "method" enough?? # TODO: see duplication of this method in Pry::CodeObject # @param [String] str The string to lookup. # @param [Binding] target Where the lookup takes place. # @return [Boolean] def safe_to_evaluate?(str, target) return true if str.strip == "self" kind = target.eval("defined?(#{str})") kind =~ /variable|constant/ end end # @raise [ArgumentError] if the argument is not a `Module` # @param [Module] mod def initialize(mod) raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod @wrapped = mod @memoized_candidates = [] @host_file_lines = nil @source = nil @source_location = nil @doc = nil end # Returns an array of the names of the constants accessible in the wrapped # module. This provides a consistent interface between 1.8 and 1.9 and also # avoids the problem of accidentally calling the singleton method # `Module.constants`. # @param [Boolean] inherit (true) Include the names of constants from # included modules? def constants(inherit = true) method = Module.instance_method(:constants).bind(@wrapped) # If we're on 1.8, we have to manually remove ancestors' constants. If # we're on 1.9, though, it's better to use the built-in `inherit` param, # since it doesn't do things like incorrectly remove Pry::Config. if method.arity == 0 consts = method.call if !inherit consts -= (@wrapped.ancestors - [@wrapped]).map(&:constants).flatten end else consts = method.call(inherit) end consts end # The prefix that would appear before methods defined on this class. # # i.e. the "String." or "String#" in String.new and String#initialize. # # @return String def method_prefix if singleton_class? if Module === singleton_instance "#{WrappedModule.new(singleton_instance).nonblank_name}." else "self." end else "#{nonblank_name}#" end end # The name of the Module if it has one, otherwise #. # # @return [String] def nonblank_name if name.to_s == "" wrapped.inspect else name end end # Is this a singleton class? # @return [Boolean] def singleton_class? if wrapped.respond_to?(:singleton_class?) wrapped.singleton_class? else wrapped != wrapped.ancestors.first end end # Is this strictly a module? (does not match classes) # @return [Boolean] def module? wrapped.instance_of?(Module) end # Is this strictly a class? # @return [Boolean] def class? wrapped.instance_of?(Class) end # Get the instance associated with this singleton class. # # @raise ArgumentError: tried to get instance of non singleton class # # @return [Object] def singleton_instance raise ArgumentError, "tried to get instance of non singleton class" unless singleton_class? if Helpers::BaseHelpers.jruby? wrapped.to_java.attached else @singleton_instance ||= ObjectSpace.each_object(wrapped).detect{ |x| (class << x; self; end) == wrapped } end end # Forward method invocations to the wrapped module def method_missing(method_name, *args, &block) wrapped.send(method_name, *args, &block) end def respond_to?(method_name) super || wrapped.respond_to?(method_name) end # Retrieve the source location of a module. Return value is in same # format as Method#source_location. If the source location # cannot be found this method returns `nil`. # # @param [Module] mod The module (or class). # @return [Array, nil] The source location of the # module (or class), or `nil` if no source location found. def source_location @source_location ||= primary_candidate.source_location rescue Pry::RescuableException nil end # @return [String, nil] The associated file for the module (i.e # the primary candidate: highest ranked monkeypatch). def file Array(source_location).first end alias_method :source_file, :file # @return [Fixnum, nil] The associated line for the module (i.e # the primary candidate: highest ranked monkeypatch). def line Array(source_location).last end alias_method :source_line, :line # Returns documentation for the module. # This documentation is for the primary candidate, if # you would like documentation for other candidates use # `WrappedModule#candidate` to select the candidate you're # interested in. # @raise [Pry::CommandError] If documentation cannot be found. # @return [String] The documentation for the module. def doc @doc ||= primary_candidate.doc end # Returns the source for the module. # This source is for the primary candidate, if # you would like source for other candidates use # `WrappedModule#candidate` to select the candidate you're # interested in. # @raise [Pry::CommandError] If source cannot be found. # @return [String] The source for the module. def source @source ||= primary_candidate.source end # @return [String] Return the associated file for the # module from YARD, if one exists. def yard_file YARD::Registry.at(name).file if yard_docs? end # @return [Fixnum] Return the associated line for the # module from YARD, if one exists. def yard_line YARD::Registry.at(name).line if yard_docs? end # @return [String] Return the YARD docs for this module. def yard_doc YARD::Registry.at(name).docstring.to_s if yard_docs? end # Return a candidate for this module of specified rank. A `rank` # of 0 is equivalent to the 'primary candidate', which is the # module definition with the highest number of methods. A `rank` # of 1 is the module definition with the second highest number of # methods, and so on. Module candidates are necessary as modules # can be reopened multiple times and in multiple places in Ruby, # the candidate API gives you access to the module definition # representing each of those reopenings. # @raise [Pry::CommandError] If the `rank` is out of range. That # is greater than `number_of_candidates - 1`. # @param [Fixnum] rank # @return [Pry::WrappedModule::Candidate] def candidate(rank) @memoized_candidates[rank] ||= Candidate.new(self, rank) end # @return [Fixnum] The number of candidate definitions for the # current module. def number_of_candidates method_candidates.count end # @note On JRuby 1.9 and higher, in certain conditions, this method chucks # away its ability to be quick (when there are lots of monkey patches, # like in Rails). However, it should be efficient enough on other rubies. # @see https://github.com/jruby/jruby/issues/525 # @return [Enumerator, Array] on JRuby 1.9 and higher returns Array, on # other rubies returns Enumerator def candidates enum = generator.new do |y| (0...number_of_candidates).each do |num| y.yield candidate(num) end end Pry::Helpers::BaseHelpers.jruby_19? ? enum.to_a : enum end # @return [Boolean] Whether YARD docs are available for this module. def yard_docs? !!(defined?(YARD) && YARD::Registry.at(name)) end # @param [Fixnum] times How far to travel up the ancestor chain. # @return [Pry::WrappedModule, nil] The wrapped module that is the # superclass. # When `self` is a `Module` then return the # nth ancestor, otherwise (in the case of classes) return the # nth ancestor that is a class. def super(times=1) return self if times.zero? if wrapped.is_a?(Class) sup = ancestors.select { |v| v.is_a?(Class) }[times] else sup = ancestors[times] end Pry::WrappedModule(sup) if sup end private # Ruby 1.8 doesn't support `Enumerator` (it's called Generator instead) # # @return [Object] Return the appropriate generator class. def generator @generator ||= if defined?(Enumerator) Enumerator else require 'generator' Generator end end # @return [Pry::WrappedModule::Candidate] The candidate of rank 0, # that is the 'monkey patch' of this module with the highest # number of methods. It is considered the 'canonical' definition # for the module. def primary_candidate @primary_candidate ||= candidate(0) end # @return [Array>] The array of `Pry::Method` objects, # there are two associated with each candidate. The first is the 'base # method' for a candidate and it serves as the start point for # the search in uncovering the module definition. The second is # the last method defined for that candidate and it is used to # speed up source code extraction. def method_candidates @method_candidates ||= all_source_locations_by_popularity.map do |group| methods_sorted_by_source_line = group.last.sort_by(&:source_line) [methods_sorted_by_source_line.first, methods_sorted_by_source_line.last] end end # A helper method. def all_source_locations_by_popularity return @all_source_locations_by_popularity if @all_source_locations_by_popularity ims = all_relevant_methods_for(wrapped) @all_source_locations_by_popularity = ims.group_by { |v| Array(v.source_location).first }. sort_by { |k, v| -v.size } end # We only want methods that have a non-nil `source_location`. We also # skip some spooky internal methods. # (i.e we skip `__class_init__` because it's an odd rbx specific thing that causes tests to fail.) # @return [Array] def all_relevant_methods_for(mod) all_methods_for(mod).select(&:source_location). reject{ |x| x.name == '__class_init__' || method_defined_by_forwardable_module?(x) } end # Return all methods (instance methods and class methods) for a # given module. # @return [Array] def all_methods_for(mod) all_from_common(mod, :instance_method) + all_from_common(mod, :method) end # FIXME: a variant of this method is also found in Pry::Method def all_from_common(mod, method_type) %w(public protected private).map do |visibility| safe_send(mod, :"#{visibility}_#{method_type}s", false).select do |method_name| if method_type == :method safe_send(mod, method_type, method_name).owner == class << mod; self; end else safe_send(mod, method_type, method_name).owner == mod end end.map do |method_name| Pry::Method.new(safe_send(mod, method_type, method_name), :visibility => visibility.to_sym) end end.flatten end # Detect methods that are defined with `def_delegator` from the Forwardable # module. We want to reject these methods as they screw up module # extraction since the `source_location` for such methods points at forwardable.rb # TODO: make this more robust as valid user-defined files called # forwardable.rb are also skipped. def method_defined_by_forwardable_module?(method) method.source_location.first =~ /forwardable\.rb/ end # memoized lines for file def lines_for_file(file) @lines_for_file ||= {} if file == Pry.eval_path @lines_for_file[file] ||= Pry.line_buffer.drop(1) else @lines_for_file[file] ||= File.readlines(file) end end end end pry-0.9.12.6/lib/pry/method/0000755000004100000410000000000012272154172015454 5ustar www-datawww-datapry-0.9.12.6/lib/pry/method/disowned.rb0000644000004100000410000000266612272154172017627 0ustar www-datawww-dataclass Pry class Method # A Disowned Method is one that's been removed from the class on which it was defined. # # e.g. # class C # def foo # C.send(:undefine_method, :foo) # Pry::Method.from_binding(binding) # end # end # # In this case we assume that the "owner" is the singleton class of the receiver. # # This occurs mainly in Sinatra applications. class Disowned < Method attr_reader :receiver, :name # Create a new Disowned method. # # @param [Object] receiver # @param [String] method_name def initialize(receiver, method_name, binding=nil) @receiver, @name = receiver, method_name end # Is the method undefined? (aka `Disowned`) # @return [Boolean] true def undefined? true end # Can we get the source for this method? # @return [Boolean] false def source? false end # Get the hypothesized owner of the method. # # @return [Object] def owner class << receiver; self; end end # Raise a more useful error message instead of trying to forward to nil. def method_missing(meth_name, *args, &block) raise "Cannot call '#{meth_name}' on an undef'd method." if method(:name).respond_to?(meth_name) Object.instance_method(:method_missing).bind(self).call(meth_name, *args, &block) end end end end pry-0.9.12.6/lib/pry/method/weird_method_locator.rb0000644000004100000410000001444012272154172022201 0ustar www-datawww-dataclass Pry class Method # This class is responsible for locating the *real* `Pry::Method` # object captured by a binding. # # Given a `Binding` from inside a method and a 'seed' Pry::Method object, # there are primarily two situations where the seed method doesn't match # the Binding: # 1. The Pry::Method is from a subclass 2. The Pry::Method represents a method of the same name # while the original was renamed to something else. For 1. we # search vertically up the inheritance chain, # and for 2. we search laterally along the object's method table. # # When we locate the method that matches the Binding we wrap it in # Pry::Method and return it, or return nil if we fail. class WeirdMethodLocator class << self # Whether the given method object matches the associated binding. # If the method object does not match the binding, then it's # most likely not the method captured by the binding, and we # must commence a search. # # @param [Pry::Method] method # @param [Binding] b # @return [Boolean] def normal_method?(method, b) method && (method.source_file && method.source_range rescue false) && File.expand_path(method.source_file) == File.expand_path(b.eval('__FILE__')) && method.source_range.include?(b.eval('__LINE__')) end def weird_method?(method, b) !normal_method?(method, b) end end attr_accessor :method attr_accessor :target # @param [Pry::Method] method The seed method. # @param [Binding] target The Binding that captures the method # we want to locate. def initialize(method, target) @method, @target = method, target end # @return [Pry::Method, nil] The Pry::Method that matches the # given binding. def get_method find_method_in_superclass || find_renamed_method end # @return [Boolean] Whether the Pry::Method is unrecoverable # This usually happens when the method captured by the Binding # has been subsequently deleted. def lost_method? !!(get_method.nil? && renamed_method_source_location) end private def normal_method?(method) self.class.normal_method?(method, target) end def target_self target.eval('self') end def target_file pry_file? ? target.eval('__FILE__') : File.expand_path(target.eval('__FILE__')) end def target_line target.eval('__LINE__') end def pry_file? Pry.eval_path == target.eval('__FILE__') end # it's possible in some cases that the method we find by this approach is a sub-method of # the one we're currently in, consider: # # class A; def b; binding.pry; end; end # class B < A; def b; super; end; end # # Given that we can normally find the source_range of methods, and that we know which # __FILE__ and __LINE__ the binding is at, we can hope to disambiguate these cases. # # This obviously won't work if the source is unavaiable for some reason, or if both # methods have the same __FILE__ and __LINE__, or if we're in rbx where b.eval('__LINE__') # is broken. # # @return [Pry::Method, nil] The Pry::Method representing the # superclass method. def find_method_in_superclass guess = method while guess # needs rescue if this is a Disowned method or a C method or something... # TODO: Fix up the exception handling so we don't need a bare rescue if normal_method?(guess) return guess else guess = guess.super end end # Uhoh... none of the methods in the chain had the right __FILE__ and __LINE__ # This may be caused by rbx https://github.com/rubinius/rubinius/issues/953, # or other unknown circumstances (TODO: we should warn the user when this happens) nil end # This is the case where the name of a method has changed # (via alias_method) so we locate the Method object for the # renamed method. # # @return [Pry::Method, nil] The Pry::Method representing the # renamed method def find_renamed_method return if !valid_file?(target_file) alias_name = all_methods_for(target_self).find do |v| expanded_source_location(target_self.method(v).source_location) == renamed_method_source_location end alias_name && Pry::Method(target_self.method(alias_name)) end def expanded_source_location(sl) return if !sl if pry_file? sl else [File.expand_path(sl.first), sl.last] end end # Use static analysis to locate the start of the method definition. # We have the `__FILE__` and `__LINE__` from the binding and the # original name of the method so we search up until we find a # def/define_method, etc defining a method of the appropriate name. # # @return [Array] The `source_location` of the # renamed method def renamed_method_source_location return @original_method_source_location if defined?(@original_method_source_location) source_index = lines_for_file(target_file)[0..(target_line - 1)].rindex do |v| Pry::Method.method_definition?(method.name, v) end @original_method_source_location = source_index && [target_file, index_to_line_number(source_index)] end def index_to_line_number(index) # Pry.line_buffer is 0-indexed pry_file? ? index : index + 1 end def valid_file?(file) (File.exists?(file) && !File.directory?(file)) || Pry.eval_path == file end def lines_for_file(file) @lines_for_file ||= {} @lines_for_file[file] ||= if Pry.eval_path == file Pry.line_buffer else File.readlines(file) end end def all_methods_for(obj) obj.public_methods(false) + obj.private_methods(false) + obj.protected_methods(false) end end end end pry-0.9.12.6/lib/pry/custom_completions.rb0000644000004100000410000000033412272154172020447 0ustar www-datawww-dataclass Pry # This proc will be instance_eval's against the active Pry instance DEFAULT_CUSTOM_COMPLETIONS = proc { commands.commands.keys } FILE_COMPLETIONS = proc { commands.commands.keys + Dir.entries('.') } end pry-0.9.12.6/lib/pry/history_array.rb0000644000004100000410000000557212272154172017431 0ustar www-datawww-dataclass Pry # A history array is an array to which you can only add elements. Older # entries are removed progressively, so that the aray never contains more than # N elements. # # History arrays are used by Pry to store the output of the last commands. # # @example # ary = Pry::HistoryArray.new 10 # ary << 1 << 2 << 3 # ary[0] # => 1 # ary[1] # => 2 # 10.times { |n| ary << n } # ary[0] # => nil # ary[-1] # => 9 class HistoryArray include Enumerable # @param [Integer] size Maximum amount of objects in the array def initialize(size) @max_size = size @hash = {} @count = 0 end # Pushes an object at the end of the array # @param [Object] value Object to be added def <<(value) @hash[@count] = value if @hash.size > max_size @hash.delete(@count - max_size) end @count += 1 self end # @overload [](index) # @param [Integer] index Index of the item to access. # @return [Object, nil] Item at that index or nil if it has been removed. # @overload [](index, size) # @param [Integer] index Index of the first item to access. # @param [Integer] size Amount of items to access # @return [Array, nil] The selected items. Nil if index is greater than # the size of the array. # @overload [](range) # @param [Range] range Range of indices to access. # @return [Array, nil] The selected items. Nil if index is greater than # the size of the array. def [](index_or_range, size = nil) if index_or_range.is_a? Integer index = convert_index(index_or_range) if size end_index = index + size index > @count ? nil : (index...[end_index, @count].min).map do |n| @hash[n] end else @hash[index] end else range = convert_range(index_or_range) range.begin > @count ? nil : range.map { |n| @hash[n] } end end # @return [Integer] Amount of objects in the array def size @count end alias count size alias length size def empty? size == 0 end def each ((@count - size)...@count).each do |n| yield @hash[n] end end def to_a ((@count - size)...@count).map { |n| @hash[n] } end def pop! @hash.delete @count - 1 @count -= 1 end def inspect "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>" end # @return [Integer] Maximum amount of objects in the array attr_reader :max_size private def convert_index(n) n >= 0 ? n : @count + n end def convert_range(range) end_index = convert_index(range.end) end_index += 1 unless range.exclude_end? Range.new(convert_index(range.begin), [end_index, @count].min, true) end end end pry-0.9.12.6/lib/pry/editor.rb0000644000004100000410000001030012272154172016001 0ustar www-datawww-dataclass Pry class Editor extend Pry::Helpers::BaseHelpers extend Pry::Helpers::CommandHelpers class << self def edit_tempfile_with_content(initial_content, line=1) temp_file do |f| f.puts(initial_content) f.flush f.close(false) invoke_editor(f.path, line, true) File.read(f.path) end end def invoke_editor(file, line, blocking=true) raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless Pry.config.editor editor_invocation = build_editor_invocation_string(file, line, blocking) return nil unless editor_invocation if jruby? open_editor_on_jruby(editor_invocation) else open_editor(editor_invocation) end end private # Generate the string that's used to start the editor. This includes # all the flags we want as well as the file and line number we # want to open at. def build_editor_invocation_string(file, line, blocking) if Pry.config.editor.respond_to?(:call) args = [file, line, blocking][0...(Pry.config.editor.arity)] Pry.config.editor.call(*args) else sanitized_file = if windows? file.gsub(/\//, '\\') else Shellwords.escape(file) end "#{Pry.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}" end end # Start the editor running, using the calculated invocation string def open_editor(editor_invocation) # Note we dont want to use Pry.config.system here as that # may be invoked non-interactively (i.e via Open4), whereas we want to # ensure the editor is always interactive system(editor_invocation) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}" end # We need JRuby specific code here cos just shelling out using # system() appears to be pretty broken :/ def open_editor_on_jruby(editor_invocation) begin require 'spoon' pid = Spoon.spawnp(*editor_invocation.split) Process.waitpid(pid) rescue FFI::NotFoundError system(editor_invocation) end end # Some editors that run outside the terminal allow you to control whether or # not to block the process from which they were launched (in this case, Pry). # For those editors, return the flag that produces the desired behavior. def blocking_flag_for_editor(blocking) case editor_name when /^emacsclient/ '--no-wait' unless blocking when /^[gm]vim/ '--nofork' if blocking when /^jedit/ '-wait' if blocking when /^mate/, /^subl/ '-w' if blocking end end # Return the syntax for a given editor for starting the editor # and moving to a particular line within that file def start_line_syntax_for_editor(file_name, line_number) # special case for 1st line return file_name if line_number <= 1 case editor_name when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/ "+#{line_number} #{file_name}" when /^mate/, /^geany/ "-l #{line_number} #{file_name}" when /^subl/ "#{file_name}:#{line_number}" when /^uedit32/ "#{file_name}/#{line_number}" when /^jedit/ "#{file_name} +line:#{line_number}" else if windows? "#{file_name}" else "+#{line_number} #{file_name}" end end end # Get the name of the binary that Pry.config.editor points to. # # This is useful for deciding which flags we pass to the editor as # we can just use the program's name and ignore any absolute paths. # # @example # Pry.config.editor="/home/conrad/bin/textmate -w" # editor_name # # => textmate # def editor_name File.basename(Pry.config.editor).split(" ").first end end end end pry-0.9.12.6/lib/pry.rb0000644000004100000410000002152312272154172014524 0ustar www-datawww-data# (C) John Mair (banisterfiend) 2011 # MIT License # require 'pp' require 'pry/helpers/base_helpers' require 'pry/hooks' class Pry # The default hooks - display messages when beginning and ending Pry sessions. DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session, :default) do |out, target, _pry_| next if _pry_.quiet? _pry_.run_command("whereami --quiet", "", target) end # The default print DEFAULT_PRINT = proc do |output, value| output_with_default_format(output, value, :hashrocket => true) end 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!(/# #{result}"if options[:hashrocket] Helpers::BaseHelpers.stagger_output(result, output) end # may be convenient when working with enormous objects and # pretty_print is too slow SIMPLE_PRINT = proc do |output, value| begin output.puts value.inspect rescue RescuableException output.puts "unknown" end end # useful when playing with truly enormous objects CLIPPED_PRINT = proc do |output, value| output.puts Pry.view_clip(value) end # Will only show the first line of the backtrace DEFAULT_EXCEPTION_HANDLER = proc do |output, exception, _| if UserError === exception && SyntaxError === exception output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}" else output.puts "#{exception.class}: #{exception.message}" output.puts "from #{exception.backtrace.first}" end end DEFAULT_PROMPT_NAME = 'pry' # The default prompt; includes the target and nesting level DEFAULT_PROMPT = [ proc { |target_self, nest_level, pry| "[#{pry.input_array.size}] #{Pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> " }, proc { |target_self, nest_level, pry| "[#{pry.input_array.size}] #{Pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* " } ] # A simple prompt - doesn't display target or nesting level SIMPLE_PROMPT = [proc { ">> " }, proc { " | " }] SHELL_PROMPT = [ proc { |target_self, _, _| "#{Pry.config.prompt_name} #{Pry.view_clip(target_self)}:#{Dir.pwd} $ " }, proc { |target_self, _, _| "#{Pry.config.prompt_name} #{Pry.view_clip(target_self)}:#{Dir.pwd} * " } ] # A prompt that includes the full object path as well as # input/output (_in_ and _out_) information. Good for navigation. NAV_PROMPT = [ proc do |conf| tree = conf.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " "[#{conf.expr_number}] (#{Pry.config.prompt_name}) #{tree}: #{conf.nesting_level}> " end, proc do |conf| tree = conf.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " "[#{conf.expr_number}] (#{ Pry.config.prompt_name}) #{tree}: #{conf.nesting_level}* " end, ] # Deal with the ^D key being pressed. Different behaviour in different cases: # 1. In an expression behave like `!` command. # 2. At top-level session behave like `exit` command. # 3. In a nested session behave like `cd ..`. DEFAULT_CONTROL_D_HANDLER = proc do |eval_string, _pry_| if !eval_string.empty? eval_string.replace('') # Clear input buffer. elsif _pry_.binding_stack.one? _pry_.binding_stack.clear throw(:breakout) else # Store the entire binding stack before popping. Useful for `cd -`. if _pry_.command_state['cd'].nil? _pry_.command_state['cd'] = OpenStruct.new end _pry_.command_state['cd'].old_stack = _pry_.binding_stack.dup _pry_.binding_stack.pop end end DEFAULT_SYSTEM = proc do |output, cmd, _| if !system(cmd) output.puts "Error: there was a problem executing system command: #{cmd}" end end # Store the current working directory. This allows show-source etc. to work if # your process has changed directory since boot. [Issue #675] INITIAL_PWD = Dir.pwd # As a REPL, we often want to catch any unexpected exceptions that may have # been raised; however we don't want to go overboard and prevent the user # from exiting Pry when they want to. module RescuableException def self.===(exception) case exception # Catch when the user hits ^C (Interrupt < SignalException), and assume # that they just wanted to stop the in-progress command (just like bash etc.) when Interrupt true # Don't catch signals (particularly not SIGTERM) as these are unlikely to be # intended for pry itself. We should also make sure that Kernel#exit works. when *Pry.config.exception_whitelist false # All other exceptions will be caught. else true end end end # An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error in # a more user-friendly manner. This should be used when the exception happens within # Pry itself as a direct consequence of the user typing something wrong. # # This allows us to distinguish between the user typing: # # pry(main)> def ) # SyntaxError: unexpected ) # # pry(main)> method_that_evals("def )") # SyntaxError: (eval):1: syntax error, unexpected ')' # from ./a.rb:2 in `eval' module UserError; end # Catches SecurityErrors if $SAFE is set module TooSafeException def self.===(exception) $SAFE > 0 && SecurityError === exception end end # Don't catch these exceptions DEFAULT_EXCEPTION_WHITELIST = [SystemExit, SignalException, Pry::TooSafeException] # CommandErrors are caught by the REPL loop and displayed to the user. They # indicate an exceptional condition that's fatal to the current command. class CommandError < StandardError; end class MethodNotFound < CommandError; end # indicates obsolete API class ObsoleteError < StandardError; end # This is to keep from breaking under Rails 3.2 for people who are doing that # IRB = Pry thing. module ExtendCommandBundle end def self.require_readline return false if @required_readline require 'readline' @required_readline = true rescue LoadError warn "Sorry, you can't use Pry without Readline or a compatible library." warn "Please `gem install rb-readline` or recompile Ruby --with-readline." raise end end if Pry::Helpers::BaseHelpers.mri_18? begin require 'ruby18_source_location' rescue LoadError end end require 'method_source' require 'shellwords' require 'stringio' require 'coderay' require 'slop' require 'rbconfig' require 'tempfile' if Pry::Helpers::BaseHelpers.jruby? begin require 'ffi' rescue LoadError warn "For a better Pry experience on JRuby, please `gem install ffi`." end end if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi? begin require 'win32console' # The mswin and mingw versions of pry require win32console, so this should # only fail on jruby (where win32console doesn't work). # Instead we'll recommend ansicon, which does. rescue LoadError warn "For a better Pry experience on Windows, please use ansicon:" warn " http://adoxa.3eeweb.com/ansicon/" end end begin require 'bond' rescue LoadError end require 'pry/version' require 'pry/rbx_method' require 'pry/rbx_path' require 'pry/code' require 'pry/history_array' require 'pry/helpers' require 'pry/code_object' require 'pry/method' require 'pry/wrapped_module' require 'pry/history' require 'pry/command' require 'pry/command_set' require 'pry/commands' require 'pry/custom_completions' require 'pry/completion' require 'pry/plugins' require 'pry/core_extensions' require 'pry/pry_class' require 'pry/pry_instance' require 'pry/cli' require 'pry/pager' require 'pry/terminal' require 'pry/editor' require 'pry/rubygem' pry-0.9.12.6/README.markdown0000644000004100000410000003523612272154172015326 0ustar www-datawww-data[![Build Status](https://secure.travis-ci.org/pry/pry.png)](http://travis-ci.org/pry/pry)
![The Pry Logo](https://dl.dropbox.com/u/26521875/pry%20stuff/logo/pry_logo_350.png) © John Mair (banisterfiend) 2012
**Please** [DONATE](http://www.pledgie.com/campaigns/15899) to the Pry project - Pry was a **huge** amount of work and every donation received is encouraging and supports Pry's continued development! **Sponsors** [Atomic Object](http://www.atomicobject.com/)
[Bendyworks](http://bendyworks.com/)
[Intridea](http://intridea.com/)
[Gaslight](http://gaslight.co/home)
**Other Resources** [Skip to the website (recommended)](http://pry.github.com)
[Skip to the wiki](https://github.com/pry/pry/wiki)
Pry is a powerful alternative to the standard IRB shell for Ruby. It is written from scratch to provide a number of advanced features, including: * Source code browsing (including core C source with the pry-doc gem) * Documentation browsing * Live help system * Open methods in editors (`edit-method Class#method`) * Syntax highlighting * Command shell integration (start editors, run git, and rake from within Pry) * Gist integration * Navigation around state (`cd`, `ls` and friends) * Runtime invocation (use Pry as a developer console or debugger) * Exotic object support (BasicObject instances, IClasses, ...) * A Powerful and flexible command system * Ability to view and replay history * Many convenience commands inspired by IPython, Smalltalk and other advanced REPLs * A wide-range number of [plugins](https://github.com/pry/pry/wiki/Available-plugins) that provide remote sessions, full debugging functionality, and more. Pry also aims to be more than an IRB replacement; it is an attempt to bring REPL driven programming to the Ruby language. It is currently not as powerful as tools like [SLIME](http://en.wikipedia.org/wiki/SLIME) for lisp, but that is the general direction Pry is heading. Pry is also fairly flexible and allows significant user [customization](https://github.com/pry/pry/wiki/Customization-and-configuration) is trivial to set it to read from any object that has a `readline` method and write to any object that has a `puts` method - many other aspects of Pry are also configurable making it a good choice for implementing custom shells. Pry comes with an executable so it can be invoked at the command line. Just enter `pry` to start. A `.pryrc` file in the user's home directory will be loaded if it exists. Type `pry --help` at the command line for more information. Try `gem install pry-doc` for additional documentation on Ruby Core methods. The additional docs are accessed through the `show-doc` and `show-method` commands. * Install the [gem](https://rubygems.org/gems/pry): `gem install pry` * Browse the comprehensive [documentation at the official Pry wiki](https://github.com/pry/pry/wiki) * Read the [YARD API documentation](http://rdoc.info/github/pry/pry/master/file/README.markdown) * See the [source code](http://github.com/pry/pry) Pry also has `rubygems-test` support; to participate, first install Pry, then: 1. Install rubygems-test: `gem install rubygems-test` 2. Run the test: `gem test pry` 3. Finally choose 'Yes' to upload the results. ### Commands Nearly every piece of functionality in a Pry session is implemented as a command. Commands are not methods and must start at the beginning of a line, with no whitespace in between. Commands support a flexible syntax and allow 'options' in the same way as shell commands, for example the following Pry command will show a list of all private instance methods (in scope) that begin with 'pa' pry(YARD::Parser::SourceParser):5> ls -Mp --grep ^pa YARD::Parser::SourceParser#methods: parse parser_class parser_type parser_type= parser_type_for_filename ### Navigating around state Pry allows us to pop in and out of different scopes (objects) using the `cd` command. This enables us to explore the run-time view of a program or library. To view which variables and methods are available within a particular scope we use the versatile [ls command.](https://gist.github.com/c0fc686ef923c8b87715) Here we will begin Pry at top-level, then Pry on a class and then on an instance variable inside that class: pry(main)> class Hello pry(main)* @x = 20 pry(main)* end => 20 pry(main)> cd Hello pry(Hello):1> ls -i instance variables: @x pry(Hello):1> cd @x pry(20:2)> self + 10 => 30 pry(20:2)> cd .. pry(Hello):1> cd .. pry(main)> cd .. The number after the `:` in the pry prompt indicates the nesting level. To display more information about nesting, use the `nesting` command. E.g pry("friend":3)> nesting Nesting status: 0. main (Pry top level) 1. Hello 2. 100 3. "friend" => nil We can then jump back to any of the previous nesting levels by using the `jump-to` command: pry("friend":3)> jump-to 1 => 100 pry(Hello):1> ### Runtime invocation Pry can be invoked in the middle of a running program. It opens a Pry session at the point it's called and makes all program state at that point available. It can be invoked on any object using the `my_object.pry` syntax or on the current binding (or any binding) using `binding.pry`. The Pry session will then begin within the scope of the object (or binding). When the session ends the program continues with any modifications you made to it. This functionality can be used for such things as: debugging, implementing developer consoles and applying hot patches. code: # test.rb require 'pry' class A def hello() puts "hello world!" end end a = A.new # start a REPL session binding.pry # program resumes here (after pry session) puts "program resumes here." Pry session: pry(main)> a.hello hello world! => nil pry(main)> def a.goodbye pry(main)* puts "goodbye cruel world!" pry(main)* end => nil pry(main)> a.goodbye goodbye cruel world! => nil pry(main)> exit program resumes here. ### Command Shell Integration A line of input that begins with a '.' will be forwarded to the command shell. This enables us to navigate the file system, spawn editors, and run git and rake directly from within Pry. Further, we can use the `shell-mode` command to incorporate the present working directory into the Pry prompt and bring in (limited at this stage, sorry) file name completion. We can also interpolate Ruby code directly into the shell by using the normal `#{}` string interpolation syntax. In the code below we're going to switch to `shell-mode` and edit the `.pryrc` file in the home directory. We'll then cat its contents and reload the file. pry(main)> shell-mode pry main:/home/john/ruby/projects/pry $ .cd ~ pry main:/home/john $ .emacsclient .pryrc pry main:/home/john $ .cat .pryrc def hello_world puts "hello world!" end pry main:/home/john $ load ".pryrc" => true pry main:/home/john $ hello_world hello world! We can also interpolate Ruby code into the shell. In the example below we use the shell command `cat` on a random file from the current directory and count the number of lines in that file with `wc`: pry main:/home/john $ .cat #{Dir['*.*'].sample} | wc -l 44 ### Code Browsing You can browse method source code with the `show-method` command. Nearly all Ruby methods (and some C methods, with the pry-doc gem) can have their source viewed. Code that is longer than a page is sent through a pager (such as less), and all code is properly syntax highlighted (even C code). The `show-method` command accepts two syntaxes, the typical ri `Class#method` syntax and also simply the name of a method that's in scope. You can optionally pass the `-l` option to show-method to include line numbers in the output. In the following example we will enter the `Pry` class, list the instance methods beginning with 're' and display the source code for the `rep` method: pry(main)> cd Pry pry(Pry)> ls -M --grep re Pry#methods: re readline refresh rep repl repl_epilogue repl_prologue retrieve_line pry(Pry):1> show-method rep -l From: /home/john/ruby/projects/pry/lib/pry/pry_instance.rb @ line 143: Number of lines: 6 143: def rep(target=TOPLEVEL_BINDING) 144: target = Pry.binding_for(target) 145: result = re(target) 146: 147: show_result(result) if should_print? 148: end Note that we can also view C methods (from Ruby Core) using the `pry-doc` plugin; we also show off the alternate syntax for `show-method`: pry(main)> show-method Array#select From: array.c in Ruby Core (C Method): Number of lines: 15 static VALUE rb_ary_select(VALUE ary) { VALUE result; long i; RETURN_ENUMERATOR(ary, 0, 0); result = rb_ary_new2(RARRAY_LEN(ary)); for (i = 0; i < RARRAY_LEN(ary); i++) { if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) { rb_ary_push(result, rb_ary_elt(ary, i)); } } return result; } ### Documentation Browsing One use-case for Pry is to explore a program at run-time by `cd`-ing in and out of objects and viewing and invoking methods. In the course of exploring it may be useful to read the documentation for a specific method that you come across. Like `show-method` the `show-doc` command supports two syntaxes - the normal `ri` syntax as well as accepting the name of any method that is currently in scope. The Pry documentation system does not rely on pre-generated `rdoc` or `ri`, instead it grabs the comments directly above the method on demand. This results in speedier documentation retrieval and allows the Pry system to retrieve documentation for methods that would not be picked up by `rdoc`. Pry also has a basic understanding of both the rdoc and yard formats and will attempt to syntax highlight the documentation appropriately. Nonetheless, the `ri` functionality is very good and has an advantage over Pry's system in that it allows documentation lookup for classes as well as methods. Pry therefore has good integration with `ri` through the `ri` command. The syntax for the command is exactly as it would be in command-line - so it is not necessary to quote strings. In our example we will enter the `Gem` class and view the documentation for the `try_activate` method: pry(main)> cd Gem pry(Gem):1> show-doc try_activate From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems.rb @ line 201: Number of lines: 3 Try to activate a gem containing path. Returns true if activation succeeded or wasn't needed because it was already activated. Returns false if it can't find the path in a gem. pry(Gem):1> We can also use `ri` in the normal way: pry(main) ri Array#each ----------------------------------------------------------- Array#each array.each {|item| block } -> array ------------------------------------------------------------------------ Calls _block_ once for each element in _self_, passing that element as a parameter. a = [ "a", "b", "c" ] a.each {|x| print x, " -- " } produces: a -- b -- c -- ### Gist integration If the `gist` gem is installed then method source or documentation can be gisted to github with the `gist` command. The `gist` command is capable of gisting [almost any REPL content](https://gist.github.com/cae143e4533416529726), including methods, documentation, input expressions, command source, and so on. In the example below we will gist the C source code for the `Symbol#to_proc` method to github: pry(main)> gist -m Symbol#to_proc Gist created at https://gist.github.com/5332c38afc46d902ce46 and added to clipboard. pry(main)> You can see the actual gist generated here: [https://gist.github.com/5332c38afc46d902ce46](https://gist.github.com/5332c38afc46d902ce46) ### Edit methods You can use `edit-method Class#method` or `edit-method my_method` (if the method is in scope) to open a method for editing directly in your favorite editor. Pry has knowledge of a few different editors and will attempt to open the file at the line the method is defined. You can set the editor to use by assigning to the `Pry.editor` accessor. `Pry.editor` will default to `$EDITOR` or failing that will use `nano` as the backup default. The file that is edited will be automatically reloaded after exiting the editor - reloading can be suppressed by passing the `--no-reload` option to `edit-method` In the example below we will set our default editor to "emacsclient" and open the `Pry#repl` method for editing: pry(main)> Pry.editor = "emacsclient" pry(main)> edit-method Pry#repl ### Live Help System Many other commands are available in Pry; to see the full list type `help` at the prompt. A short description of each command is provided with basic instructions for use; some commands have a more extensive help that can be accessed via typing `command_name --help`. A command will typically say in its description if the `--help` option is avaiable. ### Use Pry as your Rails Console pry -r ./config/environment MyArtChannel has kindly provided a hack to replace the `rails console` command in Rails 3: [https://gist.github.com/941174](https://gist.github.com/941174) This is not recommended for code bases with multiple developers, as they may not all want to use Pry. Also check out the [wiki](https://github.com/pry/pry/wiki/Setting-up-Rails-or-Heroku-to-use-Pry) for other strategies on integrating Pry with rails, notably the [pry-rails](https://github.com/pry/pry/wiki/Setting-up-Rails-or-Heroku-to-use-Pry#wiki-pry_rails) plugin. ### Limitations: * Tab completion is currently a bit broken/limited this will have a major overhaul in a future version. ### Syntax Highlighting Syntax highlighting is on by default in Pry. You can toggle it on and off in a session by using the `toggle-color` command. Alternatively, you can turn it off permanently by putting the line `Pry.color = false` in your `~/.pryrc` file. ### Future Directions Many new features are planned such as: * Increase modularity (rely more on plugin system) * Much improved tab completion (using [Bond](http://github.com/cldwalker/bond)) * Much improved documentation system, better support for YARD * Better support for code and method reloading and saving code * Extended and more sophisticated command system, allowing piping between commands and running commands in background ### Contact Problems or questions? file an issue at [github](https://github.com/pry/pry/issues) ### Contributors Pry is primarily the work of [John Mair (banisterfiend)](http://github.com/banister), for full list of contributors see the [CONTRIBUTORS](https://github.com/pry/pry/blob/master/CONTRIBUTORS) file. pry-0.9.12.6/metadata.yml0000644000004100000410000002447412272154173015133 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: pry version: !ruby/object:Gem::Version version: 0.9.12.6 platform: ruby authors: - John Mair (banisterfiend) - Conrad Irwin - Ryan Fitzgerald autorequire: bindir: bin cert_chain: [] date: 2014-01-28 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: coderay requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: slop requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '3.4' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '3.4' - !ruby/object:Gem::Dependency name: method_source requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.8' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.8' - !ruby/object:Gem::Dependency name: bacon requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.2' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.2' - !ruby/object:Gem::Dependency name: open4 requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.3' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.3' - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.9' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.9' - !ruby/object:Gem::Dependency name: mocha requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.13.1 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.13.1 - !ruby/object:Gem::Dependency name: bond requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.4.2 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.4.2 description: An IRB alternative and runtime developer console email: - jrmair@gmail.com - conrad.irwin@gmail.com - rwfitzge@gmail.com executables: - pry extensions: [] extra_rdoc_files: [] files: - .document - .gitignore - .travis.yml - .yardopts - CHANGELOG - CONTRIBUTORS - Gemfile - LICENSE - README.markdown - Rakefile - TODO - bin/pry - lib/pry.rb - lib/pry/cli.rb - lib/pry/code.rb - lib/pry/code/code_range.rb - lib/pry/code/loc.rb - lib/pry/code_object.rb - lib/pry/command.rb - lib/pry/command_set.rb - lib/pry/commands.rb - lib/pry/commands/amend_line.rb - lib/pry/commands/bang.rb - lib/pry/commands/bang_pry.rb - lib/pry/commands/cat.rb - lib/pry/commands/cat/abstract_formatter.rb - lib/pry/commands/cat/exception_formatter.rb - lib/pry/commands/cat/file_formatter.rb - lib/pry/commands/cat/input_expression_formatter.rb - lib/pry/commands/cd.rb - lib/pry/commands/code_collector.rb - lib/pry/commands/disable_pry.rb - lib/pry/commands/disabled_commands.rb - lib/pry/commands/easter_eggs.rb - lib/pry/commands/edit.rb - lib/pry/commands/edit/exception_patcher.rb - lib/pry/commands/edit/file_and_line_locator.rb - lib/pry/commands/edit/method_patcher.rb - lib/pry/commands/exit.rb - lib/pry/commands/exit_all.rb - lib/pry/commands/exit_program.rb - lib/pry/commands/find_method.rb - lib/pry/commands/fix_indent.rb - lib/pry/commands/gem_cd.rb - lib/pry/commands/gem_install.rb - lib/pry/commands/gem_list.rb - lib/pry/commands/gem_open.rb - lib/pry/commands/gist.rb - lib/pry/commands/help.rb - lib/pry/commands/hist.rb - lib/pry/commands/import_set.rb - lib/pry/commands/install_command.rb - lib/pry/commands/jump_to.rb - lib/pry/commands/ls.rb - lib/pry/commands/nesting.rb - lib/pry/commands/play.rb - lib/pry/commands/pry_backtrace.rb - lib/pry/commands/pry_version.rb - lib/pry/commands/raise_up.rb - lib/pry/commands/reload_code.rb - lib/pry/commands/reset.rb - lib/pry/commands/ri.rb - lib/pry/commands/save_file.rb - lib/pry/commands/shell_command.rb - lib/pry/commands/shell_mode.rb - lib/pry/commands/show_doc.rb - lib/pry/commands/show_info.rb - lib/pry/commands/show_input.rb - lib/pry/commands/show_source.rb - lib/pry/commands/simple_prompt.rb - lib/pry/commands/stat.rb - lib/pry/commands/switch_to.rb - lib/pry/commands/toggle_color.rb - lib/pry/commands/whereami.rb - lib/pry/commands/wtf.rb - lib/pry/completion.rb - lib/pry/config.rb - lib/pry/core_extensions.rb - lib/pry/custom_completions.rb - lib/pry/editor.rb - lib/pry/helpers.rb - lib/pry/helpers/base_helpers.rb - lib/pry/helpers/command_helpers.rb - lib/pry/helpers/documentation_helpers.rb - lib/pry/helpers/options_helpers.rb - lib/pry/helpers/table.rb - lib/pry/helpers/text.rb - lib/pry/history.rb - lib/pry/history_array.rb - lib/pry/hooks.rb - lib/pry/indent.rb - lib/pry/method.rb - lib/pry/method/disowned.rb - lib/pry/method/weird_method_locator.rb - lib/pry/module_candidate.rb - lib/pry/pager.rb - lib/pry/plugins.rb - lib/pry/pry_class.rb - lib/pry/pry_instance.rb - lib/pry/rbx_method.rb - lib/pry/rbx_path.rb - lib/pry/repl_file_loader.rb - lib/pry/rubygem.rb - lib/pry/terminal.rb - lib/pry/test/helper.rb - lib/pry/version.rb - lib/pry/wrapped_module.rb - man/pry.1 - man/pry.1.html - man/pry.1.ronn - pry.gemspec - spec/Procfile - spec/cli_spec.rb - spec/code_object_spec.rb - spec/code_spec.rb - spec/command_helpers_spec.rb - spec/command_integration_spec.rb - spec/command_set_spec.rb - spec/command_spec.rb - spec/commands/amend_line_spec.rb - spec/commands/bang_spec.rb - spec/commands/cat_spec.rb - spec/commands/cd_spec.rb - spec/commands/disable_pry_spec.rb - spec/commands/edit_spec.rb - spec/commands/exit_all_spec.rb - spec/commands/exit_program_spec.rb - spec/commands/exit_spec.rb - spec/commands/find_method_spec.rb - spec/commands/gem_list_spec.rb - spec/commands/gist_spec.rb - spec/commands/help_spec.rb - spec/commands/hist_spec.rb - spec/commands/jump_to_spec.rb - spec/commands/ls_spec.rb - spec/commands/play_spec.rb - spec/commands/raise_up_spec.rb - spec/commands/save_file_spec.rb - spec/commands/show_doc_spec.rb - spec/commands/show_input_spec.rb - spec/commands/show_source_spec.rb - spec/commands/whereami_spec.rb - spec/completion_spec.rb - spec/control_d_handler_spec.rb - spec/documentation_helper_spec.rb - spec/editor_spec.rb - spec/exception_whitelist_spec.rb - spec/fixtures/candidate_helper1.rb - spec/fixtures/candidate_helper2.rb - spec/fixtures/example.erb - spec/fixtures/example_nesting.rb - spec/fixtures/show_source_doc_examples.rb - spec/fixtures/testrc - spec/fixtures/testrcbad - spec/fixtures/whereami_helper.rb - spec/helper.rb - spec/helpers/bacon.rb - spec/helpers/mock_pry.rb - spec/helpers/table_spec.rb - spec/history_array_spec.rb - spec/hooks_spec.rb - spec/indent_spec.rb - spec/input_stack_spec.rb - spec/method_spec.rb - spec/prompt_spec.rb - spec/pry_defaults_spec.rb - spec/pry_history_spec.rb - spec/pry_output_spec.rb - spec/pry_spec.rb - spec/run_command_spec.rb - spec/sticky_locals_spec.rb - spec/syntax_checking_spec.rb - spec/wrapped_module_spec.rb - wiki/Customizing-pry.md - wiki/Home.md homepage: http://pry.github.com licenses: [] metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.1.11 signing_key: specification_version: 4 summary: An IRB alternative and runtime developer console test_files: - spec/Procfile - spec/cli_spec.rb - spec/code_object_spec.rb - spec/code_spec.rb - spec/command_helpers_spec.rb - spec/command_integration_spec.rb - spec/command_set_spec.rb - spec/command_spec.rb - spec/commands/amend_line_spec.rb - spec/commands/bang_spec.rb - spec/commands/cat_spec.rb - spec/commands/cd_spec.rb - spec/commands/disable_pry_spec.rb - spec/commands/edit_spec.rb - spec/commands/exit_all_spec.rb - spec/commands/exit_program_spec.rb - spec/commands/exit_spec.rb - spec/commands/find_method_spec.rb - spec/commands/gem_list_spec.rb - spec/commands/gist_spec.rb - spec/commands/help_spec.rb - spec/commands/hist_spec.rb - spec/commands/jump_to_spec.rb - spec/commands/ls_spec.rb - spec/commands/play_spec.rb - spec/commands/raise_up_spec.rb - spec/commands/save_file_spec.rb - spec/commands/show_doc_spec.rb - spec/commands/show_input_spec.rb - spec/commands/show_source_spec.rb - spec/commands/whereami_spec.rb - spec/completion_spec.rb - spec/control_d_handler_spec.rb - spec/documentation_helper_spec.rb - spec/editor_spec.rb - spec/exception_whitelist_spec.rb - spec/fixtures/candidate_helper1.rb - spec/fixtures/candidate_helper2.rb - spec/fixtures/example.erb - spec/fixtures/example_nesting.rb - spec/fixtures/show_source_doc_examples.rb - spec/fixtures/testrc - spec/fixtures/testrcbad - spec/fixtures/whereami_helper.rb - spec/helper.rb - spec/helpers/bacon.rb - spec/helpers/mock_pry.rb - spec/helpers/table_spec.rb - spec/history_array_spec.rb - spec/hooks_spec.rb - spec/indent_spec.rb - spec/input_stack_spec.rb - spec/method_spec.rb - spec/prompt_spec.rb - spec/pry_defaults_spec.rb - spec/pry_history_spec.rb - spec/pry_output_spec.rb - spec/pry_spec.rb - spec/run_command_spec.rb - spec/sticky_locals_spec.rb - spec/syntax_checking_spec.rb - spec/wrapped_module_spec.rb pry-0.9.12.6/man/0000755000004100000410000000000012272154172013367 5ustar www-datawww-datapry-0.9.12.6/man/pry.1.html0000644000004100000410000001743212272154172015235 0ustar www-datawww-data PRY(1) - A Reference to the PRY repl.
  1. PRY(1)
  2. PRY(1)

NAME

PRY - A Reference to the PRY repl.

Synopsis

pry [--version] [--exec] [--no-pager] [--no-history] [--no-color] [-f] [--no-plugins] [--installed-plugins] [--simple-prompt] [--require file] [-I] [--context] [--help]

DESCRIPTION

Pry is a powerful alternative to the standard IRB shell for Ruby. It is written from scratch to provide a number of advanced features.

HOMEPAGE

http://pry.github.com/

OPTIONS

-v --version

Prints the version of Pry.

-e --exec

Executes argument in context before the session starts.

--no-pager

Disable pager for long output.

--no-history

Disable history loading.

--no-color

Disable syntax highlighting for session.

-f

Prevent loading of ~/.pryrc for session.

--no-plugins

Supress loading of plugins.

--installed-plugins

List installed plugins.

--simple-prompt

Enable simple prompt mode (eg, >>).

-r --require

Require a ruby script at startup.

-I

Add a path to the $LOAD_PATH

-c --context

Start the session in the specified context. Equivalent to context.pry in a session.

FILES

~/.pryrc Personal pry initialization

EXAMPLES

Basic Usage

$ pry
[1] pry(main)>4 + 5
=> 9
[2] pry(main)> def hello_world
[2] pry(main)*   puts "Hello, World!"
[2] pry(main)* end  
=> nil
[3] pry(main)> hello_world
Hello, World!
=> nil

Command Line Interaction

Prefix any command you want your shell to execute with a period and pry will return the results from your shell.

[1] pry(main)> .date
Fri Nov 11 09:52:07 EST 2011

On the command line enter shell-mode to incorporate the current working directory into the Pry prompt.

pry(main)> shell-mode
pry main:/Users/john/ruby/projects/pry $ .cd ..
pry main:/Users/john/ruby/projects $ .cd ~
pry main:/Users/john $ .pwd
/Users/john
pry main:/Users/john $ shell-mode
pry(main)>

State Navigation

The cd command is used to move into a new object (or scope) inside a Pry session. When inside the new scope it becomes the self for the session and all commands and methods will operate on this new self.

pry(main)> self
=> main
pry(main)> cd Pry
pry(Pry):1> self
=> Pry
pry(Pry):1> cd ..
pry(main)>

The ls command is essentially a unified wrapper to a number of Ruby's introspection mechanisms, including (but not limited to) the following methods: methods, instance_variables, constants, local_variables, instance_methods, class_variables and all the various permutations thereof.

By default typing ls will return a list of just the local and instance variables available in the current context.

  • The -M option selects public instance methods (if available).
  • The -m option selects public methods.
  • The -c option selects constants.
  • The -i option select just instance variables.
  • The -l option selects just local variables.
  • The -s option modifies the -c and -m and -M options to go up the superclass chain (excluding Object).
  • The --grep REGEX prunes the list to items that match the regex.

Source Browsing

Simply typing show-method method_name will pull the source for the method and display it with syntax highlighting. You can also look up the source for multiple methods at the same time, by typing show-method method1 method2. As a convenience, Pry looks up both instance methods and class methods using this syntax, with priority given to instance methods.

pry(Pry):1> show-method rep

From: /Users/john/ruby/projects/pry/lib/pry/pry_instance.rb @ line 191:
Number of lines: 6

def rep(target=TOPLEVEL_BINDING)
  target = Pry.binding_for(target)
  result = re(target)

  show_result(result) if should_print?
end

AUTHORS

Pry is primarily the work of John Mair (banisterfiend)

  1. November 2011
  2. PRY(1)
pry-0.9.12.6/man/pry.10000644000004100000410000001045312272154172014266 0ustar www-datawww-data.\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . .TH "PRY" "1" "November 2011" "" "" . .SH "NAME" \fBPRY\fR \- A Reference to the PRY repl\. . .SH "Synopsis" \fBpry\fR [\fB\-\-version\fR] [\fB\-\-exec\fR] [\fB\-\-no\-pager\fR] [\fB\-\-no\-history\fR] [\fB\-\-no\-color\fR] [\fB\-f\fR] [\fB\-\-no\-plugins\fR] [\fB\-\-installed\-plugins\fR] [\fB\-\-simple\-prompt\fR] [\fB\-\-require\fR \fIfile\fR] [\fB\-I\fR] [\fB\-\-context\fR] [\fB\-\-help\fR] . .SH "DESCRIPTION" Pry is a powerful alternative to the standard IRB shell for Ruby\. It is written from scratch to provide a number of advanced features\. . .SH "HOMEPAGE" http://pry\.github\.com/ . .SH "OPTIONS" . .TP \fB\-v \-\-version\fR Prints the version of Pry\. . .TP \fB\-e \-\-exec\fR Executes argument in context before the session starts\. . .TP \fB\-\-no\-pager\fR Disable pager for long output\. . .TP \fB\-\-no\-history\fR Disable history loading\. . .TP \fB\-\-no\-color\fR Disable syntax highlighting for session\. . .TP \fB\-f\fR Prevent loading of ~/\.pryrc for session\. . .TP \fB\-\-no\-plugins\fR Supress loading of plugins\. . .TP \fB\-\-installed\-plugins\fR List installed plugins\. . .TP \fB\-\-simple\-prompt\fR Enable simple prompt mode (eg, >>)\. . .TP \fB\-r \-\-require\fR Require a ruby script at startup\. . .TP \fB\-I\fR Add a path to the $LOAD_PATH . .TP \fB\-c \-\-context\fR Start the session in the specified context\. Equivalent to \fBcontext\.pry\fR in a session\. . .SH "FILES" ~/\.pryrc Personal pry initialization . .SH "EXAMPLES" . .SS "Basic Usage" . .nf $ pry [1] pry(main)>4 + 5 => 9 [2] pry(main)> def hello_world [2] pry(main)* puts "Hello, World!" [2] pry(main)* end => nil [3] pry(main)> hello_world Hello, World! => nil . .fi . .SS "Command Line Interaction" Prefix any command you want your shell to execute with a period and pry will return the results from your shell\. . .IP "" 4 . .nf [1] pry(main)> \.date Fri Nov 11 09:52:07 EST 2011 . .fi . .IP "" 0 . .P On the command line enter \fBshell\-mode\fR to incorporate the current working directory into the Pry prompt\. . .IP "" 4 . .nf pry(main)> shell\-mode pry main:/Users/john/ruby/projects/pry $ \.cd \.\. pry main:/Users/john/ruby/projects $ \.cd ~ pry main:/Users/john $ \.pwd /Users/john pry main:/Users/john $ shell\-mode pry(main)> . .fi . .IP "" 0 . .SS "State Navigation" The cd command is used to move into a new object (or scope) inside a Pry session\. When inside the new scope it becomes the self for the session and all commands and methods will operate on this new self\. . .IP "" 4 . .nf pry(main)> self => main pry(main)> cd Pry pry(Pry):1> self => Pry pry(Pry):1> cd \.\. pry(main)> . .fi . .IP "" 0 . .P The ls command is essentially a unified wrapper to a number of Ruby\'s introspection mechanisms, including (but not limited to) the following methods: methods, instance_variables, constants, local_variables, instance_methods, class_variables and all the various permutations thereof\. . .P By default typing ls will return a list of just the local and instance variables available in the current context\. . .IP "\(bu" 4 The \-M option selects public instance methods (if available)\. . .IP "\(bu" 4 The \-m option selects public methods\. . .IP "\(bu" 4 The \-c option selects constants\. . .IP "\(bu" 4 The \-i option select just instance variables\. . .IP "\(bu" 4 The \-l option selects just local variables\. . .IP "\(bu" 4 The \-s option modifies the \-c and \-m and \-M options to go up the superclass chain (excluding Object)\. . .IP "\(bu" 4 The \-\-grep REGEX prunes the list to items that match the regex\. . .IP "" 0 . .SS "Source Browsing" Simply typing show\-method method_name will pull the source for the method and display it with syntax highlighting\. You can also look up the source for multiple methods at the same time, by typing show\-method method1 method2\. As a convenience, Pry looks up both instance methods and class methods using this syntax, with priority given to instance methods\. . .IP "" 4 . .nf pry(Pry):1> show\-method rep From: /Users/john/ruby/projects/pry/lib/pry/pry_instance\.rb @ line 191: Number of lines: 6 def rep(target=TOPLEVEL_BINDING) target = Pry\.binding_for(target) result = re(target) show_result(result) if should_print? end . .fi . .IP "" 0 . .SH "AUTHORS" Pry is primarily the work of John Mair (banisterfiend) pry-0.9.12.6/man/pry.1.ronn0000644000004100000410000000750512272154172015245 0ustar www-datawww-dataPRY(1) -- A Reference to the PRY repl. ====================================== ##Synopsis `pry` [`--version`] [`--exec`] [`--no-pager`] [`--no-history`] [`--no-color`] [`-f`] [`--no-plugins`] [`--installed-plugins`] [`--simple-prompt`] [`--require` _file_] [`-I`] [`--context`] [`--help`] ## DESCRIPTION Pry is a powerful alternative to the standard IRB shell for Ruby. It is written from scratch to provide a number of advanced features. ## HOMEPAGE http://pry.github.com/ ##OPTIONS * `-v --version`: Prints the version of Pry. * `-e --exec`: Executes argument in context before the session starts. * `--no-pager`: Disable pager for long output. * `--no-history`: Disable history loading. * `--no-color`: Disable syntax highlighting for session. * `-f`: Prevent loading of ~/.pryrc for session. * `--no-plugins`: Supress loading of plugins. * `--installed-plugins`: List installed plugins. * `--simple-prompt`: Enable simple prompt mode (eg, >>). * `-r --require`: Require a ruby script at startup. * `-I`: Add a path to the $LOAD_PATH * `-c --context`: Start the session in the specified context. Equivalent to `context.pry` in a session. ##FILES ~/.pryrc Personal pry initialization ##EXAMPLES ###Basic Usage $ pry [1] pry(main)>4 + 5 => 9 [2] pry(main)> def hello_world [2] pry(main)* puts "Hello, World!" [2] pry(main)* end => nil [3] pry(main)> hello_world Hello, World! => nil ###Command Line Interaction Prefix any command you want your shell to execute with a period and pry will return the results from your shell. [1] pry(main)> .date Fri Nov 11 09:52:07 EST 2011 On the command line enter `shell-mode` to incorporate the current working directory into the Pry prompt. pry(main)> shell-mode pry main:/Users/john/ruby/projects/pry $ .cd .. pry main:/Users/john/ruby/projects $ .cd ~ pry main:/Users/john $ .pwd /Users/john pry main:/Users/john $ shell-mode pry(main)> ###State Navigation The cd command is used to move into a new object (or scope) inside a Pry session. When inside the new scope it becomes the self for the session and all commands and methods will operate on this new self. pry(main)> self => main pry(main)> cd Pry pry(Pry):1> self => Pry pry(Pry):1> cd .. pry(main)> The ls command is essentially a unified wrapper to a number of Ruby's introspection mechanisms, including (but not limited to) the following methods: methods, instance\_variables, constants, local\_variables, instance\_methods, class_variables and all the various permutations thereof. By default typing ls will return a list of just the local and instance variables available in the current context. * The -M option selects public instance methods (if available). * The -m option selects public methods. * The -c option selects constants. * The -i option select just instance variables. * The -l option selects just local variables. * The -s option modifies the -c and -m and -M options to go up the superclass chain (excluding Object). * The --grep REGEX prunes the list to items that match the regex. ###Source Browsing Simply typing show-method method_name will pull the source for the method and display it with syntax highlighting. You can also look up the source for multiple methods at the same time, by typing show-method method1 method2. As a convenience, Pry looks up both instance methods and class methods using this syntax, with priority given to instance methods. pry(Pry):1> show-method rep From: /Users/john/ruby/projects/pry/lib/pry/pry_instance.rb @ line 191: Number of lines: 6 def rep(target=TOPLEVEL_BINDING) target = Pry.binding_for(target) result = re(target) show_result(result) if should_print? end ##AUTHORS Pry is primarily the work of John Mair (banisterfiend)pry-0.9.12.6/.gitignore0000644000004100000410000000015512272154172014605 0ustar www-datawww-dataMakefile *.so *.o *.def *.rbc doc/ pkg/ coverage/ .yardoc/ /tags *.gem .rbx/ .rvmrc Gemfile.lock *.swp **/*~ pry-0.9.12.6/.yardopts0000644000004100000410000000003412272154172014457 0ustar www-datawww-data--markup markdown --private pry-0.9.12.6/LICENSE0000644000004100000410000000212212272154172013616 0ustar www-datawww-dataLicense ------- (The MIT License) Copyright (c) 2011 John Mair (banisterfiend) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pry-0.9.12.6/pry.gemspec0000644000004100000410000000202612272154172014773 0ustar www-datawww-data# -*- encoding: utf-8 -*- require File.expand_path('../lib/pry/version', __FILE__) Gem::Specification.new do |s| s.name = "pry" s.version = Pry::VERSION s.authors = ["John Mair (banisterfiend)", "Conrad Irwin", "Ryan Fitzgerald"] s.email = ["jrmair@gmail.com", "conrad.irwin@gmail.com", "rwfitzge@gmail.com"] s.summary = "An IRB alternative and runtime developer console" s.description = s.summary s.homepage = "http://pry.github.com" s.executables = ["pry"] s.require_paths = ["lib"] s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- spec/*`.split("\n") s.add_dependency 'coderay', '~> 1.0' s.add_dependency 'slop', '~> 3.4' s.add_dependency 'method_source', '~> 0.8' s.add_development_dependency 'bacon', '~> 1.2' s.add_development_dependency 'open4', '~> 1.3' s.add_development_dependency 'rake', '~> 0.9' s.add_development_dependency 'mocha', '~> 0.13.1' # TODO: make this a plain dependency: s.add_development_dependency 'bond', '~> 0.4.2' end pry-0.9.12.6/TODO0000644000004100000410000001212312272154172013303 0ustar www-datawww-data0.9.5 * include method visiblity in show-doc and stat output * tempfile should end in .rb (for edit -t) * ls output should not be in array format * exceptions should allow access to previous items in the backtrace * input should allow multiple objects which are switched to automatically when EOF is reached on the preceding one * pry -r should happen in pry * more plugin-related commands in pry - see installed ones, see activated ones, see available on rubygems * should also allow plugins be explicitly activated as a command line option * should not raise if plugin activation fails (should show warning instead) * more documentation on CommandContext, etc and also command helpers * fix history saving (should not save all of Readline::HISTORY, but only what changed) * prevent blank lines going to Readline::HISTORY * ensure that cat --ex emulates the `whereami` format - includes line numbers and formatted the same, etc * rename inp and out to _inp_ and _out_ otherwise than can overwrite locals by those names when debugging (not good) * add source file to stat command * make plugins use hash instead of array * ensure edit -t has 'edit' alias (no parameters) and dumps eval_string into buffer * whitelist exceptions * hooks system * jruby shell command support 0.9.3 * hist command now excludes last line of input (the command invocation itself) * hist now has `history` alias * `pry -r` requires now happen after plugin loading (so as not to interfere with * new Pry.config.disable_auto_reload option, for turning off auto reloading by edit-method and related * add better error messages for `cd` command * add command_prefix * change some command names to include hyphen, e.g version => pry-version, install => install-command * do cat --ex and edit --ex * add reload-method * fixed exotic object regression - BasicObject.new etc now return "=> unknown" * converted: import => import-set, version => pry-version, install => install-command * fix show-doc bug for ruby 1.8 and Kernel.fork * edit -t (opens a temporary file and evals it in current context when closed) 0.9.0 Major features -------------- * Restructure command system and helpers (almost complete) * Delete unnecessary commands, add a couple of new ones (e.g amend-line) * Readline history * Plugin support * Support Rubinius core methods * in[] and out[] arrays * Improve test coverage (test some commands, etc) Minor changes ------------- * improve edit-method support for various editors * ensure all commands have appropriate error handing and informative error messages * show-doc should include signature of method Optional -------- * multi-line readline support 0.8.0 * allow #{} interpolation of all commands * update documentation! new commands and features and change in behaviour of `run` * add ; at end of line to suppress return value output * Remove message spam (before/after hooks) * stop commands returning a value * use `redo` in the r() method when encounter a command * shell functionality should just use system(), but redirect in and out to Pry.input and Pry.output by reassining $stdin and $stdout for duration of block. * basicobject and no to_s/inspect support * fix documentation, support rdoc and yard properly * only load Ripper if 1.9 AND MRI (support jruby 1.9, using RubyParser) * shell commands invokable file . * supercharge cat-file so it can syntax highlight sourcecode files 0.7.0 * add pry-doc support with syntax highlighting for docs * add 'mj' option to ls (restrict to singleton methods) * add _ex_ local to hold last exception raised in an exception 0.6.8 * add whereami command, a la the `ir_b` gem * make .pryrc be loaded by run-time pry sessions 0.6.7 * color support * --simple-prompt for pry commandline * -I mode for pry commandline * --color mode for pry commandline * clean up requires (put them all in one place) * simple-prompt command and toggle-color commandd. 0.6.1 * !@ command alias for exit_all * `cd /` for breaking out to pry top level (jump-to 0) * made `-e` option work in a more effective way for `pry` command line invocation * exit and exit-all commands now accept a parameter, this parameter becomes the return value of repl() * `command` method from CommandBase now accepts a :keep_retval arg that determines if command value is returned to pry session or just `nil` (`nil` was old behaviour) * tests for new :keep_retval and exit-all/exit behaviour; :keep_retval will remain undocumented. 0.5.0 release: * !!!! UPDATE DOCUMENTATION !!!! * Use clipped version of Pry.view() for large objects * Exit Pry session on ^d * Use Shellwords for breaking up parameters to pry commands * Use OptionParser to parse options for default pry commands * Add version command * Refactor 'status' command: add current method info * Add meth_name_from_binding utility lambda to commands.rb * Add -M, -m, -v(erbose), -a(ll), -s(uper), -l(ocals), -i(ivars), -k(klass vars) options to ls * add -i(nstance) option to show-method * add --help option to most commands * Get rid of ls_method and ls_imethods (subsumed by more powerful ls) * Get rid of show_idoc and show_imethod * Add special eval-file command that evals target file in current context pry-0.9.12.6/checksums.yaml.gz0000444000004100000410000000041612272154172016103 0ustar www-datawww-dataRe;@Yl`<4^ff hhL<zj E]z|u}<ϟ睝}6m! w:gU>wJHHV9Wkuh֐$kc4h x4LXt'1_X%{2n#'3cW>2(Xa [ʿ2ZpJd8[[^2pjE2 k29Tu+ qfaj0# pry-0.9.12.6/.document0000644000004100000410000000001412272154172014426 0ustar www-datawww-data- wiki/*.md