[英]What does #self.included(base) do in Ruby on Rails' Restful Authentication?
[英]self.included – including class methods from a module in Ruby
我讀過這篇文章: Ruby模塊 - 包括do end block - 但是當你在模塊中使用self.included do ... end
塊時仍然無法獲得。
帖子說當你包含模塊時,塊中的代碼將被運行,但是如果要包含模塊的唯一目的,那么它的重點是什么? 這個代碼不需要運行嗎? 該塊不需要存在就可以運行該代碼,對吧?
下面兩者之間有什么區別:
module M
def self.included(base)
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end
module ClassMethods
...
end
end
與
module M
def self.some_class_method
...
end
scope :disabled, -> { where(disabled: true) }
end
第一個代碼塊將ClassMethods
的類方法ClassMethods
到包含類,並在其上調用scope
方法。 第二個沒有做這些事情並且會導致NoMethodError
因為模塊沒有scope
類方法。 包含模塊后, self.some_class_method
將不會在包含類中提供。
有關模塊包含如何在Ruby中工作的完整故事,請在此處閱讀我的答案:
從Ruby中的modules / mixins繼承類方法
self.included
如果要包含一個模塊的唯一目的是什么? 包含不是模塊的唯一目的。 它們還用於其他事物,例如命名空間或簡單地存儲可在模塊本身上調用的各種類方法。
從理論上講,Ruby 可以自動將模塊中定義的所有類方法添加到包含類中,但實際上這是一個壞主意,因為您不再需要選擇是否要包含類方法 - 所有類方法都將包含在每個方法中時間,無論是否打算包括在內。 考慮這個例子:
module M
def self.class_method
"foo"
end
def self.configure_module
# add configuration for this module
end
end
class C
include M
end
這里, configure_module
方法顯然不應該添加到C
,因為它的目的是設置模塊對象的配置。 然而,如果我們有類方法的自動包含,你將無法阻止它被包括在內。
但是所有實例方法都已包含在內! 那怎么樣呢?
模塊中的實例方法只有在包含在類中才真正有用 ,因為模塊不能有實例,只有類可以。 因此,在一個模塊中,每個實例方法都應該被包含在某個地方工作。
模塊上的“類”方法是不同的,因為它可以在模塊本身上調用,因此無論它是否也添加到包含類,它都可以正常使用。 這就是為什么你有一個選擇更好的原因。
module M
# self.included is the hook which automatically runs when this module is included
def self.included(base)
puts 'this will be printed when this module will be included inside a class'
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end
def print_object_class
self.class.name # here self will be the object of class which includes this module
end
module ClassMethods
def print_class_name
self.name # Here self would be the class which is including this module
end
end
end
我嘗試修改上面的module
以幫助您了解模塊(關注點)如何在代碼可重用性方面發揮作用
self.included
是一個鈎子,當一個模塊包含在一個類中時它會自動運行。
module ClassMethods
聲明的任何方法module ClassMethods
都將成為包含此模塊的類的類方法
在module ClassMethods
外部聲明的任何方法module ClassMethods
將成為包含此模塊的類的實例方法
對於Ex,假設有一個Product類,並且您已將模塊包含在其中
class Product < ActiveRecord::Base
include M
puts 'after including M'
end
如果您在rails控制台中嘗試此示例,您會注意到,只要模塊M
包含在class Product
包含的模塊運行掛鈎中,
this will be printed when this module will be included inside a class
打印在控制台上this will be printed when this module will be included inside a class
將打印出來
在after including M
之后,這將被打印在控制台上。
您也可以嘗試以下命令
Product.disabled # a scope with name 'disabled' is avaialble because of including the module M
Product.print_class_name # Outputs => 'Product' This method is available to class with the help of module M
Product.new.print_object_class #Outputs => 'Product'
它還提供可重用性,在任何類中包含此模塊M,並且該類可以訪問模塊中描述的所有這些方法。
而你的第二個例子僅僅是基本模塊的一個例子
module N
def self.abc
puts 'basic module'
end
end
現在只能使用此模塊訪問模塊中的abc
方法定義
N.abc # outputs 'basic module'
class Product < ActiveRecord::Base
include N
end
Product.abc #raises異常,沒有在類Product.new.abc #raises異常上找到的方法,沒有找到類對象的方法
我希望這可以幫助您更好地理解模塊的概念。 如果您還有任何疑問,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.