binding_of_caller 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +33 -8
- data/Rakefile +2 -2
- data/examples/example.rb +41 -0
- data/ext/binding_of_caller/binding_of_caller.c +4 -4
- data/lib/binding_of_caller/version.rb +1 -1
- metadata +2 -3
- data/ext/binding_of_caller/compat.h +0 -57
- data/ext/binding_of_caller/example.rb +0 -39
data/README.md
CHANGED
@@ -3,25 +3,50 @@ binding_of_caller
|
|
3
3
|
|
4
4
|
(C) John Mair (banisterfiend) 2011
|
5
5
|
|
6
|
-
|
6
|
+
_Retrieve the binding of a method's caller in MRI 1.9.2_
|
7
7
|
|
8
|
-
|
8
|
+
The `binding_of_caller` gem provides the `Binding#of_caller` method.
|
9
|
+
|
10
|
+
Using `binding_of_caller` we can grab bindings from higher up the call
|
11
|
+
stack and evaluate code in that context. Allows access to bindings arbitrarily far up the
|
12
|
+
call stack, not limited to just the immediate caller.
|
13
|
+
|
14
|
+
**Recommended for use only in debugging situations. Do not use this in production apps.**
|
15
|
+
|
16
|
+
**Only works in MRI Ruby 1.9.2**
|
9
17
|
|
10
18
|
* Install the [gem](https://rubygems.org/gems/binding_of_caller): `gem install binding_of_caller`
|
11
|
-
* Read the [documentation](http://rdoc.info/github/banister/binding_of_caller/master/file/README.markdown)
|
12
19
|
* See the [source code](http://github.com/banister/binding_of_caller)
|
13
20
|
|
14
|
-
Example:
|
21
|
+
Example: Modifying a local inside the caller of a caller
|
15
22
|
--------
|
16
23
|
|
17
|
-
|
24
|
+
def a
|
25
|
+
var = 10
|
26
|
+
b
|
27
|
+
puts var
|
28
|
+
end
|
29
|
+
|
30
|
+
def b
|
31
|
+
c
|
32
|
+
end
|
33
|
+
|
34
|
+
def c
|
35
|
+
binding.of_caller(2).eval('var = :hello')
|
36
|
+
end
|
37
|
+
|
38
|
+
a()
|
18
39
|
|
19
|
-
|
40
|
+
# OUTPUT
|
41
|
+
# => hello
|
20
42
|
|
21
43
|
Features and limitations
|
22
44
|
-------------------------
|
23
45
|
|
24
|
-
|
46
|
+
* Only works with MRI 1.9.2
|
47
|
+
* Broken in 1.9.3, support will hopefully be provided in the near
|
48
|
+
* future.
|
49
|
+
* Does not work in 1.8.7, but there is a well known (continuation-based) hack to get a `Binding#of_caller` there.
|
25
50
|
|
26
51
|
Contact
|
27
52
|
-------
|
@@ -32,7 +57,7 @@ Problems or questions contact me at [github](http://github.com/banister)
|
|
32
57
|
License
|
33
58
|
-------
|
34
59
|
|
35
|
-
(The MIT License)
|
60
|
+
(The MIT License)
|
36
61
|
|
37
62
|
Copyright (c) 2011 (John Mair)
|
38
63
|
|
data/Rakefile
CHANGED
@@ -52,7 +52,7 @@ namespace :ruby do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
desc "build the
|
55
|
+
desc "build the binaries"
|
56
56
|
task :compile do
|
57
57
|
chdir "./ext/#{PROJECT_NAME}/" do
|
58
58
|
sh "ruby extconf.rb"
|
@@ -72,7 +72,7 @@ task :rmgems => ["ruby:clobber_package"]
|
|
72
72
|
|
73
73
|
desc "build and push latest gems"
|
74
74
|
task :pushgems => :gems do
|
75
|
-
chdir("
|
75
|
+
chdir("./pkg") do
|
76
76
|
Dir["*.gem"].each do |gemfile|
|
77
77
|
sh "gem push #{gemfile}"
|
78
78
|
end
|
data/examples/example.rb
ADDED
@@ -0,0 +1,41 @@
|
|
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
|
+
|
7
|
+
outer = 10
|
8
|
+
|
9
|
+
class Z
|
10
|
+
def z
|
11
|
+
u = 10
|
12
|
+
A.new.a
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class A
|
17
|
+
def a
|
18
|
+
y = 10
|
19
|
+
B.new.b
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class B
|
24
|
+
def b
|
25
|
+
x = 10
|
26
|
+
puts binding.of_caller(0).eval('local_variables')
|
27
|
+
puts binding.of_caller(1).eval('local_variables')
|
28
|
+
puts binding.of_caller(2).eval('local_variables')
|
29
|
+
puts binding.of_caller(3).eval('local_variables')
|
30
|
+
puts binding.of_caller(400).eval('local_variables')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Z.new.z
|
35
|
+
|
36
|
+
# output:
|
37
|
+
# => x
|
38
|
+
# => y
|
39
|
+
# => u
|
40
|
+
# => outer
|
41
|
+
# Exception
|
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.3.
|
5
|
+
version: 0.3.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- John Mair (banisterfiend)
|
@@ -39,9 +39,8 @@ files:
|
|
39
39
|
- LICENSE
|
40
40
|
- README.md
|
41
41
|
- Rakefile
|
42
|
+
- examples/example.rb
|
42
43
|
- ext/binding_of_caller/binding_of_caller.c
|
43
|
-
- ext/binding_of_caller/compat.h
|
44
|
-
- ext/binding_of_caller/example.rb
|
45
44
|
- ext/binding_of_caller/extconf.rb
|
46
45
|
- ext/binding_of_caller/ruby_headers/192/debug.h
|
47
46
|
- ext/binding_of_caller/ruby_headers/192/dln.h
|
@@ -1,57 +0,0 @@
|
|
1
|
-
/* contains basic macros to facilitate ruby 1.8 and ruby 1.9 compatibility */
|
2
|
-
|
3
|
-
#ifndef GUARD_COMPAT_H
|
4
|
-
#define GUARD_COMPAT_H
|
5
|
-
|
6
|
-
#include <ruby.h>
|
7
|
-
|
8
|
-
/* test for 1.9 */
|
9
|
-
#if !defined(RUBY_19) && defined(ROBJECT_EMBED_LEN_MAX)
|
10
|
-
# define RUBY_19
|
11
|
-
#endif
|
12
|
-
|
13
|
-
/* macros for backwards compatibility with 1.8 */
|
14
|
-
#ifndef RUBY_19
|
15
|
-
# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
|
16
|
-
# define RCLASS_SUPER(c) (RCLASS(c)->super)
|
17
|
-
# define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
|
18
|
-
# define OBJ_UNTRUSTED OBJ_TAINTED
|
19
|
-
# include "st.h"
|
20
|
-
#endif
|
21
|
-
|
22
|
-
#ifdef RUBY_19
|
23
|
-
inline static VALUE
|
24
|
-
class_alloc(VALUE flags, VALUE klass)
|
25
|
-
{
|
26
|
-
rb_classext_t *ext = ALLOC(rb_classext_t);
|
27
|
-
NEWOBJ(obj, struct RClass);
|
28
|
-
OBJSETUP(obj, klass, flags);
|
29
|
-
obj->ptr = ext;
|
30
|
-
RCLASS_IV_TBL(obj) = 0;
|
31
|
-
RCLASS_M_TBL(obj) = 0;
|
32
|
-
RCLASS_SUPER(obj) = 0;
|
33
|
-
RCLASS_IV_INDEX_TBL(obj) = 0;
|
34
|
-
return (VALUE)obj;
|
35
|
-
}
|
36
|
-
#endif
|
37
|
-
|
38
|
-
inline static VALUE
|
39
|
-
create_class(VALUE flags, VALUE klass)
|
40
|
-
{
|
41
|
-
#ifdef RUBY_19
|
42
|
-
VALUE new_klass = class_alloc(flags, klass);
|
43
|
-
#else
|
44
|
-
NEWOBJ(new_klass, struct RClass);
|
45
|
-
OBJSETUP(new_klass, klass, flags);
|
46
|
-
#endif
|
47
|
-
|
48
|
-
return (VALUE)new_klass;
|
49
|
-
}
|
50
|
-
|
51
|
-
# define FALSE 0
|
52
|
-
# define TRUE 1
|
53
|
-
|
54
|
-
/* a useful macro. cannot use ordinary CLASS_OF as it does not return an lvalue */
|
55
|
-
#define KLASS_OF(c) (RBASIC(c)->klass)
|
56
|
-
|
57
|
-
#endif
|
@@ -1,39 +0,0 @@
|
|
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
|