unextendable 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,18 @@
1
1
  = Unextendable CHANGELOG
2
2
 
3
+ == Version 0.1.3 (May 2, 2011)
4
+
5
+ * Always returning boolean when calling object.meta_class?
6
+ * Corrected the arguments definition of instance.respond_to? (being able to pass include_private)
7
+
8
+ == Version 0.1.2 (May 2, 2011)
9
+
10
+ * Improved object_instance.unextend
11
+ * Created a single point of definition for determination to whether or not unextend a certain module
12
+ * Added object.meta_class? (aliased with singleton_class?)
13
+ * Fixed error raised when trying to wrap a non-existing object instance method
14
+ * Corrected respond_to? and raising NoMethodError when calling an unextended module method which wasn't defined in the object instance itself
15
+
3
16
  == Version 0.1.1 (May 1, 2011)
4
17
 
5
18
  * Being able to pass a block to 'unextend' and only unextending a module when the block passes
@@ -100,19 +100,25 @@ After that, you can do the following:
100
100
  c.salutation #=> "Mr. X"
101
101
  c.extend U
102
102
  c.salutation #=> "Mr. U"
103
+ c.unextend U
104
+ c.salutation #=> "Mr. X"
103
105
  c.unextend
104
106
  c.salutation #=> "Mr. C"
105
107
  c.extend A
106
108
  c.salutation #=> "Mr. A"
107
109
  c.extend X
108
110
  c.salutation #=> "Mr. X"
111
+ c.unextend do |mod|
112
+ mod == U
113
+ end
114
+ c.salutation #=> "Mr. X"
109
115
  c.unextend
110
116
  c.salutation #=> "Mr. A" (because module A is NOT unextendable)
111
117
  </pre>
112
118
 
113
119
  h2. Last remarks
114
120
 
115
- Please check out "https://github.com/archan937/unextendable/blob/master/test/object_instance_test.rb":https://github.com/archan937/unextendable/blob/master/test/object_instance_test.rb for most of the tests.
121
+ Please check out "https://github.com/archan937/unextendable/blob/master/test/object_instance_test.rb":https://github.com/archan937/unextendable/blob/master/test/object_instance_test.rb for most of the tests available. You can run the unit tests with @rake@ within the terminal.
116
122
 
117
123
  Also, the Unextendable repo is provided with @script/console@ which you can run for testing purposes. The module and class definitions are already defined when starting up and the object instance <code>@c</code> of the class @C@ is also defined.
118
124
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.3
@@ -8,6 +8,11 @@ class Object
8
8
  end
9
9
  alias :singleton_class :meta_class
10
10
 
11
+ def meta_class?
12
+ !!(meta_class rescue false)
13
+ end
14
+ alias :singleton_class? :meta_class?
15
+
11
16
  meta_class do
12
17
  def extended_modules
13
18
  @extended_modules ||= []
@@ -29,17 +34,29 @@ class Object
29
34
  def unextend(*modules, &block)
30
35
  if modules.empty?
31
36
  meta_class.extended_modules.delete_if do |mod|
32
- mod.unextendable? if !block_given? || block.call(mod)
37
+ unextend? mod, &block
33
38
  end
34
39
  else
35
40
  modules.each do |mod|
36
- meta_class.extended_modules.delete mod if !block_given? || block.call(mod)
41
+ meta_class.extended_modules.delete mod if unextend? mod, &block
37
42
  end
38
43
  end
39
44
  end
40
45
 
46
+ def respond_to?(symbol, include_private = false)
47
+ if meta_class? && meta_class.extended_modules.any?{|mod| mod.unextendable?}
48
+ meta_class.extended_modules.detect{|x| x.instance_methods.include? symbol.to_s} || meta_class.method_procs[symbol.to_s].class == Proc
49
+ else
50
+ !(meta_class? && meta_class.method_procs.key?(symbol.to_s) && meta_class.method_procs[symbol.to_s].nil?) && super
51
+ end
52
+ end
53
+
41
54
  private
42
55
 
56
+ def unextend?(mod, &block)
57
+ mod.unextendable? && (!block_given? || !!block.call(mod))
58
+ end
59
+
43
60
  def wrap_unextendable_module(mod)
44
61
  return unless (mod.class == Module) && mod.unextendable?
45
62
 
@@ -51,7 +68,7 @@ private
51
68
  def wrap_unextendable_method(name)
52
69
  return if meta_class.method_procs.key? name
53
70
 
54
- meta_class.method_procs[name] = method(name).to_proc
71
+ meta_class.method_procs[name] = respond_to?(name) ? method(name).to_proc : nil
55
72
 
56
73
  instance_eval <<-CODE
57
74
  def #{name}(*args, &block)
@@ -66,7 +83,11 @@ private
66
83
  end
67
84
 
68
85
  def call_unextendable_method(method_name, *args, &block)
69
- method_for(method_name).call(*args, &block)
86
+ if method = method_for(method_name)
87
+ method.call(*args, &block)
88
+ else
89
+ raise NoMethodError, "undefined method `#{method_name}' for #{self.inspect}"
90
+ end
70
91
  end
71
92
 
72
93
  def method_for(method_name)
@@ -75,7 +96,9 @@ private
75
96
  end
76
97
 
77
98
  def proc_for(method_name)
78
- meta_class.method_procs[method_name.to_s] || method(method_name.to_s)
99
+ meta_class.method_procs.key?(method_name.to_s) ?
100
+ meta_class.method_procs[method_name.to_s] :
101
+ method(method_name.to_s)
79
102
  end
80
103
 
81
104
  end
@@ -1,7 +1,7 @@
1
1
  module Unextendable
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- TINY = 1
4
+ TINY = 3
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join(".")
7
7
  end
@@ -77,6 +77,9 @@ class ObjectInstanceTest < Test::Unit::TestCase
77
77
  def name
78
78
  "U"
79
79
  end
80
+ def foo
81
+ "bar"
82
+ end
80
83
  end
81
84
  end
82
85
 
@@ -86,10 +89,16 @@ class ObjectInstanceTest < Test::Unit::TestCase
86
89
  end
87
90
 
88
91
  should "call wrap_unextendable_method" do
89
- @c.expects(:wrap_unextendable_method)
92
+ @c.expects(:wrap_unextendable_method).twice
90
93
  @c.extend U
91
94
  end
92
95
 
96
+ should "add nil value as method proc when not responding to module method name" do
97
+ @c.extend U
98
+ assert_equal 1, @c.meta_class.method_procs.select{|k, v| v.nil?}.size
99
+ assert_equal 1, @c.meta_class.method_procs.select{|k, v| v.class == Proc}.size
100
+ end
101
+
93
102
  should "add the module to extended_modules" do
94
103
  assert @c.meta_class.extended_modules.empty?
95
104
  @c.extend U
@@ -99,7 +108,7 @@ class ObjectInstanceTest < Test::Unit::TestCase
99
108
  should "add method proc to method_procs" do
100
109
  assert @c.meta_class.send(:method_procs).empty?
101
110
  @c.extend U
102
- assert_equal 1, @c.meta_class.send(:method_procs).size
111
+ assert_equal 2, @c.meta_class.send(:method_procs).size
103
112
  end
104
113
 
105
114
  context "when calling an unextendable method" do
@@ -176,16 +185,32 @@ class ObjectInstanceTest < Test::Unit::TestCase
176
185
  @c.title = "Dr."
177
186
  assert_equal "Dr. C", @c.salutation
178
187
 
188
+ assert !@c.respond_to?(:foo)
189
+ assert_raise NoMethodError do
190
+ @c.foo
191
+ end
192
+
179
193
  @c.extend U
180
194
  assert_equal "Dr. U", @c.salutation
181
195
  @c.title = "Sir"
182
196
  assert_equal "Sir U", @c.salutation
183
197
 
198
+ assert @c.respond_to?(:foo)
199
+ assert_nothing_raised NoMethodError do
200
+ @c.foo
201
+ end
202
+ assert_equal "bar", @c.foo
203
+
184
204
  @c.unextend U
185
205
  assert_equal "Sir C", @c.salutation
186
206
  @c.title = ""
187
207
  assert_equal "C", @c.salutation
188
208
 
209
+ assert !@c.respond_to?(:foo)
210
+ assert_raise NoMethodError do
211
+ @c.foo
212
+ end
213
+
189
214
  @c.extend U
190
215
  assert_equal "U", @c.salutation
191
216
  @c.title = "Ms."
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unextendable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Paul Engel
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-01 00:00:00 +02:00
19
- default_executable:
18
+ date: 2011-05-02 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: shoulda
@@ -73,7 +72,6 @@ files:
73
72
  - test/object_instance_test.rb
74
73
  - test/test_helper.rb
75
74
  - unextendable.gemspec
76
- has_rdoc: true
77
75
  homepage: https://github.com/archan937/unextendable
78
76
  licenses: []
79
77
 
@@ -103,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
101
  requirements: []
104
102
 
105
103
  rubyforge_project: unextendable
106
- rubygems_version: 1.6.2
104
+ rubygems_version: 1.7.2
107
105
  signing_key:
108
106
  specification_version: 3
109
107
  summary: A small gem making unextending extended module methods within object instances possible