Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
View
15 activesupport/lib/active_support/concern.rb
@@ -4,17 +4,12 @@ module ActiveSupport
# module M
# def self.included(base)
# base.extend ClassMethods
- # base.send(:include, InstanceMethods)
# scope :disabled, where(:disabled => true)
# end
#
# module ClassMethods
# ...
# end
- #
- # module InstanceMethods
- # ...
- # end
# end
#
# By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
@@ -31,10 +26,6 @@ module ActiveSupport
# module ClassMethods
# ...
# end
- #
- # module InstanceMethods
- # ...
- # end
# end
#
# Moreover, it gracefully handles module dependencies. Given a +Foo+ module and a +Bar+
@@ -118,7 +109,11 @@ def append_features(base)
@_dependencies.each { |dep| base.send(:include, dep) }
super
base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
- base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods")
+ if const_defined?("InstanceMethods")
+ base.send :include, const_get("InstanceMethods")
+ ActiveSupport::Deprecation.warn "The InstanceMethods module inside ActiveSupport::Concern will be " \
+ "no longer included automatically. Please define instance methods directly in #{base} instead.", caller
+ end
base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
end
end
View
7 activesupport/test/concern_test.rb
@@ -19,9 +19,6 @@ def included_ran
end
end
- module InstanceMethods
- end
-
included do
self.included_ran = true
end
@@ -74,7 +71,7 @@ def test_class_methods_are_extended
def test_instance_methods_are_included
@klass.send(:include, Baz)
assert_equal "baz", @klass.new.baz
- assert @klass.included_modules.include?(ConcernTest::Baz::InstanceMethods)
+ assert @klass.included_modules.include?(ConcernTest::Baz)
end
def test_included_block_is_ran
@@ -92,6 +89,6 @@ def test_modules_dependencies_are_met
def test_dependencies_with_multiple_modules
@klass.send(:include, Foo)
- assert_equal [ConcernTest::Foo, ConcernTest::Bar, ConcernTest::Baz::InstanceMethods, ConcernTest::Baz], @klass.included_modules[0..3]
+ assert_equal [ConcernTest::Foo, ConcernTest::Bar, ConcernTest::Baz], @klass.included_modules[0..2]
end
end

8 comments on commit 401393b

@jlecour

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.

@josevalim
Owner
@fxn
Owner

:+1:

@clemens

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

@phillipoertel

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.

@josevalim
Owner

Yeah, the deprecation warning is wrong, fixing.

@phillipoertel

you are awesome! :-)

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