binding_of_caller 0.7.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/.gemtest +0 -0
  3. data/.github/workflows/test.yml +108 -0
  4. data/.gitignore +12 -7
  5. data/.yardopts +0 -0
  6. data/Gemfile +6 -1
  7. data/LICENSE +0 -0
  8. data/README.md +17 -5
  9. data/Rakefile +4 -132
  10. data/binding_of_caller.gemspec +33 -35
  11. data/lib/binding_of_caller/jruby_interpreted.rb +123 -0
  12. data/lib/binding_of_caller/{mri2.rb → mri.rb} +8 -14
  13. data/lib/binding_of_caller/rubinius.rb +21 -28
  14. data/lib/binding_of_caller/version.rb +1 -1
  15. data/lib/binding_of_caller.rb +9 -10
  16. metadata +33 -109
  17. data/.travis.yml +0 -23
  18. data/HISTORY +0 -0
  19. data/examples/example.rb +0 -41
  20. data/ext/binding_of_caller/binding_of_caller.c +0 -225
  21. data/ext/binding_of_caller/extconf.rb +0 -33
  22. data/ext/binding_of_caller/ruby_headers/192/debug.h +0 -36
  23. data/ext/binding_of_caller/ruby_headers/192/dln.h +0 -41
  24. data/ext/binding_of_caller/ruby_headers/192/eval_intern.h +0 -232
  25. data/ext/binding_of_caller/ruby_headers/192/id.h +0 -173
  26. data/ext/binding_of_caller/ruby_headers/192/iseq.h +0 -104
  27. data/ext/binding_of_caller/ruby_headers/192/method.h +0 -103
  28. data/ext/binding_of_caller/ruby_headers/192/node.h +0 -483
  29. data/ext/binding_of_caller/ruby_headers/192/regenc.h +0 -211
  30. data/ext/binding_of_caller/ruby_headers/192/regint.h +0 -841
  31. data/ext/binding_of_caller/ruby_headers/192/regparse.h +0 -354
  32. data/ext/binding_of_caller/ruby_headers/192/rubys_gc.h +0 -77
  33. data/ext/binding_of_caller/ruby_headers/192/thread_pthread.h +0 -27
  34. data/ext/binding_of_caller/ruby_headers/192/thread_win32.h +0 -33
  35. data/ext/binding_of_caller/ruby_headers/192/timev.h +0 -21
  36. data/ext/binding_of_caller/ruby_headers/192/transcode_data.h +0 -109
  37. data/ext/binding_of_caller/ruby_headers/192/version.h +0 -55
  38. data/ext/binding_of_caller/ruby_headers/192/vm_core.h +0 -703
  39. data/ext/binding_of_caller/ruby_headers/192/vm_exec.h +0 -184
  40. data/ext/binding_of_caller/ruby_headers/192/vm_insnhelper.h +0 -208
  41. data/ext/binding_of_caller/ruby_headers/192/vm_opts.h +0 -51
  42. data/ext/binding_of_caller/ruby_headers/193/addr2line.h +0 -21
  43. data/ext/binding_of_caller/ruby_headers/193/atomic.h +0 -56
  44. data/ext/binding_of_caller/ruby_headers/193/constant.h +0 -34
  45. data/ext/binding_of_caller/ruby_headers/193/debug.h +0 -41
  46. data/ext/binding_of_caller/ruby_headers/193/dln.h +0 -50
  47. data/ext/binding_of_caller/ruby_headers/193/encdb.h +0 -167
  48. data/ext/binding_of_caller/ruby_headers/193/eval_intern.h +0 -234
  49. data/ext/binding_of_caller/ruby_headers/193/id.h +0 -175
  50. data/ext/binding_of_caller/ruby_headers/193/internal.h +0 -227
  51. data/ext/binding_of_caller/ruby_headers/193/iseq.h +0 -125
  52. data/ext/binding_of_caller/ruby_headers/193/method.h +0 -105
  53. data/ext/binding_of_caller/ruby_headers/193/node.h +0 -503
  54. data/ext/binding_of_caller/ruby_headers/193/parse.h +0 -186
  55. data/ext/binding_of_caller/ruby_headers/193/regenc.h +0 -219
  56. data/ext/binding_of_caller/ruby_headers/193/regint.h +0 -851
  57. data/ext/binding_of_caller/ruby_headers/193/regparse.h +0 -362
  58. data/ext/binding_of_caller/ruby_headers/193/revision.h +0 -1
  59. data/ext/binding_of_caller/ruby_headers/193/rubys_gc.h +0 -98
  60. data/ext/binding_of_caller/ruby_headers/193/thread_pthread.h +0 -51
  61. data/ext/binding_of_caller/ruby_headers/193/thread_win32.h +0 -40
  62. data/ext/binding_of_caller/ruby_headers/193/timev.h +0 -21
  63. data/ext/binding_of_caller/ruby_headers/193/transcode_data.h +0 -117
  64. data/ext/binding_of_caller/ruby_headers/193/transdb.h +0 -189
  65. data/ext/binding_of_caller/ruby_headers/193/version.h +0 -52
  66. data/ext/binding_of_caller/ruby_headers/193/vm_core.h +0 -755
  67. data/ext/binding_of_caller/ruby_headers/193/vm_exec.h +0 -184
  68. data/ext/binding_of_caller/ruby_headers/193/vm_insnhelper.h +0 -220
  69. data/ext/binding_of_caller/ruby_headers/193/vm_opts.h +0 -51
  70. data/test/test_binding_of_caller.rb +0 -161
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f3fb3c7ee20b9b9ca1237d0540c2768efc657111
4
- data.tar.gz: be4845aeca79432000b44be789993c23c1955715
2
+ SHA256:
3
+ metadata.gz: 0254f3b28703e0ce22f22a5835efdc9ac7f8d7756eb018c9700174d2dab1bf00
4
+ data.tar.gz: e87d62228e3eca329d9315c15f329a1d163be3ff7aee49702ddc604b4fe85e52
5
5
  SHA512:
6
- metadata.gz: 3fd5d2a9ffbda43fcc2d8afa739ec51052f5dacc8632c3e88b60b7be90c2bd67c8a813156dab341e9f3399e46db667f3a1246043d50f1f60b6654d5c07e4e93c
7
- data.tar.gz: 13fe3b6ab87052403c99be357fb91ea3ed2c9e9e5a8bafadc3123293bbb0a47bd7a235c67f7d25adb020f07bef0dee6d5a00424c7f59bf4c8b59dfc1f691d5c8
6
+ metadata.gz: 91989097e5c3d8420c2fc4cb8071a262879325cbe59d16f6bbb35cb86b0f2be42ab1d27b515c0497a4deea863d0f0f60b6e8dce446ce2c4bb777f7699e87d8e1
7
+ data.tar.gz: 13a9eb1a35130ba007dc12517cdac063e623faeef11d7533d57c6762fe25664ad224711d3902d10fe1c081c089c91314fd8c661720b15c6bcc02e3c873caba6e
data/.gemtest CHANGED
File without changes
@@ -0,0 +1,108 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ schedule:
7
+ - cron: '0 0 11,25 * *' # roughly every two weeks to run on new Ruby versions
8
+ pull_request:
9
+ branches: [ master ]
10
+ workflow_dispatch:
11
+
12
+ jobs:
13
+ test:
14
+ name: "Unit"
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ ruby:
20
+ - "2.1"
21
+ - "2.2"
22
+ - "2.3"
23
+ - "2.4"
24
+ - "2.5"
25
+ - "2.6"
26
+ - "2.7"
27
+ - "3.0"
28
+ - "3.1"
29
+ - "3.2"
30
+ exclude:
31
+ # 2.2 segfaults on recent Ubuntu: https://github.com/ruby/setup-ruby/issues/496
32
+ - { ruby: "2.2" }
33
+
34
+ steps:
35
+
36
+ - uses: actions/checkout@v2
37
+
38
+ - name: Set up Ruby
39
+ uses: ruby/setup-ruby@v1
40
+ with:
41
+ ruby-version: ${{ matrix.ruby }}
42
+ bundler-cache: true
43
+
44
+ - name: Test
45
+ run: bundle exec rspec -f doc
46
+
47
+ system:
48
+ name: "System"
49
+ runs-on: ${{ matrix.os }}
50
+ strategy:
51
+ fail-fast: false
52
+ matrix:
53
+ os:
54
+ - macos-latest
55
+ - ubuntu-latest
56
+ - windows-latest
57
+ ruby:
58
+ - "2"
59
+ - "3.0"
60
+ - "jruby"
61
+ - "truffleruby"
62
+ exclude:
63
+ # Windows releases of jruby and truffleruby have issues. Skip them for now.
64
+ - { ruby: "jruby", os: "windows-latest" }
65
+ - { ruby: "truffleruby", os: "windows-latest" }
66
+
67
+ steps:
68
+
69
+ - uses: actions/checkout@v2
70
+
71
+ - name: Determine ruby version name
72
+ id: ruby_version
73
+ run: |
74
+ if [[ $OS == 'windows-latest' && $RUBY == '3.0' ]]; then
75
+ # Windows doesn't have 3.0, so run head there but nowhere else.
76
+ echo "::set-output name=release::head"
77
+ else
78
+ echo "::set-output name=release::$RUBY"
79
+ fi
80
+ shell: bash
81
+ env:
82
+ OS: ${{ matrix.os }}
83
+ RUBY: ${{ matrix.ruby }}
84
+
85
+ - name: Set up Ruby
86
+ uses: ruby/setup-ruby@v1
87
+ with:
88
+ ruby-version: ${{ steps.ruby_version.outputs.release }}
89
+ bundler-cache: true
90
+
91
+ - name: Install gem
92
+ run: bundle exec rake install
93
+
94
+ - name: Create directory for gem test
95
+ run: mkdir -p tmp/gem-test
96
+
97
+ - name: Create test Gemfile
98
+ run: echo "gem 'binding_of_caller'" > Gemfile
99
+ working-directory: ./tmp/gem-test
100
+
101
+ - name: Test gem load
102
+ run: bundle exec ruby -e "require 'binding_of_caller'"
103
+
104
+ - name: Test gem functionality
105
+ if: ${{ matrix.ruby != 'jruby' && matrix.ruby != 'truffleruby' }}
106
+ run: bundle exec ruby -e "require 'binding_of_caller'; binding.of_caller(0).eval('var = :hello')"
107
+ env:
108
+ JRUBY_OPTS: "--dev" # This will support JRuby once the gem is updated to support JRuby 9.x
data/.gitignore CHANGED
@@ -1,8 +1,13 @@
1
- Makefile
2
- *.so
3
- *.o
4
- *.def
5
- doc/
6
- pkg/
7
- .yardoc/
8
1
  Gemfile.lock
2
+
3
+ /.bundle/
4
+ /.yardoc
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
data/.yardopts CHANGED
File without changes
data/Gemfile CHANGED
@@ -1,2 +1,7 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in binding_of_caller.gemspec
2
4
  gemspec
5
+
6
+ gem "rake"
7
+ gem "rspec"
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
- [![Build Status](https://secure.travis-ci.org/banister/binding_of_caller.png)](http://travis-ci.org/banister/binding_of_caller)
1
+ [![Build Status](https://github.com/banister/binding_of_caller/workflows/Test/badge.svg?branch=master&event=push)](https://github.com/banister/binding_of_caller/actions?query=branch%3Amaster)
2
+ [![Gem Version](https://img.shields.io/gem/v/binding_of_caller.svg)](https://rubygems.org/gems/binding_of_caller)
2
3
 
3
4
  binding_of_caller
4
- ===========
5
+ =================
5
6
 
6
7
  (C) John Mair (banisterfiend) 2012
7
8
 
8
- _Retrieve the binding of a method's caller in MRI 1.9.2+, MRI 2.0 and RBX (Rubinius)_
9
+ _Retrieve the binding of a method's caller in MRI (>= 2.0.0) and RBX (Rubinius)_
9
10
 
10
11
  The `binding_of_caller` gem provides the `Binding#of_caller` method.
11
12
 
@@ -15,7 +16,7 @@ call stack, not limited to just the immediate caller.
15
16
 
16
17
  **Recommended for use only in debugging situations. Do not use this in production apps.**
17
18
 
18
- **Only works in MRI Ruby 1.9.2, 1.9.3, 2.0 and RBX (Rubinius)**
19
+ **Works in MRI Ruby (>= 2.0) and RBX (Rubinius)**
19
20
 
20
21
  * Install the [gem](https://rubygems.org/gems/binding_of_caller): `gem install binding_of_caller`
21
22
  * See the [source code](http://github.com/banister/binding_of_caller)
@@ -52,8 +53,19 @@ This project is a spinoff from the [Pry REPL project.](http://pry.github.com)
52
53
  Features and limitations
53
54
  -------------------------
54
55
 
55
- * Only works with MRI 1.9.2, 1.9.3, 2.0 and RBX (Rubinius)
56
+ * Works in MRI (>= 2.0.0) and RBX (Rubinius)
57
+ * For MRI 1.9.x, use version "~> 0.8" of the gem, which included support for MRI before 2.0.
56
58
  * Does not work in 1.8.7, but there is a well known (continuation-based) hack to get a `Binding#of_caller` there.
59
+ * There is experimental support for jruby 1.7.x, but it only works in interpreted
60
+ mode (i.e. use the option `-Djruby.compile.mode=OFF` or append
61
+ `compile.mode=OFF` to your `.jrubyrc`)
62
+
63
+ Development
64
+ -----------
65
+
66
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
67
+
68
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
57
69
 
58
70
  Contact
59
71
  -------
data/Rakefile CHANGED
@@ -1,134 +1,6 @@
1
- dlext = RbConfig::CONFIG['DLEXT']
2
- direc = File.dirname(__FILE__)
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
3
 
4
- $:.unshift 'lib'
4
+ RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- require 'rake/clean'
7
- require 'rubygems/package_task'
8
-
9
- require "binding_of_caller/version"
10
-
11
- CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
12
- CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
13
- "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*#*", "**/*#*.*",
14
- "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake", "**/*.rbc")
15
-
16
- def mri_2?
17
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" &&
18
- RUBY_VERSION =~ /^2/
19
- end
20
-
21
- def apply_spec_defaults(s)
22
- s.name = "binding_of_caller"
23
- s.summary = "Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack."
24
- s.version = BindingOfCaller::VERSION
25
- s.date = Time.now.strftime '%Y-%m-%d'
26
- s.author = "John Mair (banisterfiend)"
27
- s.email = 'jrmair@gmail.com'
28
- s.description = s.summary
29
- s.require_path = 'lib'
30
- s.add_dependency 'debug_inspector', '>= 0.0.1'
31
- s.add_development_dependency 'bacon'
32
- s.add_development_dependency 'rake'
33
- s.homepage = "http://github.com/banister/binding_of_caller"
34
- s.has_rdoc = 'yard'
35
- s.files = `git ls-files`.split("\n")
36
- s.test_files = `git ls-files -- test/*`.split("\n")
37
- end
38
-
39
- desc "Show version"
40
- task :version do
41
- puts "BindingOfCaller version: #{BindingOfCaller::VERSION}"
42
- end
43
-
44
- desc "run tests"
45
- task :default => [:test]
46
-
47
- desc "Run tests"
48
- task :test do
49
- unless defined?(Rubinius)
50
- Rake::Task['compile'].execute
51
- end
52
-
53
- $stdout.puts("\033[33m")
54
- sh "bacon -Itest -rubygems -a -q"
55
- $stdout.puts("\033[0m")
56
-
57
- unless defined?(Rubinius)
58
- Rake::Task['cleanup'].execute
59
- end
60
- end
61
-
62
- task :pry do
63
- puts "loading binding_of_caller into pry"
64
- sh "pry -r ./lib/binding_of_caller"
65
- end
66
-
67
- desc "generate gemspec"
68
- task :gemspec => "ruby:gemspec"
69
-
70
- namespace :ruby do
71
- spec = Gem::Specification.new do |s|
72
- apply_spec_defaults(s)
73
- s.platform = Gem::Platform::RUBY
74
- s.extensions = ["ext/binding_of_caller/extconf.rb"]
75
- end
76
-
77
- Gem::PackageTask.new(spec) do |pkg|
78
- pkg.need_zip = false
79
- pkg.need_tar = false
80
- end
81
-
82
- desc "Generate gemspec file"
83
- task :gemspec do
84
- File.open("#{spec.name}.gemspec", "w") do |f|
85
- f << spec.to_ruby
86
- end
87
- end
88
- end
89
-
90
- desc "build the binaries"
91
- task :compile => :cleanup do
92
- if !mri_2?
93
- chdir "./ext/binding_of_caller/" do
94
- sh "ruby extconf.rb"
95
- sh "make"
96
- sh "cp *.#{dlext} ../../lib/"
97
- end
98
- end
99
- end
100
-
101
- desc 'cleanup the extensions'
102
- task :cleanup do
103
- if !mri_2?
104
- sh 'rm -rf lib/binding_of_caller.so'
105
- chdir "./ext/binding_of_caller/" do
106
- sh 'make clean'
107
- end
108
- end
109
- end
110
-
111
- desc "reinstall gem"
112
- task :reinstall => :gems do
113
- sh "gem uninstall binding_of_caller" rescue nil
114
- sh "gem install #{direc}/pkg/binding_of_caller-#{BindingOfCaller::VERSION}.gem"
115
- end
116
-
117
- task :install => :reinstall
118
-
119
- desc "build all platform gems at once"
120
- task :gems => [:clean, :rmgems, "ruby:gem"]
121
-
122
- task :gem => [:gems]
123
-
124
- desc "remove all platform gems"
125
- task :rmgems => ["ruby:clobber_package"]
126
-
127
- desc "build and push latest gems"
128
- task :pushgems => :gems do
129
- chdir("./pkg") do
130
- Dir["*.gem"].each do |gemfile|
131
- sh "gem push #{gemfile}"
132
- end
133
- end
134
- end
6
+ task :default => :spec
@@ -1,37 +1,35 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- Gem::Specification.new do |s|
4
- s.name = "binding_of_caller"
5
- s.version = "0.7.2"
6
-
7
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["John Mair (banisterfiend)"]
9
- s.date = "2013-06-07"
10
- s.description = "Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack."
11
- s.email = "jrmair@gmail.com"
12
- s.extensions = ["ext/binding_of_caller/extconf.rb"]
13
- s.files = [".gemtest", ".gitignore", ".travis.yml", ".yardopts", "Gemfile", "HISTORY", "LICENSE", "README.md", "Rakefile", "binding_of_caller.gemspec", "examples/example.rb", "ext/binding_of_caller/binding_of_caller.c", "ext/binding_of_caller/extconf.rb", "ext/binding_of_caller/ruby_headers/192/debug.h", "ext/binding_of_caller/ruby_headers/192/dln.h", "ext/binding_of_caller/ruby_headers/192/eval_intern.h", "ext/binding_of_caller/ruby_headers/192/id.h", "ext/binding_of_caller/ruby_headers/192/iseq.h", "ext/binding_of_caller/ruby_headers/192/method.h", "ext/binding_of_caller/ruby_headers/192/node.h", "ext/binding_of_caller/ruby_headers/192/regenc.h", "ext/binding_of_caller/ruby_headers/192/regint.h", "ext/binding_of_caller/ruby_headers/192/regparse.h", "ext/binding_of_caller/ruby_headers/192/rubys_gc.h", "ext/binding_of_caller/ruby_headers/192/thread_pthread.h", "ext/binding_of_caller/ruby_headers/192/thread_win32.h", "ext/binding_of_caller/ruby_headers/192/timev.h", "ext/binding_of_caller/ruby_headers/192/transcode_data.h", "ext/binding_of_caller/ruby_headers/192/version.h", "ext/binding_of_caller/ruby_headers/192/vm_core.h", "ext/binding_of_caller/ruby_headers/192/vm_exec.h", "ext/binding_of_caller/ruby_headers/192/vm_insnhelper.h", "ext/binding_of_caller/ruby_headers/192/vm_opts.h", "ext/binding_of_caller/ruby_headers/193/addr2line.h", "ext/binding_of_caller/ruby_headers/193/atomic.h", "ext/binding_of_caller/ruby_headers/193/constant.h", "ext/binding_of_caller/ruby_headers/193/debug.h", "ext/binding_of_caller/ruby_headers/193/dln.h", "ext/binding_of_caller/ruby_headers/193/encdb.h", "ext/binding_of_caller/ruby_headers/193/eval_intern.h", "ext/binding_of_caller/ruby_headers/193/id.h", "ext/binding_of_caller/ruby_headers/193/internal.h", "ext/binding_of_caller/ruby_headers/193/iseq.h", "ext/binding_of_caller/ruby_headers/193/method.h", "ext/binding_of_caller/ruby_headers/193/node.h", "ext/binding_of_caller/ruby_headers/193/parse.h", "ext/binding_of_caller/ruby_headers/193/regenc.h", "ext/binding_of_caller/ruby_headers/193/regint.h", "ext/binding_of_caller/ruby_headers/193/regparse.h", "ext/binding_of_caller/ruby_headers/193/revision.h", "ext/binding_of_caller/ruby_headers/193/rubys_gc.h", "ext/binding_of_caller/ruby_headers/193/thread_pthread.h", "ext/binding_of_caller/ruby_headers/193/thread_win32.h", "ext/binding_of_caller/ruby_headers/193/timev.h", "ext/binding_of_caller/ruby_headers/193/transcode_data.h", "ext/binding_of_caller/ruby_headers/193/transdb.h", "ext/binding_of_caller/ruby_headers/193/version.h", "ext/binding_of_caller/ruby_headers/193/vm_core.h", "ext/binding_of_caller/ruby_headers/193/vm_exec.h", "ext/binding_of_caller/ruby_headers/193/vm_insnhelper.h", "ext/binding_of_caller/ruby_headers/193/vm_opts.h", "lib/binding_of_caller.rb", "lib/binding_of_caller/mri2.rb", "lib/binding_of_caller/rubinius.rb", "lib/binding_of_caller/version.rb", "test/test_binding_of_caller.rb"]
14
- s.homepage = "http://github.com/banister/binding_of_caller"
15
- s.require_paths = ["lib"]
16
- s.rubygems_version = "2.0.3"
17
- s.summary = "Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack."
18
- s.test_files = ["test/test_binding_of_caller.rb"]
19
-
20
- if s.respond_to? :specification_version then
21
- s.specification_version = 4
22
-
23
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
- s.add_runtime_dependency(%q<debug_inspector>, [">= 0.0.1"])
25
- s.add_development_dependency(%q<bacon>, [">= 0"])
26
- s.add_development_dependency(%q<rake>, [">= 0"])
27
- else
28
- s.add_dependency(%q<debug_inspector>, [">= 0.0.1"])
29
- s.add_dependency(%q<bacon>, [">= 0"])
30
- s.add_dependency(%q<rake>, [">= 0"])
31
- end
32
- else
33
- s.add_dependency(%q<debug_inspector>, [">= 0.0.1"])
34
- s.add_dependency(%q<bacon>, [">= 0"])
35
- s.add_dependency(%q<rake>, [">= 0"])
1
+ require_relative 'lib/binding_of_caller/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "binding_of_caller"
5
+ spec.version = BindingOfCaller::VERSION
6
+ spec.authors = ["John Mair (banisterfiend)"]
7
+ spec.email = ["jrmair@gmail.com"]
8
+
9
+ spec.summary = %q{Retrieve the binding of a method's caller, or further up the stack.}
10
+ spec.description = <<-TXT
11
+ Provides the Binding#of_caller method.
12
+
13
+ Using binding_of_caller we can grab bindings from higher up the call stack and evaluate code in that context.
14
+ Allows access to bindings arbitrarily far up the call stack, not limited to just the immediate caller.
15
+
16
+ Recommended for use only in debugging situations. Do not use this in production apps.
17
+ TXT
18
+ spec.homepage = "https://github.com/banister/binding_of_caller"
19
+ spec.license = "MIT"
20
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.0.0")
21
+
22
+ spec.metadata = {
23
+ "changelog_uri" => "https://github.com/banister/binding_of_caller/releases",
24
+ }
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
29
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|examples|bin)/}) }
36
30
  end
31
+
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_dependency "debug_inspector", ">= 1.2.0"
37
35
  end
@@ -0,0 +1,123 @@
1
+ module BindingOfCaller
2
+ class JRubyBindingHolder
3
+ java_import org.jruby.RubyBinding
4
+
5
+ def initialize(binding)
6
+ @binding = binding
7
+ end
8
+
9
+ def eval(code, file = nil, line = nil)
10
+ b = JRuby.dereference(RubyBinding.new(JRuby.runtime, Binding, @binding))
11
+ if (file == nil)
12
+ Kernel.eval code, b
13
+ else
14
+ Kernel.eval code, b, file, line
15
+ end
16
+ end
17
+
18
+ def frame_type
19
+ case
20
+ when block?
21
+ :block
22
+ when eval?
23
+ :eval
24
+ when top?
25
+ :top
26
+ else
27
+ :method
28
+ end
29
+ end
30
+
31
+ def frame_description
32
+ "#{block_desc}#{method_desc}"
33
+ end
34
+
35
+ private
36
+
37
+ def block?
38
+ @binding.getDynamicScope().getStaticScope().isBlockScope()
39
+ end
40
+
41
+ def eval?
42
+ @binding.getFrame().getKlazz().nil? && @binding.getLine() != 0
43
+ end
44
+
45
+ def top?
46
+ @binding.getFrame().getKlazz().nil? && @binding.getLine() == 0
47
+ end
48
+
49
+ def block_desc
50
+ if frame_type == :block
51
+ "block in "
52
+ end
53
+ end
54
+
55
+ def method_desc
56
+ @binding.getFrame().getName() || "<main>"
57
+ end
58
+ end
59
+
60
+ module BindingExtensions
61
+ def of_caller(index = 1)
62
+ index += 1 # always omit this frame
63
+ JRuby.runtime.current_context.binding_of_caller(index)
64
+ end
65
+
66
+ def callers
67
+ ary = []
68
+ n = 2
69
+ while binding = of_caller(n)
70
+ ary << binding
71
+ n += 1
72
+ end
73
+ ary
74
+ end
75
+
76
+ def frame_count
77
+ callers.count - 1
78
+ end
79
+
80
+ def frame_type
81
+ nil
82
+ end
83
+
84
+ def frame_description
85
+ nil
86
+ end
87
+ end
88
+ end
89
+
90
+
91
+ class org::jruby::runtime::ThreadContext
92
+ java_import org.jruby.runtime.Binding
93
+ java_import org.jruby.RubyInstanceConfig::CompileMode
94
+
95
+ field_accessor :frameStack, :frameIndex,
96
+ :scopeStack, :scopeIndex,
97
+ :backtrace, :backtraceIndex
98
+
99
+ def binding_of_caller(index)
100
+ unless JRuby.runtime.instance_config.compile_mode == CompileMode::OFF
101
+ raise RuntimeError, "caller binding only supported in interpreter"
102
+ end
103
+
104
+ index += 1 # always omit this frame
105
+
106
+ return nil if index > frameIndex
107
+
108
+ frame = frameStack[frameIndex - index]
109
+
110
+ return binding_of_caller(index - 1) if index > scopeIndex
111
+
112
+ scope = scopeStack[scopeIndex - index]
113
+ element = backtrace[backtraceIndex - index]
114
+
115
+ binding = Binding.new(frame, scope.static_scope.module, scope, element.clone)
116
+
117
+ BindingOfCaller::JRubyBindingHolder.new(binding)
118
+ end
119
+ end
120
+
121
+ class ::Binding
122
+ include BindingOfCaller::BindingExtensions
123
+ end
@@ -17,25 +17,19 @@ module BindingOfCaller
17
17
  # @return [Array<Binding>]
18
18
  def callers
19
19
  ary = []
20
-
21
- RubyVM::DebugInspector.open do |i|
22
- n = 0
23
- loop do
24
- begin
25
- b = i.frame_binding(n)
26
- rescue ArgumentError
27
- break
28
- end
29
20
 
21
+ DebugInspector.open do |dc|
22
+ locs = dc.backtrace_locations
23
+
24
+ locs.size.times do |i|
25
+ b = dc.frame_binding(i)
30
26
  if b
31
- b.instance_variable_set(:@iseq, i.frame_iseq(n))
27
+ b.instance_variable_set(:@iseq, dc.frame_iseq(i))
32
28
  ary << b
33
29
  end
34
-
35
- n += 1
36
30
  end
37
31
  end
38
-
32
+
39
33
  ary.drop(1)
40
34
  end
41
35
 
@@ -49,7 +43,7 @@ module BindingOfCaller
49
43
  # @return [Symbol]
50
44
  def frame_type
51
45
  return nil if !@iseq
52
-
46
+
53
47
  # apparently the 9th element of the iseq array holds the frame type
54
48
  # ...not sure how reliable this is.
55
49
  @frame_type ||= @iseq.to_a[9]
@@ -4,22 +4,11 @@ module BindingOfCaller
4
4
  # Retrieve the binding of the nth caller of the current frame.
5
5
  # @return [Binding]
6
6
  def of_caller(n)
7
- bt = Rubinius::VM.backtrace(1 + n, true).first
7
+ location = Rubinius::VM.backtrace(1 + n, true).first
8
8
 
9
- raise RuntimeError, "Invalid frame, gone beyond end of stack!" if bt.nil?
9
+ raise RuntimeError, "Invalid frame, gone beyond end of stack!" if location.nil?
10
10
 
11
- b = Binding.setup(
12
- bt.variables,
13
- bt.variables.method,
14
- bt.constant_scope,
15
- bt.variables.self,
16
- bt
17
- )
18
-
19
- b.instance_variable_set :@frame_description,
20
- bt.describe.gsub("{ } in", "block in")
21
-
22
- b
11
+ setup_binding_from_location(location)
23
12
  end
24
13
 
25
14
  # The description of the frame.
@@ -31,25 +20,14 @@ module BindingOfCaller
31
20
  # Return bindings for all caller frames.
32
21
  # @return [Array<Binding>]
33
22
  def callers
34
- ary = []
35
- n = 0
36
- loop do
37
- begin
38
- ary << Binding.of_caller(n)
39
- rescue
40
- break
41
- end
42
- n += 1
43
- end
44
- ary.drop_while do |v|
45
- !(v.frame_type == :method && v.eval("__method__") == :callers)
46
- end.drop(1)
23
+ Rubinius::VM.backtrace(1, true).map &(method(:setup_binding_from_location).
24
+ to_proc)
47
25
  end
48
26
 
49
27
  # Number of parent frames available at the point of call.
50
28
  # @return [Fixnum]
51
29
  def frame_count
52
- callers.size - 1
30
+ Rubinius::VM.backtrace(1).count
53
31
  end
54
32
 
55
33
  # The type of the frame.
@@ -65,6 +43,21 @@ module BindingOfCaller
65
43
  :method
66
44
  end
67
45
  end
46
+
47
+ protected
48
+
49
+ def setup_binding_from_location(location)
50
+ binding = Binding.setup location.variables,
51
+ location.variables.method,
52
+ location.constant_scope,
53
+ location.variables.self,
54
+ location
55
+
56
+ binding.instance_variable_set :@frame_description,
57
+ location.describe.gsub("{ } in", "block in")
58
+
59
+ binding
60
+ end
68
61
  end
69
62
  end
70
63
 
@@ -1,3 +1,3 @@
1
1
  module BindingOfCaller
2
- VERSION = "0.7.2"
2
+ VERSION = "1.0.1"
3
3
  end