binding_of_caller 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ Makefile
2
+ *.so
3
+ *.o
4
+ *.def
5
+ doc/
6
+ pkg/
7
+ .yardoc/
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ License
2
+ -------
3
+
4
+ (The MIT License)
5
+
6
+ Copyright (c) 2011 John Mair (banisterfiend)
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ 'Software'), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,11 +1,12 @@
1
1
  dlext = Config::CONFIG['DLEXT']
2
- direc = File.dirname(__FILE__)
2
+
3
+ $:.unshift 'lib'
3
4
 
4
5
  PROJECT_NAME = "binding_of_caller"
5
6
 
6
7
  require 'rake/clean'
7
8
  require 'rake/gempackagetask'
8
- require "#{direc}/lib/#{PROJECT_NAME}/version"
9
+ require "#{PROJECT_NAME}/version"
9
10
 
10
11
  CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
11
12
  CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
@@ -14,77 +15,57 @@ CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
14
15
 
15
16
  def apply_spec_defaults(s)
16
17
  s.name = PROJECT_NAME
17
- s.summary = "FIX ME"
18
+ s.summary = "Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack. Currently only works for MRI 1.9.2."
18
19
  s.version = BindingOfCaller::VERSION
19
20
  s.date = Time.now.strftime '%Y-%m-%d'
20
21
  s.author = "John Mair (banisterfiend)"
21
22
  s.email = 'jrmair@gmail.com'
22
23
  s.description = s.summary
23
24
  s.require_path = 'lib'
24
- s.add_development_dependency("bacon",">=1.1.0")
25
- s.homepage = "http://banisterfiend.wordpress.com"
25
+ s.add_development_dependency("bacon","~>1.1.0")
26
+ s.homepage = "http://github.com/banister/binding_of_caller"
26
27
  s.has_rdoc = 'yard'
27
- s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
28
- "test/*.rb", "HISTORY", "README.md", "Rakefile"]
28
+ s.files = `git ls-files`.split("\n")
29
+ s.test_files = `git ls-files -- test/*`.split("\n")
29
30
  end
30
31
 
31
- desc "run tests"
32
+ desc "Run tests"
32
33
  task :test do
33
- sh "bacon -k #{direc}/test/test.rb"
34
+ sh "bacon -Itest -rubygems test.rb -q"
34
35
  end
35
36
 
36
- [:mingw32, :mswin32].each do |v|
37
- namespace v do
38
- spec = Gem::Specification.new do |s|
39
- apply_spec_defaults(s)
40
- s.platform = "i386-#{v}"
41
- s.files += FileList["lib/**/*.#{dlext}"].to_a
42
- end
43
-
44
- Rake::GemPackageTask.new(spec) do |pkg|
45
- pkg.need_zip = false
46
- pkg.need_tar = false
47
- end
48
- end
37
+ task :pry do
38
+ puts "loading binding_of_caller into pry"
39
+ sh "pry -r ./lib/binding_of_caller"
49
40
  end
50
41
 
51
42
  namespace :ruby do
52
43
  spec = Gem::Specification.new do |s|
53
- apply_spec_defaults(s)
44
+ apply_spec_defaults(s)
54
45
  s.platform = Gem::Platform::RUBY
55
46
  s.extensions = ["ext/#{PROJECT_NAME}/extconf.rb"]
56
47
  end
57
-
48
+
58
49
  Rake::GemPackageTask.new(spec) do |pkg|
59
50
  pkg.need_zip = false
60
51
  pkg.need_tar = false
61
52
  end
62
53
  end
63
54
 
64
- directories = ["#{direc}/lib/1.8", "#{direc}/lib/1.9"]
65
- directories.each { |d| directory d }
66
-
67
- desc "build the 1.8 and 1.9 binaries from source and copy to lib/"
68
- task :compile => directories do
69
- build_for = proc do |pik_ver, ver|
70
- sh %{ \
71
- c:\\devkit\\devkitvars.bat && \
72
- pik #{pik_ver} && \
73
- ruby extconf.rb && \
74
- make clean && \
75
- make && \
76
- cp *.so #{direc}/lib/#{ver} \
77
- }
78
- end
79
-
80
- chdir("#{direc}/ext/#{PROJECT_NAME}") do
81
- build_for.call("187", "1.8")
82
- build_for.call("192", "1.9")
55
+ desc "build the biinaries"
56
+ task :compile do
57
+ chdir "./ext/#{PROJECT_NAME}/" do
58
+ sh "ruby extconf.rb"
59
+ sh "make clean"
60
+ sh "make"
61
+ sh "cp *.#{dlext} ../../lib/"
83
62
  end
84
63
  end
85
64
 
86
65
  desc "build all platform gems at once"
87
- task :gems => [:clean, :rmgems, "mingw32:gem", "mswin32:gem", "ruby:gem"]
66
+ task :gems => [:clean, :rmgems, "ruby:gem"]
67
+
68
+ task :gem => [:gems]
88
69
 
89
70
  desc "remove all platform gems"
90
71
  task :rmgems => ["ruby:clobber_package"]
@@ -1,22 +1,15 @@
1
1
  /* (c) 2011 John Mair (banisterfiend), MIT license */
2
2
 
3
3
  #include <ruby.h>
4
- //#include "compat.h"
5
4
 
6
- //#ifdef RUBY_19
7
5
  # include <ruby/io.h>
8
6
  # include <ruby/re.h>
9
7
  # include "vm_core.h"
10
8
  # include "gc.h"
11
- /* #else */
12
- /* # include "re.h" */
13
- /* # include "env.h" */
14
- /* # include "node.h" */
15
- /* # include "rubysig.h" */
16
- /* # include "rubyio.h" */
17
- /* #endif */
18
9
 
19
- extern rb_thread_t *ruby_current_thread;
10
+ typedef enum { false, true } bool;
11
+
12
+ const int max_frame_errors = 4;
20
13
 
21
14
  static size_t
22
15
  binding_memsize(const void *ptr)
@@ -65,8 +58,6 @@ binding_alloc(VALUE klass)
65
58
  return obj;
66
59
  }
67
60
 
68
- typedef enum { false, true } bool;
69
-
70
61
  static bool valid_frame_p(rb_control_frame_t * cfp) {
71
62
  return cfp->iseq && !NIL_P(cfp->self);
72
63
  }
@@ -74,7 +65,7 @@ static bool valid_frame_p(rb_control_frame_t * cfp) {
74
65
  static rb_control_frame_t * find_valid_frame(rb_control_frame_t * cfp) {
75
66
  int error_count = 0;
76
67
 
77
- while (error_count <= 4) {
68
+ while (error_count <= max_frame_errors) {
78
69
  cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
79
70
 
80
71
  if (valid_frame_p(cfp))
@@ -95,9 +86,11 @@ static VALUE binding_of_caller(VALUE self, VALUE rb_level)
95
86
  rb_control_frame_t *cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
96
87
  int level = FIX2INT(rb_level);
97
88
 
89
+ // attempt to locate the nth parent control frame
98
90
  for (int i = 0; i < level; i++)
99
91
  cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
100
92
 
93
+ // if did not find a valid one, then search for a valid one
101
94
  if (!valid_frame_p(cfp))
102
95
  cfp = find_valid_frame(cfp);
103
96
 
@@ -118,7 +111,9 @@ static VALUE binding_of_caller(VALUE self, VALUE rb_level)
118
111
  void
119
112
  Init_binding_of_caller()
120
113
  {
121
- rb_define_method(rb_cObject, "binding_of_caller", binding_of_caller, 1);
114
+ VALUE mBindingOfCaller = rb_define_module("BindingOfCaller");
122
115
 
116
+ rb_define_method(mBindingOfCaller, "of_caller", binding_of_caller, 1);
117
+ rb_include_module(rb_cBinding, mBindingOfCaller);
123
118
  }
124
119
 
@@ -0,0 +1,39 @@
1
+ require './binding_of_caller'
2
+
3
+ outer = 10
4
+
5
+ class Z
6
+ def z
7
+ u = 10
8
+ A.new.a
9
+ end
10
+ end
11
+
12
+ class A
13
+ def a
14
+ y = 10
15
+ B.new.b
16
+ end
17
+ end
18
+
19
+ class B
20
+ def b
21
+ x = 10
22
+ puts binding_of_caller(0).eval('local_variables')
23
+ puts binding_of_caller(1).eval('local_variables')
24
+ puts binding_of_caller(2).eval('local_variables')
25
+ puts binding_of_caller(3).eval('local_variables')
26
+ puts binding_of_caller(400).eval('local_variables')
27
+ end
28
+ end
29
+
30
+ def a; b; end; def b; binding_of_caller(10); end; a;
31
+
32
+ # Z.new.z
33
+
34
+ # output:
35
+ # => x
36
+ # => y
37
+ # => u
38
+ # => outer
39
+ # Exception
@@ -1,3 +1,3 @@
1
1
  module BindingOfCaller
2
- VERSION = "0.2.0"
3
- end
2
+ VERSION = "0.3.0"
3
+ end
data/test/test.rb CHANGED
@@ -1,12 +1,59 @@
1
- direc = File.dirname(__FILE__)
2
-
3
- require 'rubygems'
4
- require "#{direc}/../lib/binding_of_caller"
5
- require 'bacon'
1
+ unless Object.const_defined? :BindingOfCaller
2
+ $:.unshift File.expand_path '../../lib', __FILE__
3
+ require 'binding_of_caller'
4
+ require 'binding_of_caller/version'
5
+ end
6
6
 
7
- puts "Testing binding_of_caller version #{BindingOfCaller::VERSION}..."
7
+ puts "Testing binding_of_caller version #{BindingOfCaller::VERSION}..."
8
8
  puts "Ruby version: #{RUBY_VERSION}"
9
9
 
10
10
  describe BindingOfCaller do
11
+ it "should fetch immediate caller's binding when 0 is passed" do
12
+ o = Object.new
13
+ def o.a
14
+ var = 1
15
+ binding.of_caller(0).eval('var')
16
+ end
17
+
18
+ o. a.should == 1
19
+ end
20
+
21
+ it "should fetch parent of caller's binding when 1 is passed" do
22
+ o = Object.new
23
+ def o.a
24
+ var = 1
25
+ b
26
+ end
27
+
28
+ def o.b
29
+ binding.of_caller(1).eval('var')
30
+ end
31
+
32
+ o.a.should == 1
33
+ end
34
+
35
+ it "should modify locals in parent of caller's binding" do
36
+ o = Object.new
37
+ def o.a
38
+ var = 1
39
+ b
40
+ var
41
+ end
42
+
43
+ def o.b
44
+ binding.of_caller(1).eval('var = 20')
45
+ end
46
+
47
+ o.a.should == 20
48
+ end
49
+
50
+ it "should raise an exception when retrieving an out of band binding" do
51
+ o = Object.new
52
+ def o.a
53
+ binding.of_caller(100)
54
+ end
55
+
56
+ lambda { o.a }.should.raise RuntimeError
57
+ end
11
58
  end
12
59
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: binding_of_caller
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.0
5
+ version: 0.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - John Mair (banisterfiend)
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-10-17 00:00:00 Z
13
+ date: 2011-10-18 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bacon
@@ -18,12 +18,12 @@ dependencies:
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
- - - ">="
21
+ - - ~>
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.1.0
24
24
  type: :development
25
25
  version_requirements: *id001
26
- description: FIX ME
26
+ description: Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack. Currently only works for MRI 1.9.2.
27
27
  email: jrmair@gmail.com
28
28
  executables: []
29
29
 
@@ -32,8 +32,17 @@ extensions:
32
32
  extra_rdoc_files: []
33
33
 
34
34
  files:
35
- - ext/binding_of_caller/extconf.rb
35
+ - .gemtest
36
+ - .gitignore
37
+ - .yardopts
38
+ - HISTORY
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - ext/binding_of_caller/binding_of_caller.c
36
43
  - ext/binding_of_caller/compat.h
44
+ - ext/binding_of_caller/example.rb
45
+ - ext/binding_of_caller/extconf.rb
37
46
  - ext/binding_of_caller/ruby_headers/192/debug.h
38
47
  - ext/binding_of_caller/ruby_headers/192/dln.h
39
48
  - ext/binding_of_caller/ruby_headers/192/eval_intern.h
@@ -82,14 +91,9 @@ files:
82
91
  - ext/binding_of_caller/ruby_headers/193/vm_exec.h
83
92
  - ext/binding_of_caller/ruby_headers/193/vm_insnhelper.h
84
93
  - ext/binding_of_caller/ruby_headers/193/vm_opts.h
85
- - ext/binding_of_caller/binding_of_caller.c
86
94
  - lib/binding_of_caller/version.rb
87
- - lib/binding_of_caller.rb
88
95
  - test/test.rb
89
- - HISTORY
90
- - README.md
91
- - Rakefile
92
- homepage: http://banisterfiend.wordpress.com
96
+ homepage: http://github.com/banister/binding_of_caller
93
97
  licenses: []
94
98
 
95
99
  post_install_message:
@@ -115,6 +119,6 @@ rubyforge_project:
115
119
  rubygems_version: 1.8.11
116
120
  signing_key:
117
121
  specification_version: 3
118
- summary: FIX ME
119
- test_files: []
120
-
122
+ summary: Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack. Currently only works for MRI 1.9.2.
123
+ test_files:
124
+ - test/test.rb
@@ -1,22 +0,0 @@
1
- # binding_of_caller.rb
2
- # (C) John Mair (banisterfiend); MIT license
3
-
4
- direc = File.dirname(__FILE__)
5
-
6
- require "#{direc}/binding_of_caller/version"
7
-
8
- begin
9
- if RUBY_VERSION =~ /1.9/
10
- require "#{direc}/1.9/binding_of_caller"
11
- else
12
- require "#{direc}/1.8/binding_of_caller"
13
- end
14
- rescue LoadError => e
15
- require "rbconfig"
16
- dlext = Config::CONFIG['DLEXT']
17
- require "#{direc}/binding_of_caller.#{dlext}"
18
- end
19
-
20
- module BindingOfCaller
21
- end
22
-