rexpl 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.rbc
6
+ doc/*
7
+ .yardoc/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use rbx-2.0.0pre@rexpl
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rexpl.gemspec
4
+ gemspec
@@ -0,0 +1,24 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ desc "Run Rexpl tests"
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "test"
8
+ t.test_files = FileList['test/**/*_test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ require 'yard'
13
+ YARD::Rake::YardocTask.new(:docs) do |t|
14
+ t.files = ['lib/**/*.rb']
15
+ t.options = ['-m', 'markdown', '--no-private', '-r', 'Readme.md', '--title', 'Rexpl documentation']
16
+ end
17
+ task :doc => [:docs]
18
+
19
+ desc "Generate and open class diagram (needs Graphviz installed)"
20
+ task :graph do |t|
21
+ `bundle exec yard graph -d --full --no-private | dot -Tpng -o graph.png && open graph.png`
22
+ end
23
+
24
+ task :default => [:test]
@@ -0,0 +1,67 @@
1
+ # rexpl
2
+
3
+ **rexpl** is a sandbox to experiment and play with the [Rubinius](http:://rubini.us)
4
+ Virtual Machine and its bytecode instructions. It comes wrapped in a REPL
5
+ (Read-Eval-Print Loop) à la IRB, so that anytime you can open a terminal,
6
+ fire up **rexpl**, and start playing with instant feedback.
7
+
8
+ This intends to be a fun tool to use when learning how to use Rubinius
9
+ bytecode instructions, for example when bootstraping a new language targeting
10
+ the Rubinius VM for the first time.
11
+
12
+ Its main feature is **stack introspection**, which means you can inspect
13
+ what the stack looks like after each step of your instruction set.
14
+
15
+ ## How to use it?
16
+
17
+ Needless to say, **rexpl** runs only on Rubinius. Thus, your first step is to
18
+ install it. Go to the [Rubinius website](http://rubini.us) to find how, or if
19
+ you are using RVM, just follow [this instructions](http://beginrescueend.com/interpreters/rbx/).
20
+
21
+ $ gem install rexpl
22
+ $ rexpl
23
+
24
+ Now you should see a welcome banner and an IRB-like prompt, and you're good to
25
+ go! Just start typing some [VM instructions](http://rubini.us/doc/en/virtual-machine/instructions/)
26
+ and see what happens!
27
+
28
+ There are three extra commands to take advantage of the stack introspection:
29
+
30
+ * `list` lists the instruction set of the current program.
31
+ * `reset` empties the instruction set and starts a new program.
32
+ * `draw` prints a visual representation of the stack after each instruction of
33
+ your program.
34
+
35
+ ## When to use it?
36
+
37
+ Imagine you are bootstrapping a new language targeting the Rubinius VM and you
38
+ just implemented a particular AST node, but when you try to run the tests, you
39
+ keep getting nasty stack validation errors. Net stack underflow? What the heck
40
+ does this even mean? Where the hell is that extra `pop`? Did this or that
41
+ instruction consume stack? Or maybe produce it? Oh fuck it, let's go fishing.
42
+
43
+ Don't panic. You always have your friends pen and paper ready to help you out,
44
+ Read through the source code, and knowing what each instruction does, try to
45
+ follow along and draw what the stack looks like at each step (does that sound
46
+ familiar to you?). Or just fire up **rexpl**.
47
+
48
+ ## Resources
49
+
50
+ Documentation is online here:
51
+
52
+ * [Rexpl documentation](http://rdoc.info/github/txus/rexpl/master/frames)
53
+
54
+ ##Note on Patches/Pull Requests
55
+
56
+ * Fork the project.
57
+ * Make your feature addition or bug fix.
58
+ * Add tests for it. This is important so I don't break it in a
59
+ future version unintentionally.
60
+ * Commit, do not mess with rakefile, version, or history.
61
+ If you want to have your own version, that is fine but bump version
62
+ in a commit by itself I can ignore when I pull.
63
+ * Send me a pull request. Bonus points for topic branches.
64
+
65
+ ## Copyright
66
+
67
+ Copyright (c) 2010 Josep M. Bach. See LICENSE for details.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env rbx
2
+ require 'rexpl'
3
+ Rexpl::Environment.run
@@ -0,0 +1,15 @@
1
+ # rexpl is an interactive bytecode console for the Rubinius VM.
2
+ #
3
+ # **rexpl** is a sandbox to experiment and play with the [Rubinius](http://rubini.us)
4
+ # Virtual Machine and its bytecode instructions. It comes wrapped in a REPL
5
+ # (Read-Eval-Print Loop) à la IRB, so that anytime you can open a terminal,
6
+ # fire up **rexpl**, and start playing with instant feedback.
7
+ #
8
+ module Rexpl
9
+ end
10
+
11
+ require 'rexpl/version'
12
+ require 'rexpl/generator_proxy'
13
+ require 'rexpl/generator_methods'
14
+ require 'rexpl/output'
15
+ require 'rexpl/environment'
@@ -0,0 +1,31 @@
1
+ module Rexpl
2
+ # This class represents the Environment holding a {GeneratorProxy} instance
3
+ # exposing the main entry point as a class method.
4
+ #
5
+ class Environment
6
+ @@generator = GeneratorProxy.new
7
+
8
+ class << self
9
+ # Fires up the REPL. This is the program's main entry point.
10
+ def run
11
+ Output.print_banner
12
+
13
+ while (Output.print_prompt; input = gets)
14
+ @@generator.instance_eval input.chomp
15
+
16
+ # After each new instruction, evaluate all of them.
17
+ dynamic_method(:run) do |g|
18
+ @@generator.visit(g)
19
+ if g.size == 0
20
+ g.push_nil
21
+ else
22
+ g.print_debug_info
23
+ end
24
+ g.ret
25
+ end
26
+ new.run
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,43 @@
1
+ module Rexpl
2
+ # Extends the Rubinius::Generator class with some utility methods used by
3
+ # Replx.
4
+ #
5
+ module GeneratorMethods
6
+ # Prints the topmost element on the stack and the stack's current size.
7
+ #
8
+ # Calling this method neither consumes nor produces stack, it's just used
9
+ # for debugging the current state.
10
+ def print_debug_info
11
+ initial_size = size
12
+ dup
13
+ push_const :Rexpl
14
+ find_const :Output
15
+ swap_stack
16
+ send :inspect, 0, true
17
+ push_literal initial_size
18
+ swap_stack
19
+ send :print_debug_info, 2, true
20
+ pop
21
+ end
22
+
23
+ # Returns an array with all the elements currently in the stack.
24
+ #
25
+ # Calling #return_stack increases by 1 the stack size (being the topmost
26
+ # element an array containing a duplicate of every other element in the
27
+ # stack).
28
+ def return_stack
29
+ initial_size = size
30
+ dup_many initial_size
31
+ make_array initial_size
32
+ end
33
+
34
+ # Returns the current size of the stack.
35
+ #
36
+ # @return [Fixnum] the current size of the stack.
37
+ def size
38
+ @current_block.instance_eval { @stack }
39
+ end
40
+ end
41
+ end
42
+
43
+ Rubinius::Generator.__send__ :include, Rexpl::GeneratorMethods
@@ -0,0 +1,116 @@
1
+ module Rexpl
2
+ # This class acts as a Proxy between the user and an actual Generator.
3
+ #
4
+ class GeneratorProxy
5
+ protected_methods = %w(class to_s inspect instance_eval tainted?)
6
+ # Undefine every method so that this class acts as an actual proxy.
7
+ instance_methods.each do |method|
8
+ unless method.to_s =~ /^_/ || protected_methods.include?(method.to_s)
9
+ undef_method method
10
+ end
11
+ end
12
+
13
+ attr_accessor :instructions
14
+
15
+ # Initializes a new {GeneratorProxy} instance with an empty instruction
16
+ # set.
17
+ def initialize
18
+ @instructions = []
19
+ end
20
+
21
+ # Swallows every message passed onto the instance and stores it in the
22
+ # instruction set.
23
+ def method_missing(method, *args)
24
+ @instructions << [method, *args]
25
+ nil
26
+ end
27
+
28
+ # Applies the set of instructions to an actual generator.
29
+ #
30
+ # It captures errors in case an instruction is unknown or called with wrong
31
+ # arguments.
32
+ #
33
+ # @param [Rubinius::Generator] generator the generator onto which apply the
34
+ # instructions.
35
+ #
36
+ # @example
37
+ #
38
+ # proxy = Rexpl::GeneratorProxy.new
39
+ # proxy.push 83
40
+ # proxy.push_literal 'bar'
41
+ #
42
+ # dynamic_method(:foo) do |g|
43
+ # proxy.visit(g)
44
+ # g.ret
45
+ # end
46
+ #
47
+ def visit(generator)
48
+ last_instruction = nil
49
+ begin
50
+ @instructions.each do |instruction|
51
+ last_instruction = instruction
52
+ generator.__send__ *instruction
53
+ end
54
+ rescue NameError, ArgumentError=>e
55
+ puts "[ERROR]: #{e}"
56
+ @instructions.delete(last_instruction)
57
+ end
58
+ end
59
+
60
+ # Empties the instruction set.
61
+ def reset
62
+ Output.print_reset
63
+ initialize
64
+ end
65
+
66
+ # Prints a list of the current instruction set.
67
+ def list
68
+ puts
69
+ @instructions.each_with_index do |instruction, idx|
70
+ Output.print_instruction instruction, idx
71
+ end
72
+ puts
73
+ end
74
+
75
+ # Visually represents the state of the stack after each instruction is ran.
76
+ def draw
77
+ instructions = @instructions.dup
78
+ klass = Class.new do
79
+ dynamic_method(:draw) do |g|
80
+
81
+ instructions.each_with_index do |instruction, idx|
82
+ # Execute the instruction
83
+ before = g.size
84
+ g.__send__ *instruction
85
+ after = g.size
86
+
87
+ # Print the instruction header
88
+ produced = after - before
89
+ verb = 'produced'
90
+ if produced < 0
91
+ verb = 'consumed'
92
+ produced = produced.abs
93
+ end
94
+ g.push_self
95
+ g.push_literal "[#{idx}] [#{instruction.first} #{instruction[1..-1].map(&:inspect).join(', ')}] #{verb} #{produced} stack, size is now #{after}"
96
+ g.send :puts, 1, true
97
+ g.pop
98
+
99
+ # Visually print the entire stack
100
+ g.return_stack
101
+ g.push_const :Rexpl
102
+ g.find_const :Output
103
+ g.swap_stack
104
+ g.send :print_stack, 1, true
105
+ g.pop
106
+ end
107
+
108
+ g.push_nil
109
+ g.ret
110
+ end
111
+ end
112
+
113
+ klass.new.draw
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,72 @@
1
+ require 'ansi'
2
+
3
+ module Rexpl
4
+ # Utility module to abstract output-related stuff, like printing banners or
5
+ # graphically representing stacks.
6
+ class Output
7
+ extend ANSI::Code
8
+
9
+ class << self
10
+ # Prints the welcome banner and a bit of instructions on how to use the
11
+ # interactive console.
12
+ def print_banner
13
+ puts
14
+ puts bold { red { "rexpl" } } + bold { " v#{Rexpl::VERSION}" } + " - interactive bytecode console for Rubinius"
15
+ puts bold { "--------------------------------------------------------" }
16
+ puts
17
+ print_rationale
18
+ end
19
+
20
+ # Prints the console prompt.
21
+ def print_prompt
22
+ print bold { '> ' }
23
+ end
24
+
25
+ # Prints a message indicating that the instruction set has been resetted.
26
+ def print_reset
27
+ puts "Reseted!"
28
+ end
29
+
30
+ # Prints the current size of the stack and the topmost value.
31
+ def print_debug_info(size, value)
32
+ puts "=> [" + bold { "Stack size: #{size}"} + "] " + "[" + bold { "Topmost value: #{value}" } + "]"
33
+ end
34
+
35
+ # Prints an instruction in a single row.
36
+ def print_instruction(instruction, idx)
37
+ puts bold { "[" } + blue { idx.to_s } + bold { "]" } + ": " + green { instruction.first } + " " + bold { instruction[1..-1].map(&:inspect) }
38
+ end
39
+
40
+ # Prints a stack out of an array of stack cells.
41
+ #
42
+ # @param [Array] cells the cells of the stack containing its values.
43
+ def print_stack(cells)
44
+ puts
45
+ puts "\t#{bold { 'Current stack' }.center(33, ' ')}"
46
+ puts "\t" + blue { "-------------------------" }
47
+ cells.reverse.each do |element|
48
+ puts "\t#{blue {"|"} }#{bold { element.inspect.center(23, ' ') }}#{blue {"|"}}"
49
+ puts "\t" + blue { "-------------------------" }
50
+ end
51
+ puts
52
+ end
53
+
54
+ # Prints a little readme to get people started when firing up the
55
+ # interactive console.
56
+ def print_rationale
57
+ puts "To start playing, just start typing some Rubinius VM instructions."
58
+ puts "You can find a complete list with documentation here:"
59
+ puts
60
+ puts "\thttp://rubini.us/doc/en/virtual-machine/instructions/"
61
+ puts
62
+ puts "To introspect the program you are writing, use the following commands,"
63
+ puts "or type " + bold { "exit" } + " to exit:"
64
+ puts
65
+ puts " " + bold { "list" } + " lists the instruction set of the current program."
66
+ puts " " + bold { "reset" } + " empties the instruction set and starts a new program."
67
+ puts " " + bold { "draw" } + " prints a visual representation of the stack after each instruction."
68
+ puts
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,4 @@
1
+ module Rexpl
2
+ # The current rexpl version.
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rexpl/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rexpl"
7
+ s.version = Rexpl::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Josep M. Bach"]
10
+ s.email = ["josep.m.bach@gmail.com"]
11
+ s.homepage = "http://github.com/txus/rexpl"
12
+ s.summary = %q{Rexpl is an interactive bytecode console for Rubinius}
13
+ s.description = %q{Rexpl is an interactive bytecode console for Rubinius}
14
+
15
+ s.rubyforge_project = "rexpl"
16
+
17
+ s.add_runtime_dependency "ansi"
18
+ s.add_development_dependency "minitest"
19
+ s.add_development_dependency "mocha"
20
+ s.add_development_dependency 'yard'
21
+ s.add_development_dependency 'bluecloth'
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
27
+ end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class EnvironmentTest < MiniTest::Unit::TestCase
4
+
5
+ def test_run
6
+ Rexpl::Output.stubs(:print_banner)
7
+ Rexpl::Output.stubs(:print_prompt)
8
+
9
+ Rexpl::Environment.expects(:gets).times(3).returns('noop', 'push 3', nil)
10
+
11
+ proxy = mock
12
+ Rexpl::Environment.class_variable_set(:@@generator, proxy)
13
+
14
+ proxy.expects(:instance_eval).with('noop')
15
+ proxy.expects(:instance_eval).with('push 3')
16
+ proxy.expects(:visit).with do |g|
17
+ assert_kind_of Rubinius::Generator, g
18
+ end.twice
19
+
20
+ Rexpl::Environment.run
21
+ end
22
+
23
+ end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ class GeneratorMethodsTest < MiniTest::Unit::TestCase
4
+
5
+ def test_print_debug_info
6
+ klass = Class.new do
7
+ dynamic_method :foo do |g|
8
+ g.push 5
9
+ g.push 6
10
+ g.print_debug_info
11
+ g.ret
12
+ end
13
+ end
14
+ Rexpl::Output.expects(:print_debug_info).with(2, '6')
15
+ result = klass.new.foo
16
+ assert_equal result, 6
17
+ end
18
+
19
+ def test_return_stack_returns_an_array_with_stack_cells
20
+ klass = Class.new do
21
+ dynamic_method :foo do |g|
22
+ g.push 3
23
+ g.push 6
24
+ g.return_stack
25
+ g.ret
26
+ end
27
+ end
28
+ assert_equal klass.new.foo, [3, 6]
29
+ end
30
+
31
+ def test_size_returns_size_of_the_stack
32
+ g = Rubinius::Generator.new
33
+ g.push 3
34
+ g.push 5
35
+ assert_equal 2, g.size
36
+ end
37
+
38
+ end
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+
3
+ class GeneratorProxyTest < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ @proxy = Rexpl::GeneratorProxy.new
7
+ end
8
+
9
+ def test_swallows_everything_with_its_args
10
+ @proxy.push 3
11
+ @proxy.foo
12
+ @proxy.bar
13
+ @proxy.whatever
14
+ @proxy.biwinning
15
+
16
+ assert_equal 5, @proxy.instructions.size
17
+ assert_equal [:push, 3], @proxy.instructions.first
18
+ end
19
+
20
+ def test_visit_executes_the_instructions
21
+ @proxy.push 3
22
+ @proxy.push_literal 'hey'
23
+
24
+ g = Rubinius::Generator.new
25
+ g.expects(:push).with(3)
26
+ g.expects(:push_literal).with('hey')
27
+
28
+ @proxy.visit(g)
29
+ end
30
+
31
+ def test_reset
32
+ @proxy.push 3
33
+ @proxy.push 5
34
+
35
+ Rexpl::Output.expects(:print_reset)
36
+
37
+ @proxy.reset
38
+
39
+ assert_equal 0, @proxy.instructions.size
40
+ end
41
+
42
+ def test_list
43
+ @proxy.push 3
44
+ @proxy.push 5
45
+
46
+ Rexpl::Output.expects(:print_instruction).with([:push, 3], 0)
47
+ Rexpl::Output.expects(:print_instruction).with([:push, 5], 1)
48
+
49
+ @proxy.list
50
+ end
51
+
52
+ def test_draw
53
+ @proxy.push 3
54
+ @proxy.push 5
55
+ @proxy.meta_send_op_plus 2
56
+
57
+ Rexpl::Output.expects(:print_stack).with([3])
58
+ Rexpl::Output.expects(:print_stack).with([3, 5])
59
+ Rexpl::Output.expects(:print_stack).with([8])
60
+
61
+ @proxy.draw
62
+ end
63
+
64
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+ require 'stringio'
3
+
4
+ class OutputTest < MiniTest::Unit::TestCase
5
+ def setup
6
+ $stdout = StringIO.new
7
+ end
8
+
9
+ def test_print_banner
10
+ Rexpl::Output.print_banner
11
+ assert_match /rexpl/, $stdout.string
12
+ end
13
+
14
+ def test_print_prompt
15
+ Rexpl::Output.print_prompt
16
+ assert_match />/, $stdout.string
17
+ end
18
+
19
+ def test_print_reset
20
+ Rexpl::Output.print_reset
21
+ assert_match /Reseted!/, $stdout.string
22
+ end
23
+
24
+ def test_print_debug_info
25
+ Rexpl::Output.print_debug_info("3", '"some_value"')
26
+ assert_match /Stack size: 3/, $stdout.string
27
+ assert_match /Topmost value: "some_value"/, $stdout.string
28
+ end
29
+
30
+ def test_print_instruction
31
+ instruction = ['send', ':puts', '1', 'true']
32
+
33
+ Rexpl::Output.print_instruction(instruction, 3)
34
+ assert_match /send/, $stdout.string
35
+ assert_match /:puts/, $stdout.string
36
+ assert_match /1/, $stdout.string
37
+ assert_match /true/, $stdout.string
38
+ assert_match /3/, $stdout.string
39
+ end
40
+
41
+ def test_print_stack
42
+ cells = %w(Rubinius 23)
43
+ Rexpl::Output.print_stack(cells)
44
+ assert_match /Current stack/, $stdout.string
45
+ assert_match /23/, $stdout.string
46
+ assert_match /Rubinius/, $stdout.string
47
+
48
+ # Rubinius should appear after 23, since cells are reversed
49
+ refute_match /Rubinius/, $stdout.string.split('23').first
50
+ assert_match /Rubinius/, $stdout.string.split('23').last
51
+ end
52
+
53
+ def test_print_rationale
54
+ Rexpl::Output.print_rationale
55
+ assert_match /list/, $stdout.string
56
+ assert_match /reset/, $stdout.string
57
+ assert_match /draw/, $stdout.string
58
+ end
59
+
60
+ def teardown
61
+ $stdout = STDOUT
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+
3
+ gem 'minitest'
4
+ require 'minitest/autorun'
5
+ require 'mocha'
6
+
7
+ require 'rexpl'
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rexpl
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Josep M. Bach
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-17 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ansi
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: minitest
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: mocha
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: yard
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: bluecloth
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ description: Rexpl is an interactive bytecode console for Rubinius
92
+ email:
93
+ - josep.m.bach@gmail.com
94
+ executables:
95
+ - rexpl
96
+ extensions: []
97
+
98
+ extra_rdoc_files: []
99
+
100
+ files:
101
+ - .gitignore
102
+ - .rvmrc
103
+ - Gemfile
104
+ - Rakefile
105
+ - Readme.md
106
+ - bin/rexpl
107
+ - lib/rexpl.rb
108
+ - lib/rexpl/environment.rb
109
+ - lib/rexpl/generator_methods.rb
110
+ - lib/rexpl/generator_proxy.rb
111
+ - lib/rexpl/output.rb
112
+ - lib/rexpl/version.rb
113
+ - rexpl.gemspec
114
+ - test/rexpl/environment_test.rb
115
+ - test/rexpl/generator_methods_test.rb
116
+ - test/rexpl/generator_proxy_test.rb
117
+ - test/rexpl/output_test.rb
118
+ - test/test_helper.rb
119
+ has_rdoc: true
120
+ homepage: http://github.com/txus/rexpl
121
+ licenses: []
122
+
123
+ post_install_message:
124
+ rdoc_options: []
125
+
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ hash: 3
134
+ segments:
135
+ - 0
136
+ version: "0"
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ hash: 3
143
+ segments:
144
+ - 0
145
+ version: "0"
146
+ requirements: []
147
+
148
+ rubyforge_project: rexpl
149
+ rubygems_version: 1.5.2
150
+ signing_key:
151
+ specification_version: 3
152
+ summary: Rexpl is an interactive bytecode console for Rubinius
153
+ test_files:
154
+ - test/rexpl/environment_test.rb
155
+ - test/rexpl/generator_methods_test.rb
156
+ - test/rexpl/generator_proxy_test.rb
157
+ - test/rexpl/output_test.rb
158
+ - test/test_helper.rb