pry 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. data/CHANGELOG +3 -0
  2. data/README.markdown +133 -0
  3. data/Rakefile +58 -0
  4. data/lib/pry.rb +101 -0
  5. data/lib/pry/version.rb +3 -0
  6. metadata +82 -0
@@ -0,0 +1,3 @@
1
+ 8/12/2010 version 0.1.0
2
+ * release!
3
+
@@ -0,0 +1,133 @@
1
+ Pry
2
+ =============
3
+
4
+ (C) John Mair (banisterfiend) 2010
5
+
6
+ _attach an irb-like session to any object_
7
+
8
+ Pry is a simple Ruby REPL that specializes in the interactive
9
+ manipulation of objects during the running of a program.
10
+
11
+ * Install the [gem](https://rubygems.org/gems/pry): `gem install pry`
12
+ * Read the [documentation](http://rdoc.info/github/banister/pry/master/file/README.markdown)
13
+ * See the [source code](http://github.com/banister/pry)
14
+
15
+ example: prying on an object at runtime
16
+ ---------------------------------------
17
+
18
+ With the `Pry.into()` method we can pry (open an irb-like session) on
19
+ an object. In the example below we open a Pry session for the `Test` class and execute a method and add
20
+ an instance variable. The program is halted for the duration of the session.
21
+
22
+ require 'pry'
23
+
24
+ class Test
25
+ def self.hello() "hello world" end
26
+ end
27
+
28
+ Pry.into(Test)
29
+
30
+ # Pry session begins on stdin
31
+ Beginning Pry session for Test
32
+ pry(Test)> self
33
+ => Test
34
+ pry(Test)> hello
35
+ => "hello world"
36
+ pry(Test)> @y = 20
37
+ => 20
38
+ pry(Test)> exit
39
+ Ending Pry session for Test
40
+
41
+ # program resumes here
42
+
43
+ If we now inspect the `Test` object we can see our changes have had
44
+ effect:
45
+
46
+ Test.instance_variable_get(:@y) #=> 20
47
+
48
+
49
+ example: Pry sessions can nest arbitrarily deep so we can pry on objects inside objects:
50
+ ----------------------------------------------------------------------------------------
51
+
52
+ Here we will begin Pry at top-level, then pry on a class and then on
53
+ an instance variable inside that class:
54
+
55
+ # Pry.into() without parameters begins a Pry session on top-level (main)
56
+ Pry.into
57
+ Beginning Pry session for main
58
+ pry(main)> class Hello
59
+ pry(main)* @x = 20
60
+ pry(main)* end
61
+ => 20
62
+ pry(main)> Pry.into Hello
63
+ Beginning Pry session for Hello
64
+ pry(Hello)> instance_variables
65
+ => [:@x]
66
+ pry(Hello)> Pry.into @x
67
+ Beginning Pry session for 20
68
+ pry(20)> self + 10
69
+ => 30
70
+ pry(20)> exit
71
+ Ending Pry session for 20
72
+ pry(Hello)> exit
73
+ Ending Pry session for Hello
74
+ pry(main)> exit
75
+ Ending Pry session for main
76
+
77
+ # program resumes here
78
+
79
+
80
+ example: Spawn a separate thread so you can use `Pry` to manipulate an
81
+ object without halting the program.
82
+ ---------------------------------------------------------------------------------------------------
83
+
84
+ If we embed our `Pry.into` method inside its own thread we can examine
85
+ and manipulate objects without halting the program.
86
+
87
+ # Pry.into() without parameters opens up the top-level (main)
88
+ Thread.new { Pry.into }
89
+
90
+
91
+ Features and limitations
92
+ ------------------------
93
+
94
+ Pry is an irb-like clone with an emphasis on interactively examining
95
+ and manipulating objects during the running of a program.
96
+
97
+ Its primary utility is probably in debugging, though it may have other
98
+ uses (such as implementing a quake-like console for games, for example). Here is a
99
+ list of Pry's features along with some of its limitations given at the
100
+ end.
101
+
102
+ Features:
103
+
104
+ * Pry can be invoked at any time and on any object in the running program.
105
+ * Pry sessions can nest arbitrarily deeply -- to go back one level of nesting type 'exit' or 'quit'
106
+ * Pry has multi-line support built in.
107
+ * Pry implements all the methods in the REPL chain separately: `Pry.r`
108
+ for reading; `Pry.re` for eval; `Pry.rep` for printing; and `Pry.repl`
109
+ for the loop (`Pry.into` is simply an alias for `Pry.repl`). You can
110
+ invoke any of these methods directly depending on exactly what aspect of the functionality you need.
111
+
112
+ Limitations:
113
+
114
+ * Pry does not pretend to be a replacement for `irb`,
115
+ and so does not have an executable. It is designed to be used by
116
+ other programs, not on its own. For a full-featured `irb` replacement
117
+ see [ripl](https://github.com/cldwalker/ripl)
118
+ * Although Pry works fine in Ruby 1.9, only Ruby 1.8 syntax is
119
+ supported. This is because Pry uses the
120
+ [RubyParser](https://github.com/seattlerb/ruby_parser)
121
+ gem internally to validate expressions, and RubyParser, as yet, only parses Ruby 1.8
122
+ code. In practice this usually just means you cannot use the new
123
+ hash literal syntax (this: syntax) or the 'stabby lambda' syntax
124
+ (->).
125
+
126
+
127
+ Contact
128
+ -------
129
+
130
+ Problems or questions contact me at [github](http://github.com/banister)
131
+
132
+
133
+
@@ -0,0 +1,58 @@
1
+ dlext = Config::CONFIG['DLEXT']
2
+ direc = File.dirname(__FILE__)
3
+
4
+ require 'rake/clean'
5
+ require 'rake/gempackagetask'
6
+ require "#{direc}/lib/pry/version"
7
+
8
+ CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
9
+ CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
10
+ "ext/**/*~", "ext/**/*#*", "ext/**/*.obj",
11
+ "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
12
+
13
+ def apply_spec_defaults(s)
14
+ s.name = "pry"
15
+ s.summary = "attach an irb-like session to any object"
16
+ s.version = Pry::VERSION
17
+ s.date = Time.now.strftime '%Y-%m-%d'
18
+ s.author = "John Mair (banisterfiend)"
19
+ s.email = 'jrmair@gmail.com'
20
+ s.description = s.summary
21
+ s.require_path = 'lib'
22
+ s.add_dependency("ruby_parser",">=2.0.5")
23
+ s.homepage = "http://banisterfiend.wordpress.com"
24
+ s.has_rdoc = 'yard'
25
+ s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
26
+ "test/*.rb", "CHANGELOG", "README.markdown", "Rakefile"]
27
+ end
28
+
29
+ task :test do
30
+ sh "bacon -k #{direc}/test/test.rb"
31
+ end
32
+
33
+ namespace :ruby do
34
+ spec = Gem::Specification.new do |s|
35
+ apply_spec_defaults(s)
36
+ s.platform = Gem::Platform::RUBY
37
+ end
38
+
39
+ Rake::GemPackageTask.new(spec) do |pkg|
40
+ pkg.need_zip = false
41
+ pkg.need_tar = false
42
+ end
43
+ end
44
+
45
+ desc "build all platform gems at once"
46
+ task :gems => [:rmgems, "ruby:gem"]
47
+
48
+ desc "remove all platform gems"
49
+ task :rmgems => ["ruby:clobber_package"]
50
+
51
+ desc "build and push latest gems"
52
+ task :pushgems => :gems do
53
+ chdir("#{direc}/pkg") do
54
+ Dir["*.gem"].each do |gemfile|
55
+ sh "gem push #{gemfile}"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,101 @@
1
+ require 'rubygems'
2
+ require 'readline'
3
+ require 'ruby_parser'
4
+
5
+ module Pry
6
+ class << self
7
+ attr_accessor :default_prompt, :wait_prompt,
8
+ :session_start_msg, :session_end_msg
9
+ end
10
+
11
+ @default_prompt = proc { |v| "pry(#{v})> " }
12
+ @wait_prompt = proc { |v| "pry(#{v})* " }
13
+ @session_start_msg = proc { |v| "Beginning Pry session for #{v}" }
14
+ @session_end_msg = proc { |v| "Ending Pry session for #{v}" }
15
+
16
+ # loop
17
+ def self.repl(target=TOPLEVEL_BINDING)
18
+ if !target.is_a?(Binding)
19
+ target = target.instance_eval { binding }
20
+ end
21
+
22
+ puts session_start_msg.call(target.eval('self'))
23
+
24
+ loop do
25
+ if catch(:pop) { rep(target) } == :return
26
+ break target.eval('self')
27
+ end
28
+ end
29
+
30
+ puts session_end_msg.call(target.eval('self'))
31
+ end
32
+
33
+ class << self
34
+ alias_method :into, :repl
35
+ alias_method :start, :repl
36
+ end
37
+
38
+ # print
39
+ def self.rep(target=TOPLEVEL_BINDING)
40
+ if !target.is_a?(Binding)
41
+ target = target.instance_eval { binding }
42
+ end
43
+
44
+ value = re(target)
45
+ case value
46
+ when Exception
47
+ puts "#{value.class}: #{value.message}"
48
+ else
49
+ puts "=> #{value.inspect}"
50
+ end
51
+ end
52
+
53
+ # eval
54
+ def self.re(target=TOPLEVEL_BINDING)
55
+ target.eval r(target)
56
+ rescue StandardError => e
57
+ e
58
+ end
59
+
60
+ # read
61
+ def self.r(target=TOPLEVEL_BINDING)
62
+ eval_string = ""
63
+ loop do
64
+ val = Readline.readline(prompt(eval_string, target), true)
65
+ eval_string += "#{val}\n"
66
+ process_commands(val, eval_string, target)
67
+
68
+ break eval_string if valid_expression?(eval_string)
69
+ end
70
+ end
71
+
72
+ def self.process_commands(val, eval_string, target)
73
+ case val
74
+ when "#exit", "#quit"
75
+ exit
76
+ when "!"
77
+ eval_string.replace("")
78
+ puts "Refreshed REPL."
79
+ when "exit", "quit"
80
+ throw(:pop, :return)
81
+ end
82
+ end
83
+
84
+ def self.prompt(eval_string, target)
85
+ context = target.eval('self')
86
+
87
+ if eval_string.empty?
88
+ default_prompt.call(context)
89
+ else
90
+ wait_prompt.call(context)
91
+ end
92
+ end
93
+
94
+ def self.valid_expression?(code)
95
+ RubyParser.new.parse(code)
96
+ rescue Racc::ParseError
97
+ false
98
+ else
99
+ true
100
+ end
101
+ end
@@ -0,0 +1,3 @@
1
+ module Pry
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pry
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - John Mair (banisterfiend)
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-09 00:00:00 +13:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: ruby_parser
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 0
31
+ - 5
32
+ version: 2.0.5
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: attach an irb-like session to any object
36
+ email: jrmair@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - lib/pry/version.rb
45
+ - lib/pry.rb
46
+ - CHANGELOG
47
+ - README.markdown
48
+ - Rakefile
49
+ has_rdoc: yard
50
+ homepage: http://banisterfiend.wordpress.com
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.7
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: attach an irb-like session to any object
81
+ test_files: []
82
+