Следват кодовите фрагменти:
Модул: 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
Персонализиран модул: 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
Персонализиран клас: потребител
class User < ActiveRecord::Base
include GeneralScopes
end
Употреба:
User.recent(5) => Prints the recent five User instances available in database
Имам следните въпроси в контекста на показаните по-горе кодови фрагменти:
1) включване (MODULE_NAME(s)). include е частен метод на екземпляр на Module и този метод се извиква от self имплицитно. И така, какво представлява self в тялото на класа? В екземпляра на класа методът self представлява текущия обект. В класовия метод self представлява обекта Class на класа.
Как работи този include <MODULE_NAME>
синтаксис от тялото на класа?
2) разширяване (MODULE_NAME(s))
Цитирано от „Езикът за програмиране Ruby“ от Дейвид Фланаган и Юкихиро Мацумото (Oreilly), Глава 7 Класове и модули
Object.extend. Този метод прави методите на екземпляра на посочения модул или модули в методи с единичен елемент на обекта приемник. (И ако обектът приемник е екземпляр на клас, тогава методите на приемника стават методите на класа на този клас)
Не мога да разбера това в контекста на моя модул GeneralScopes, показан по-горе.
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
modul GeneralScopes Предполагам, че извиква метода на екземпляр на модула ActiveSupport::Concern "included(base = nil, &block)". Как работи това извикване на метод на екземпляр от тялото на модула? Кой обект действа като приемник кога
included do
scope :reverse_order_by_date, :order => "date DESC"
scope :recent, lambda { |count| reverse_order_by_date.limit(count) }
end
се изпълнява?
4) Методът на екземпляра на модула ActiveSupport::Concern "включен (база = нула, &блок)"
def included(base = nil, &block)
if base.nil?
@_included_block = block
else
super
end
end
Тук се използва super. Това super работи в контекста на потребителски клас или модул ActiveSupport::Concern? Към кой клас отива управлението, когато се изпълни super?
Би било от голяма полза, ако някой може да ме накара да разбера изпълнения контролен поток или да ме насочи към подходящи ресурси, обясняващи концепциите, свързани с въпроси, които имам.