Skip to content
This repository
Browse code

Deprecate InstanceMethods namespace handling in ActiveSupport::Concern.

This avoids the unnecessary "yo dawg, I heard you like include, so I put a module that includes your module when it is included" approach when building extensions.
  • Loading branch information...
commit 401393b6561adc1ce7101945163c9601257c057a 1 parent f312e21
José Valim authored November 21, 2011
15  activesupport/lib/active_support/concern.rb
@@ -4,17 +4,12 @@ module ActiveSupport
4 4
   #   module M
5 5
   #     def self.included(base)
6 6
   #       base.extend ClassMethods
7  
-  #       base.send(:include, InstanceMethods)
8 7
   #       scope :disabled, where(:disabled => true)
9 8
   #     end
10 9
   #
11 10
   #     module ClassMethods
12 11
   #       ...
13 12
   #     end
14  
-  #
15  
-  #     module InstanceMethods
16  
-  #       ...
17  
-  #     end
18 13
   #   end
19 14
   #
20 15
   # By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
@@ -31,10 +26,6 @@ module ActiveSupport
31 26
   #     module ClassMethods
32 27
   #       ...
33 28
   #     end
34  
-  #
35  
-  #     module InstanceMethods
36  
-  #       ...
37  
-  #     end
38 29
   #   end
39 30
   #
40 31
   # Moreover, it gracefully handles module dependencies. Given a +Foo+ module and a +Bar+
@@ -118,7 +109,11 @@ def append_features(base)
118 109
         @_dependencies.each { |dep| base.send(:include, dep) }
119 110
         super
120 111
         base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
121  
-        base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods")
  112
+        if const_defined?("InstanceMethods")
  113
+          base.send :include, const_get("InstanceMethods")
  114
+          ActiveSupport::Deprecation.warn "The InstanceMethods module inside ActiveSupport::Concern will be " \
  115
+            "no longer included automatically. Please define instance methods directly in #{base} instead.", caller
  116
+        end
122 117
         base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
123 118
       end
124 119
     end
7  activesupport/test/concern_test.rb
@@ -19,9 +19,6 @@ def included_ran
19 19
       end
20 20
     end
21 21
 
22  
-    module InstanceMethods
23  
-    end
24  
-
25 22
     included do
26 23
       self.included_ran = true
27 24
     end
@@ -74,7 +71,7 @@ def test_class_methods_are_extended
74 71
   def test_instance_methods_are_included
75 72
     @klass.send(:include, Baz)
76 73
     assert_equal "baz", @klass.new.baz
77  
-    assert @klass.included_modules.include?(ConcernTest::Baz::InstanceMethods)
  74
+    assert @klass.included_modules.include?(ConcernTest::Baz)
78 75
   end
79 76
 
80 77
   def test_included_block_is_ran
@@ -92,6 +89,6 @@ def test_modules_dependencies_are_met
92 89
 
93 90
   def test_dependencies_with_multiple_modules
94 91
     @klass.send(:include, Foo)
95  
-    assert_equal [ConcernTest::Foo, ConcernTest::Bar, ConcernTest::Baz::InstanceMethods, ConcernTest::Baz], @klass.included_modules[0..3]
  92
+    assert_equal [ConcernTest::Foo, ConcernTest::Bar, ConcernTest::Baz], @klass.included_modules[0..2]
96 93
   end
97 94
 end

8 notes on commit 401393b

Jérémy Lecour

Does this mean that we don't have to create an InstanceMethods module, and just put our methods in the parent module ?
It's a little less expressive, but definitely cleaner.

José Valim
Owner
Xavier Noria
Owner

:+1:

Clemens Kofler

I hate you for this, Jose. ;-) In one of my projects I've started scoping everything to InstanceMethods because I thought there was a good reason that Rails was doing it. Now I'll have to fix something that was right in the first place. -_- Luckily, it's just one git revert away. :D

Phillip Oertel

In the following example:

class Project < ActiveRecord::Base
include Project::Visibility
...

module Project::Visibility
extend ActiveSupport::Concern
...
module InstanceMethods
...

I get the deprecation warning: "The InstanceMethods module inside ActiveSupport::Concern will be no longer included automatically. Please define instance methods directly in Project instead. (called from include at /Users/phillip/Projekte/torial/git/app/models/project.rb:3)"

IMHO the deprecation warning should tell me to put the instance methods directly into the module, not the base class? Putting the code back into the main class kind of spoils the whole concern idea, right?

The implementation is correct, it's just the deprecation warning that is confusing.

José Valim
Owner

Yeah, the deprecation warning is wrong, fixing.

Phillip Oertel

you are awesome! :-)

Please sign in to comment.
Something went wrong with that request. Please try again.