pry 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+