force_bind 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,34 @@
1
+ = force_bind
2
+
3
+ Adds UnboundMethod#force_bind to bind an unbound method to class (or any object of any type).
4
+ It basically bypasses the argument type checking that #bind has.
5
+
6
+ == Example
7
+
8
+ Bind an instance method to its class (making it act like a class method):
9
+
10
+ class Foo
11
+ def bar
12
+ puts "I'm inside #{self}"
13
+ end
14
+ end
15
+
16
+ Foo.new.bar
17
+ #=> "I'm inside #<Foo:0x123456>"
18
+
19
+ meth = Foo.instance_method(:bar).force_bind(Foo)
20
+ meth.call
21
+ #=> "I'm inside Foo"
22
+
23
+ You can also use this to rebind the instance method of any object to any
24
+ other object:
25
+
26
+ class A
27
+ def foo; self end
28
+ end
29
+
30
+ class B; end
31
+
32
+ meth = A.instance_method(:foo).force_bind(B.new)
33
+ meth.call
34
+ #=> #<B:0x123456>
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ WINDOWS = (PLATFORM =~ /win32|cygwin/ ? true : false) rescue false
5
+ SUDO = WINDOWS ? '' : 'sudo'
6
+
7
+ load 'force_bind.gemspec'
8
+ Rake::GemPackageTask.new(SPEC) do |pkg|
9
+ pkg.gem_spec = SPEC
10
+ pkg.need_zip = true
11
+ pkg.need_tar = true
12
+ end
13
+
14
+ desc "Install the gem locally"
15
+ task :install => :package do
16
+ sh "#{SUDO} gem install pkg/#{SPEC.name}-#{SPEC.version}.gem --local"
17
+ sh "rm -rf pkg/#{SPEC.name}-#{SPEC.version}" unless ENV['KEEP_FILES']
18
+ end
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+ $CPPFLAGS += " -DRUBY_19" if RUBY_VERSION =~ /1.9/
3
+ ext = 'force_bind'
4
+ dir_config(ext)
5
+ create_makefile(ext)
@@ -0,0 +1,29 @@
1
+ #include "ruby.h"
2
+
3
+ struct METHOD {
4
+ VALUE oclass;
5
+ VALUE rclass;
6
+ VALUE recv;
7
+ ID id, oid;
8
+ struct RNode *body;
9
+ };
10
+
11
+ static VALUE
12
+ umethod_force_bind(VALUE method, VALUE recv)
13
+ {
14
+ struct METHOD *data, *bound;
15
+
16
+ Data_Get_Struct(method, struct METHOD, data);
17
+ method = Data_Make_Struct(rb_cMethod, struct METHOD, free, -1, bound);
18
+ *bound = *data;
19
+ bound->recv = recv;
20
+ bound->rclass = TYPE(recv) == T_CLASS ? RCLASS(recv) : CLASS_OF(recv);
21
+
22
+ return method;
23
+ }
24
+
25
+ void
26
+ Init_force_bind()
27
+ {
28
+ rb_define_method(rb_cUnboundMethod, "force_bind", umethod_force_bind, 1);
29
+ }
@@ -0,0 +1,25 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../force_bind'
3
+
4
+ class Mock
5
+ def the_method; self end
6
+ end
7
+
8
+ class TestForceBind < Test::Unit::TestCase
9
+ def test_force_bind_class
10
+ proc = Mock.instance_method(:the_method).force_bind(Mock)
11
+ assert_equal Mock, proc.call
12
+ end
13
+
14
+ def test_force_bind_object
15
+ mock = Mock.new
16
+ proc = Mock.instance_method(:the_method).force_bind(mock)
17
+ assert_equal mock, proc.call
18
+ end
19
+
20
+ def test_force_bind_object_from_other_class
21
+ arr = Array.new
22
+ proc = Mock.instance_method(:the_method).force_bind(arr)
23
+ assert_equal arr, proc.call
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: force_bind
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Loren Segal
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-15 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: lsegal@soen.ca
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Rakefile
26
+ - README
27
+ - ext/force_bind.c
28
+ - ext/extconf.rb
29
+ - test/test_force_bind.rb
30
+ has_rdoc: false
31
+ homepage: http://github.com/lsegal/force_bind
32
+ licenses: []
33
+
34
+ post_install_message:
35
+ rdoc_options: []
36
+
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.3.5
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Adds UnboundMethod#force_bind to bind an unbound method to class (or any object of any type)
58
+ test_files: []
59
+