force_bind 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+