Reputation: 655
What's the difference between
module A
def self.included(klass)
puts klass
end
end
and
module A
include ActiveSupport::Concern
included do
puts self
end
end
Which one is a better and which one to use when?
Upvotes: 3
Views: 707
Reputation: 176552
Both snippets produce the same result. However, there is a small but important difference.
The first code is pure Ruby. It means it will work without any dependency.
The second piece of code depends on ActiveSupport that is an external dependency. If you want to use it you need to include the gem in your project. In a Rails application, there is almost no overhead because the application already depends on ActiveSupport. But in a non-Rails application, it may not be convenient.
Moreover, ActiveSupport::Concern
does a lot more than simply adding some syntactic sugar for the Ruby included hook. In fact, the primary scope of such module was to manage multiple dependencies between modules.
In the Rails codebase it's very common to define small piece of features into separate modules. A good example is ActiveSupport
itself. However, you may have that the feature A
may require some feature defined in the module B
, so if you include B
in your code, then the module should make sure to require and mix also A
, otherwise your code will crash.
It also implements a very common pattern based on the included hook: class-level extensions. The following Ruby code
module A
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def bar
"bar"
end
end
end
class Foo
include A
end
Foo.bar
# => "bar"
becomes
module A
extend ActiveSupport::Concern
module ClassMethods
def bar
"bar"
end
end
end
class Foo
include A
end
Foo.bar
# => "bar"
My personal advice is to avoid using the ActiveSupport::Concern
if
Concern
ActiveSupport
as dependencyUpvotes: 4
Reputation: 168249
In your second piece of code, included
is called once during when A
is defined. It does not do anything unless you had defined included
to do something. The block passed to included
would have no effect unless you had overwritten included
to take a block and do something with it. In short, your second piece of code does not make sense.
Upvotes: -1