Following are the code snippets:
Module: ActiveSupport::Concern
module ActiveSupport
module Concern
def self.extended(base)
base.instance_variable_set("@_dependencies", [])
end
def append_features(base)
if base.instance_variable_defined?("@_dependencies")
base.instance_variable_get("@_dependencies") << self
return false
else
return false if base < self
@_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")
base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
end
end
def included(base = nil, &block)
if base.nil?
@_included_block = block
else
super
end
end
end
end
Custom Module: GeneralScopes
module GeneralScopes
extend ActiveSupport::Concern
included do
scope :reverse_order_by_date, :order => "date DESC"
scope :recent, lambda { |count| reverse_order_by_date.limit(count) }
end
end
Custom Class: User
class User < ActiveRecord::Base
include GeneralScopes
end
Usage:
User.recent(5) => Prints the recent five User instances available in database
I have following questions in context of above shown code snippets:
1) include(MODULE_NAME(s)). include is a private instance method of Module and this method is invoked by self implicitly. So what does self represent in the class body? In the class's instance method self represents the current object. In the class's class method self represents the class's Class object.
How does this include <MODULE_NAME>
syntax from class body works?
2) extend(MODULE_NAME(s))
Quoted from "The Ruby Programming Language" by David Flanagan and Yukihiro Matsumoto (Oreilly), Chapter 7 Classes and Modules
Object.extend.This method makes the instance methods of the specified module or modules into singleton methods of the receiver object.(And if the receiver object is a Class instance, then the methods of the receiver become the class methods of that class)
I am unable to understand this in context of my GeneralScopes module shown above.
3)
module GeneralScopes
extend ActiveSupport::Concern
included do
scope :reverse_order_by_date, :order => "date DESC"
scope :recent, lambda { |count| reverse_order_by_date.limit(count) }
end
end
module GeneralScopes I assume is invoking the ActiveSupport::Concern module's instance method "included(base = nil, &block)".How does this invocation of an instance method from module body work? Which object acts as the receiver when
included do
scope :reverse_order_by_date, :order => "date DESC"
scope :recent, lambda { |count| reverse_order_by_date.limit(count) }
end
is executed?
4) ActiveSupport::Concern module's instance method "included(base = nil, &block)"
def included(base = nil, &block)
if base.nil?
@_included_block = block
else
super
end
end
Here super is used.This super works in context of User class or ActiveSupport::Concern module? To which class the control goes when super is executed?
It would be a great help if anybody can make me understand the control flow executed or point me to any relevant resources explaining the concepts related to questions I have.