unextendable 0.1.1 → 0.1.3

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.
@@ -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