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

Reply via email to