ruby18_source_location 0.2-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ *.so
3
+ *.o
4
+ .rvmrc
5
+ ext/Makefile
data/LICENSE.MIT ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Conrad Irwin <conrad.irwin@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ The `ruby18_source_location` gem backports the `source_location` instance method of `Method`, `UnboundMethod` and
2
+ `Proc` from Ruby 1.9.
3
+
4
+ This allows you to use `Method#source_location` on ruby 1.8.7, and also all the other gems that depend on it.
5
+
6
+ Usage
7
+ -----
8
+
9
+ gem install ruby18_source_location
10
+
11
+ ```ruby
12
+ require 'rubygems'
13
+ require 'ruby18_source_location'
14
+
15
+ def example
16
+ 2
17
+ end
18
+
19
+ puts method(:example).source_location.inspect
20
+ # => ["/tmp/example.rb", 4]
21
+
22
+ puts Proc.new{}.source_location.inspect
23
+ # => ["/tmp/example.rb", 11]
24
+
25
+ puts method(:puts).source_location.inspect
26
+ # => nil
27
+ ```
28
+
29
+ Known issues
30
+ ------------
31
+
32
+ Under Ruby-1.8.7, it's not currently possible to get the `source_location` of methods defined by `attr_reader`,
33
+ `attr_writer` or `attr_accessor`, unless you are running Ruby Enterprise Edition.
34
+
35
+ Meta-foo
36
+ --------
37
+
38
+ This is made available under the MIT license (see LICENSE.MIT), contributions and bug reports are welcome.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+
2
+ def dir(*args); Dir.chdir(File.join(File.dirname(__FILE__), *args)); end
3
+
4
+ desc "Compile local copy"
5
+ task :compile do
6
+ cd("ext") do
7
+ system "ruby extconf.rb"
8
+ system "make"
9
+ end
10
+ end
11
+
12
+ task :clean do
13
+ cd("ext") do
14
+ system "make clean"
15
+ end
16
+ end
17
+
18
+ desc "Package the gem"
19
+ task :gem do
20
+ dir('.')
21
+ system "gem build ruby18_source_location.gemspec"
22
+ end
23
+
24
+ desc "Package the windows gem"
25
+ task :win_gem => [:clean, :compile] do
26
+ dir = File.dirname(__FILE__)
27
+ cd(dir) do
28
+ system "cp #{dir}/ext/*.so #{dir}/lib/"
29
+ system "gem build ruby18_source_location_mswin32.gemspec"
30
+ system "gem build ruby18_source_location_mingw32.gemspec"
31
+ end
32
+ end
33
+
34
+ desc "Run the tests"
35
+ task :test do
36
+ dir("test")
37
+ system "ruby test_ruby18_source_location.rb"
38
+ end
39
+
40
+ desc "Run an interactive shell"
41
+ task :pry do
42
+ dir('.')
43
+ system "pry -f -r ext/ruby18_source_location -r test/examples"
44
+ end
45
+
46
+ task :default => [:clean, :compile, :test]
data/ext/extconf.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = "ruby18_source_location"
4
+
5
+ dir_config(extension_name)
6
+
7
+ create_makefile(extension_name)
@@ -0,0 +1,158 @@
1
+ #include "ruby.h"
2
+ #include "node.h"
3
+
4
+ // Cargo-culted from ruby internal headers.
5
+ struct FRAME {
6
+ VALUE self;
7
+ int argc;
8
+ ID last_func;
9
+ ID orig_func;
10
+ VALUE last_class;
11
+ struct FRAME *prev;
12
+ struct FRAME *tmp;
13
+ struct RNode *node;
14
+ int iter;
15
+ int flags;
16
+ unsigned long uniq;
17
+ } *ruby_frame;
18
+
19
+ struct METHOD {
20
+ VALUE klass, rklass;
21
+ VALUE recv;
22
+ ID id, oid;
23
+ int safe_level;
24
+ NODE *body;
25
+ };
26
+
27
+ struct BLOCK {
28
+ NODE *var;
29
+ NODE *body;
30
+ VALUE self;
31
+ struct FRAME frame;
32
+ struct SCOPE *scope;
33
+ VALUE klass;
34
+ NODE *cref;
35
+ int iter;
36
+ int vmode;
37
+ int flags;
38
+ int uniq;
39
+ struct RVarmap *dyna_vars;
40
+ VALUE orig_thread;
41
+ VALUE wrapper;
42
+ VALUE block_obj;
43
+ struct BLOCK *outer;
44
+ struct BLOCK *prev;
45
+ };
46
+
47
+
48
+ static VALUE method_source_location(VALUE);
49
+ static VALUE proc_source_location(VALUE);
50
+
51
+ void
52
+ Init_ruby18_source_location()
53
+ {
54
+ rb_define_method(rb_cUnboundMethod, "source_location", method_source_location, 0);
55
+ rb_define_method(rb_cMethod, "source_location", method_source_location, 0);
56
+ rb_define_method(rb_cProc, "source_location", proc_source_location, 0);
57
+ }
58
+
59
+ static VALUE
60
+ node_source_location(NODE *node)
61
+ {
62
+ const char *filename = node->nd_file;
63
+ int lineno = nd_line(node);
64
+
65
+ if (filename && lineno) {
66
+ VALUE str = rb_str_new2(filename);
67
+
68
+ // TODO: is there a better way of telling whether the file should be absolute
69
+ if (Qtrue == rb_funcall(rb_cFile, rb_intern("exist?"), 1, str))
70
+ str = rb_file_expand_path(str, Qnil);
71
+
72
+ return rb_assoc_new(str, INT2FIX(lineno));
73
+ }
74
+
75
+ rb_raise(rb_eRuntimeError, "source_location: no file for node");
76
+ }
77
+
78
+ /*
79
+ * call-seq:
80
+ * meth.source_location => [String, Fixnum]
81
+ *
82
+ * returns a pair of the Filename and line number on which the method is defined
83
+ *
84
+ * returns nil if method has no associated ruby source code
85
+ */
86
+ static VALUE
87
+ method_source_location(VALUE method)
88
+ {
89
+ struct METHOD *data;
90
+ struct BLOCK *block;
91
+ NODE *node;
92
+
93
+ Data_Get_Struct(method, struct METHOD, data);
94
+
95
+ if (!(node = data->body))
96
+ rb_raise(rb_eRuntimeError, "source_location: no body for method");
97
+
98
+ switch (nd_type(node)) {
99
+ // methods defined by C extensions
100
+ case NODE_CFUNC:
101
+ return Qnil;
102
+
103
+ // attr_accessor :foo
104
+ case NODE_IVAR: // method(:foo)
105
+ case NODE_ATTRSET: // method(:foo=)
106
+
107
+ // ruby enterpise edition fixes nd_line on these nodes
108
+ #ifdef MBARI_API
109
+ return node_source_location(node);
110
+ #else
111
+ // FIXME, Ruby-1.8.7 returns a bad nd_line on these.
112
+ return Qnil;
113
+ #endif
114
+
115
+ // def foo; end
116
+ case NODE_SCOPE:
117
+ return node_source_location((NODE *)node->u3.value);
118
+
119
+ // define_method(:foo, method(:bar))
120
+ case NODE_DMETHOD:
121
+ return method_source_location(node->u3.value);
122
+
123
+ // define_method(:foo) { }, define_method(:foo, &bar)
124
+ case NODE_BMETHOD:
125
+ return proc_source_location(node->u3.value);
126
+
127
+ default:
128
+ rb_raise(rb_eRuntimeError, "source_location: unhandled method type %d", nd_type(node));
129
+
130
+ }
131
+ }
132
+
133
+ /*
134
+ * call-seq:
135
+ * proc.source_location => [String, Fixnum]
136
+ *
137
+ * returns a pair of the Filename and line number on which the method is defined
138
+ *
139
+ * returns nil if method has no associated ruby source code
140
+ */
141
+ static VALUE
142
+ proc_source_location(VALUE block)
143
+ {
144
+ struct BLOCK *data;
145
+ NODE *node;
146
+ Data_Get_Struct(block, struct BLOCK, data);
147
+
148
+ // Proc.new {}, or Proc.new &proc
149
+ if ((node = data->frame.node) && nd_type(node) == NODE_ITER)
150
+ return node_source_location(node);
151
+
152
+ // Proc.new &method(:foo)
153
+ if ((node = data->body) && nd_type(node) == NODE_IFUNC)
154
+ return method_source_location(node->u2.value);
155
+
156
+ rb_raise(rb_eRuntimeError, "source_location: unhandled proc type");
157
+
158
+ }
@@ -0,0 +1,14 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.name = "ruby18_source_location"
4
+ s.version = "0.2"
5
+ s.platform = Gem::Platform::RUBY
6
+ s.author = "Conrad Irwin"
7
+ s.email = "conrad.irwin@gmail.com"
8
+ s.homepage = "http://github.com/ConradIrwin/ruby18_source_location"
9
+ s.summary = "Add .source_location to methods in Ruby 1.8.7"
10
+ s.description = "Allows you to make use of lots of ruby 1.9.2 specific goodness"
11
+ s.files = `git ls-files`.split("\n")
12
+ s.extensions = "ext/extconf.rb"
13
+ s.require_path = "ext"
14
+ end
data/test/examples.rb ADDED
@@ -0,0 +1,64 @@
1
+ class Example
2
+
3
+ def example1
4
+
5
+ end
6
+
7
+ define_method(:example2) {
8
+
9
+ }
10
+
11
+ Example3 = Proc.new do
12
+
13
+ end
14
+
15
+ Example4 = lambda {
16
+
17
+ }
18
+
19
+ define_method(:example5, Example3)
20
+
21
+ define_method(:example6, &Example4)
22
+
23
+ define_method(:example7, instance_method(:example1))
24
+
25
+ define_method(:example8, &Example.new.method(:example2))
26
+
27
+ Example9 = Proc.new &Example3
28
+
29
+ Example10 = Proc.new &Example.new.method(:example1)
30
+
31
+ eval <<-EVAL
32
+ def example11
33
+
34
+ end
35
+ EVAL
36
+
37
+ eval <<-EVAL, binding, __FILE__, __LINE__+1
38
+ def example12
39
+
40
+ end
41
+ EVAL
42
+
43
+ def self.example13
44
+
45
+ end
46
+
47
+ alias example14 example1
48
+
49
+ alias_method :example15, :example2
50
+
51
+ attr_reader :example16
52
+
53
+ attr_accessor :example17
54
+
55
+ def example18(&block)
56
+ block
57
+ end
58
+
59
+ Example19 = lambda &method(:puts)
60
+ end
61
+
62
+
63
+
64
+ # vim: number
@@ -0,0 +1,106 @@
1
+ require 'test/unit'
2
+
3
+ puts "Testing with #{RUBY_VERSION}"
4
+ if Method.method_defined?(:source_location)
5
+ warn "using BUILTING source_location"
6
+ else
7
+ require "#{File.dirname(__FILE__)}/../ext/ruby18_source_location"
8
+ end
9
+ require "#{File.dirname(__FILE__)}/examples"
10
+
11
+ class TestRuby18SourceLocation < Test::Unit::TestCase
12
+
13
+ def assert_on_line(line, method)
14
+ assert_equal [File.expand_path('./examples.rb'), line], method.source_location
15
+ end
16
+
17
+ def assert_same_source(m1, m2)
18
+ assert_equal m1.source_location, m2.source_location
19
+ end
20
+
21
+ def test_normal_method
22
+ assert_on_line 3, Example.instance_method(:example1)
23
+ end
24
+
25
+ def test_define_method_with_block
26
+ assert_on_line 7, Example.instance_method(:example2)
27
+ end
28
+
29
+ def test_proc_new
30
+ assert_on_line 11, Example::Example3
31
+ end
32
+
33
+ def test_lambda
34
+ assert_on_line 15, Example::Example4
35
+ end
36
+
37
+ def test_define_method_with_proc_arg
38
+ assert_same_source Example::Example3, Example.new.method(:example5)
39
+ end
40
+
41
+ def test_define_method_with_amp_proc
42
+ assert_same_source Example::Example4, Example.new.method(:example6)
43
+ end
44
+
45
+ def test_define_method_with_method_arg
46
+ assert_same_source Example.new.method(:example1), Example.new.method(:example7)
47
+ end
48
+
49
+ def test_define_method_with_amp_method
50
+ assert_same_source Example.new.method(:example2), Example.new.method(:example8)
51
+ end
52
+
53
+ def test_proc_with_amp_proc
54
+ assert_same_source Example::Example3, Example::Example9
55
+ end
56
+
57
+ def test_proc_with_amp_method
58
+ assert_same_source Example.instance_method(:example1), Example::Example10
59
+ end
60
+
61
+ def test_eval
62
+ assert_equal ['(eval)', 1], Example.instance_method(:example11).source_location
63
+ end
64
+
65
+ def test_eval_with_overridden_line
66
+ assert_on_line 38, Example.new.method(:example12)
67
+ end
68
+
69
+ def test_class_method
70
+ assert_on_line 43, Example.method(:example13)
71
+ end
72
+
73
+ def test_alias
74
+ assert_same_source Example.new.method(:example1), Example.new.method(:example14)
75
+ end
76
+
77
+ def test_alias_method
78
+ assert_same_source Example.new.method(:example2), Example.new.method(:example15)
79
+ end
80
+
81
+ def test_c_method
82
+ assert_equal nil, method(:puts).source_location
83
+ end
84
+
85
+ def test_attr_reader
86
+ assert_on_line 51, Example.instance_method(:example16)
87
+ end
88
+
89
+ def test_attr_accessor
90
+ assert_on_line 53, Example.instance_method(:example17)
91
+ end
92
+
93
+ def test_attr_assign
94
+ assert_on_line 53, Example.instance_method(:example17=)
95
+ end
96
+
97
+ def test_blocks
98
+ assert_equal [File.expand_path(__FILE__), __LINE__], Example.new.example18{
99
+
100
+ }.source_location
101
+ end
102
+
103
+ def test_lambdas_with_c_methods
104
+ assert_equal nil, Example::Example19.source_location
105
+ end
106
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby18_source_location
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ version: "0.2"
10
+ platform: i386-mswin32
11
+ authors:
12
+ - Conrad Irwin
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-04-13 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Allows you to make use of lots of ruby 1.9.2 specific goodness
22
+ email: conrad.irwin@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - .gitignore
31
+ - LICENSE.MIT
32
+ - README.md
33
+ - Rakefile
34
+ - ext/extconf.rb
35
+ - ext/ruby18_source_location.c
36
+ - ruby18_source_location.gemspec
37
+ - test/examples.rb
38
+ - test/test_ruby18_source_location.rb
39
+ - lib/ruby18_source_location.so
40
+ has_rdoc: true
41
+ homepage: http://github.com/ConradIrwin/ruby18_source_location
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.5.2
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Add .source_location to methods in Ruby 1.8.7
74
+ test_files: []
75
+