Greetings,
I have never taken a look at how Hook was used in
DataMapper and Merb, and wondering if it is necessary to
make hookable_* and __hooks* be public?
As a result, I forked Extlib and started trying to make them
be private. Patch was attached in this mail, and here's
the essential diff:
http://github.com/godfat/extlib/commit/1c8c
Here's the spec:
http://github.com/godfat/extlib/commit/63a3
On my computer, all specs were passed.
Is it ok to apply this kind of behavior?
Thanks!
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"DataMapper" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/datamapper?hl=en
-~----------~----~----~----~------~----~------~--~---
commit 1c8cb8855ceb3b7e081c4414690083fff6d2aa3c
Author: godfat <[EMAIL PROTECTED]>
Date: Thu Sep 4 11:12:59 2008 +0800
make internal method be private, don't expose them.
diff --git a/lib/extlib/hook.rb b/lib/extlib/hook.rb
index 2ebb161..0de975e 100644
--- a/lib/extlib/hook.rb
+++ b/lib/extlib/hook.rb
@@ -258,10 +258,10 @@ module Extlib
name = method_info[:name]
if scope == :instance
- args = method_defined?(name) && instance_method(name).arity != 0 ? '*args' : ''
+ args = (method_defined?(name) || private_method_defined?(name)) && instance_method(name).arity != 0 ? '*args' : ''
%(#{name}(#{args}) if self.class <= ObjectSpace._id2ref(#{method_info[:from].object_id}))
else
- args = respond_to?(name) && method(name).arity != 0 ? '*args' : ''
+ args = respond_to?(name, true) && method(name).arity != 0 ? '*args' : ''
%(#{name}(#{args}) if self <= ObjectSpace._id2ref(#{method_info[:from].object_id}))
end
end
@@ -285,12 +285,14 @@ module Extlib
if scope == :instance && !instance_methods(false).include?(target_method.to_s)
send(:alias_method, renamed_target, target_method)
+ send(:private, renamed_target)
proxy_module = Module.new
proxy_module.class_eval(source, __FILE__, __LINE__)
self.send(:include, proxy_module)
else
source = %{alias_method :#{renamed_target}, :#{target_method}\n#{source}}
+ source += "\nprivate :#{renamed_target}"
source = %{class << self\n#{source}\nend} if scope == :class
class_eval(source, __FILE__, __LINE__)
end
@@ -324,9 +326,11 @@ module Extlib
if scope == :class
(class << self; self; end;).instance_eval do
define_method(method_sym, &block)
+ private method_sym
end
else
define_method(method_sym, &block)
+ private method_sym
end
end
commit 63a3dc7cee815c42908d64867b4af0789dc212e1
Author: godfat <[EMAIL PROTECTED]>
Date: Thu Sep 4 14:04:27 2008 +0800
added spec for 'never touch public methods'
diff --git a/spec/hook_spec.rb b/spec/hook_spec.rb
index 038875a..467c807 100644
--- a/spec/hook_spec.rb
+++ b/spec/hook_spec.rb
@@ -1195,4 +1195,23 @@ describe Extlib::Hook do
end
end
+ describe 'never touch public methods' do
+ def spec_public_methods methods, before, after
+ original_methods = @class.send(methods).sort
+ @class.send(before, :ambiguous, &lambda{ 'Caption Hook' })
+ @class.send(methods).sort.should == original_methods
+
+ @class.send(after, :ambiguous, &lambda{ 'Caption Look' })
+ @class.send(methods).sort.should == original_methods
+ end
+
+ it 'should contain the same public instance methods' do
+ spec_public_methods :public_instance_methods, :before, :after
+ end
+
+ it 'should contain the same public class methods' do
+ spec_public_methods :methods, :before_class_method, :after_class_method
+ end
+ end
+
end