Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

adding READMEs and CHANGELOG etc

  • Loading branch information...
commit 2dc06b23c8bf269be2281bf2ae8e40990e75a156 1 parent a3399b9
John Mair banister authored
3  CHANGELOG
View
@@ -0,0 +1,3 @@
+8/12/2010 version 0.1.0
+* release!
+
105 README.markdown
View
@@ -0,0 +1,105 @@
+Pry
+=============
+
+(C) John Mair (banisterfiend) 2010
+
+_attach an irb-like session to any object_
+
+Pry is a simple Ruby REPL that specializes in interactively manipulates objects during the running of the program.
+
+Based on some ideas found in this [Ruby-Forum thread](http://www.ruby-forum.com/topic/179060)
+
+`Tweak` provides the `using` method.
+
+* Install the [gem](https://rubygems.org/gems/tweak): `gem install tweak`
+* Read the [documentation](http://rdoc.info/github/banister/tweak/master/file/README.markdown)
+* See the [source code](http://github.com/banister/tweak)
+
+example: using
+-------------------------
+
+With the `using` method we can enhance a core class for the duration
+of a block:
+
+ module Tweaks
+
+ class String
+ def hello
+ :hello
+ end
+ end
+
+ class Fixnum
+ Hello = :hello
+
+ def bye
+ :bye
+ end
+ end
+
+ end
+
+ using Tweaks do
+ "john".hello #=> :hello
+ 5.bye #=> :bye
+ Fixnum::Hello #=> :hello
+ end
+
+ "john".hello #=> NameError
+
+How it works
+--------------
+
+Makes use of the `Remix` and `Object2module` libraries. Note that `Tweak`
+modifies core classes by what is effectively a module inclusion, this
+means you cannot use `Tweak` to override existing functionality but
+more to augment and supplement that functionality.
+
+`Tweak` works by doing the following:
+
+* Looks for top-level classes and modules with the same name as those
+defined under the using-module.
+* Uses `Object2module` to include the corresponding class/module
+defined under the using-module into the top-level class/module of the
+same name.
+* Uses `Remix` to uninclude that functionality at the end of the
+`using` block.
+
+Also look at the [Remix](http://github.com/banister/remix) library's
+`temp_include` and `temp_extend` methods for a more general solution than `Tweak`.
+
+Thread Safety
+--------------
+
+`Tweak` is not threadsafe.
+
+Limitations
+-----------
+
+Does not work with nested modules, e.g `class String::SomethingElse`
+
+This is not intended to be a robust or serious solution, it's just a
+little experiment. :)
+
+Companion Libraries
+--------------------
+
+Tweak is one of a series of experimental libraries that mess with
+the internals of Ruby to bring new and interesting functionality to
+the language, see also:
+
+* [Remix](http://github.com/banister/remix) - Makes ancestor chains read/write
+* [Object2module](http://github.com/banister/object2module) - Enables you to include/extend Object/Classes.
+* [Include Complete](http://github.com/banister/include_complete) - Brings in
+ module singleton classes during an include. No more ugly ClassMethods and included() hook hacks.
+* [Prepend](http://github.com/banister/prepend) - Prepends modules in front of a class; so method lookup starts with the module
+* [GenEval](http://github.com/banister/gen_eval) - A strange new breed of instance_eval
+* [LocalEval](http://github.com/banister/local_eval) - instance_eval without changing self
+
+Contact
+-------
+
+Problems or questions contact me at [github](http://github.com/banister)
+
+
+
58 Rakefile
View
@@ -0,0 +1,58 @@
+dlext = Config::CONFIG['DLEXT']
+direc = File.dirname(__FILE__)
+
+require 'rake/clean'
+require 'rake/gempackagetask'
+require "#{direc}/lib/pry/version"
+
+CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
+CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
+ "ext/**/*~", "ext/**/*#*", "ext/**/*.obj",
+ "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
+
+def apply_spec_defaults(s)
+ s.name = "pry"
+ s.summary = "Open an irb-like session on any object"
+ s.version = Pry::VERSION
+ s.date = Time.now.strftime '%Y-%m-%d'
+ s.author = "John Mair (banisterfiend)"
+ s.email = 'jrmair@gmail.com'
+ s.description = s.summary
+ s.require_path = 'lib'
+ s.add_dependency("ruby_parser",">=2.0.5")
+ s.homepage = "http://banisterfiend.wordpress.com"
+ s.has_rdoc = 'yard'
+ s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
+ "test/*.rb", "CHANGELOG", "README.markdown", "Rakefile"]
+end
+
+task :test do
+ sh "bacon -k #{direc}/test/test.rb"
+end
+
+namespace :ruby do
+ spec = Gem::Specification.new do |s|
+ apply_spec_defaults(s)
+ s.platform = Gem::Platform::RUBY
+ end
+
+ Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.need_zip = false
+ pkg.need_tar = false
+ end
+end
+
+desc "build all platform gems at once"
+task :gems => [:rmgems, "ruby:gem"]
+
+desc "remove all platform gems"
+task :rmgems => ["ruby:clobber_package"]
+
+desc "build and push latest gems"
+task :pushgems => :gems do
+ chdir("#{direc}/pkg") do
+ Dir["*.gem"].each do |gemfile|
+ sh "gem push #{gemfile}"
+ end
+ end
+end
119 lib/pry.rb
View
@@ -3,66 +3,85 @@
require 'ruby_parser'
module Pry
- module RubyParserExtension
- def valid?(code)
- new.parse(code)
- rescue Racc::ParseError
- false
- else
- true
+ DEFAULT_PROMPT = proc { |v| "pry(#{v})> " }
+ DEFAULT_WAIT_PROMPT = proc { |v| "pry(#{v})* " }
+
+ # loop
+ def self.repl(target=TOPLEVEL_BINDING)
+ if !target.is_a?(Binding)
+ target = target.instance_eval { binding }
+ end
+
+ loop do
+ if catch(:pop) { rep(target) } == :return
+ return target.eval('self')
+ end
end
end
- def self.repl_loop(target=TOPLEVEL_BINDING)
- repl(target, :loop => true)
- end
+ # print
+ def self.rep(target=TOP_LEVEL_BINDING)
+ if !target.is_a?(Binding)
+ target = target.instance_eval { binding }
+ end
- def self.repl(target=TOPLEVEL_BINDING, options={:loop => false})
- prompt = ""
- code = proc do
- eval_string = ""
- while true
- if eval_string.empty?
- prompt = "> "
- else
- prompt = "* "
- end
-
- val = Readline.readline(prompt, true)
- eval_string += "#{val}\n"
+ value = re(target)
+ case value
+ when Exception
+ puts "#{value.class}: #{value.message}"
+ else
+ puts "=> #{value.inspect}"
+ end
+
+ end
- if val == "#"
- elsif val == "#pop"
- puts "Poppping back"
- return
- elsif (_, new_target = val.split(/#target\s*\=\s*/)).size > 1
- target = target.eval(new_target)
- eval_string = ""
- puts "Context changed to #{target}"
- break
- end
+ # eval
+ def self.re(target=TOPLEVEL_BINDING)
+ target.eval r(target)
+ rescue StandardError => e
+ e
+ end
- abort if val == "abort"
- exit if val == "exit"
- exit if val == "quit"
-
- break if RubyParser.valid?(eval_string)
- end
- begin
- puts "=> #{target.eval(eval_string).inspect}"
- rescue StandardError => e
- puts "#{e.message}"
- end
+ # read
+ def self.r(target=TOPLEVEL_BINDING)
+ eval_string = ""
+ loop do
+ val = Readline.readline(prompt(eval_string, target), true)
+ eval_string += "#{val}\n"
+ process_commands(val, eval_string)
+
+ break eval_string if valid_expression?(eval_string)
+ end
+ end
+
+ def self.process_commands(val, eval_string)
+ case val
+ when "exit", "quit"
+ exit
+ when "!"
+ eval_string.replace("")
+ puts "Refreshed REPL."
+ when "#pop"
+ puts "Popping up a context."
+ throw(:pop, :return)
end
+ end
- if options[:loop]
- loop(&code)
+ def self.prompt(eval_string, target)
+ context = target.eval('self')
+
+ if eval_string.empty?
+ DEFAULT_PROMPT.call(context)
else
- code.call
+ DEFAULT_WAIT_PROMPT.call(context)
end
end
-end
-class RubyParser
- extend Pry::RubyParserExtension
+ def self.valid_expression?(code)
+ RubyParser.new.parse(code)
+ rescue Racc::ParseError
+ false
+ else
+ true
+ end
end
3  lib/pry/version.rb
View
@@ -0,0 +1,3 @@
+module Pry
+ VERSION = "0.1.0"
+end
16 lib/target.rb
View
@@ -1,16 +0,0 @@
-require './pry'
-
-o = Object.new
-class << o
- def pig;
- puts "pig!!!"
- end
-
- def horse?
- puts "HORSEY LOL"
- end
-end
-
-5.times {
- pry(o)
-}
Please sign in to comment.
Something went wrong with that request. Please try again.