ruby 鉤子方法的介紹和應用

2021-09-16 20:11:47 字數 4008 閱讀 1713

在 class 與 module 的關係裡提到了,當乙個 class 引入(include)乙個 module 時,module 中的方法會變成

class 的例項方法,而不是類方法. extend 方法會把 module 中的方法放入 eigenclass 中,變成類方法.

這裡使用鉤子方法來實現.即當在乙個class中include乙個 module 時,使 module 中的方法變成class的類方法.

module mymixin  

def self.included(base)

base.extend(self)

end

def a_method

"a_method"

end

end

class myclass

include mymixin

end

puts myclass.a_method ## a_method

puts myclass.new.a_method ## a_method

在class include 乙個方法是用到的是module的included方法.拓展included方法可以實現將module方法變為class 的類方法和例項方法.included 就是乙個鉤子方法

鉤子方法提供了一種用於在程式執行時擴充套件程式的行為.例如,在乙個子類繼承了一些特定的父類時收到通知,或者是處理乙個物件上的不可呼叫方法而不讓編譯器丟擲異常.這些情況就是使用鉤子方法,但是它們的用法並不僅限於此.不同的框架/庫使用了不同的鉤子方法來實現它們的功能.

在class上 include 乙個module可以得到module上的方法作為class 的例項方法

included 也就是我們在上面提到的,這是ruby提供的乙個鉤子方法,當你在一些 module 或者 class 中 include 了乙個 module 時它會被呼叫.我們可以在 module 的 included 方法裡增加所需要的邏輯.

def self.included(base)

base.extend classmethods

assert_validations_api!(base)

base.class_eval do

validates_presence_of :email, if: :email_required?

validates_uniqueness_of :email, allow_blank: true, if: :email_changed?

validates_format_of :email, with: email_regexp, allow_blank: true, if: :email_changed?

validates_presence_of :password, if: :password_required?

validates_confirmation_of :password, if: :password_required?

validates_length_of :password, within: password_length, allow_blank: true

endend

extended 和 included 類似,在 class上 extend 乙個 module 可以得到 module 上的方法作為 class 的類方法.這時候 extended 就會被觸發.

module person

def self.extended(base)

puts "# extended #"

enddef name

"my name is person"

endendclass user

extend person

end## user extended person

user.name ## "my name is person"

class 與 module 的引用方法還有 prepend .其對應的鉤子方法是 prepended.與 include 和 extend 不同的是,include extend 類似於繼承,當 class 本身有同名的方法時,以 class 自身方法為準,而 prepend 則是與之相反的,會覆蓋掉 class 上的同名方法.

其鉤子方法與 included 和 extended 用法一致.

module person

def name

"my name belongs to person"

endendclass includeuser

include person

def name

"my name belongs to user"

endendclass prependuser

def name

"my name belongs to user"

endprepend person

endincludeuser.new.name ## 'my name belongs to user'

prependuser.new.name ## 'my name belongs to person'

繼承是物件導向中乙個最重要的概念。當父類被其他子類繼承時,父類的 inherited 類方法將會被呼叫.

class person

def self.inherited(child_class)

puts "# inherits #"

enddef name

"my name is person"

endendclass user < person

end## user inherits person

puts user.new.name ## my name is person

class << self

def inherited(base)

super

activesupport.run_load_hooks(:before_configuration, base.instance)

endend

method_missing 可能是ruby中使用最廣的鉤子,當我們試圖訪問乙個物件上不存在的方法時則會呼叫這個鉤子方法.

class person

def method_missing(sym, *args)

"# not defined on #"

enddef name

"my name is person"

endendp = person.new

puts p.name # => my name is person

puts p.address # => address not defined on #

person 並沒有定義 address, 這將會丟擲乙個異常.method_missing 鉤子可以優雅地捕捉到這些未定義的方法.

method_missing 接收兩個引數:被呼叫的方法名和傳遞給該方法的引數。 首先ruby會尋找我們試圖呼叫的方法,如果方法沒找到則會尋找 method_missing 方法。 現在我們過載了 person 中的 method_missing,因此ruby將會呼叫它而不是丟擲異常。

Ruby 型別和方法

1.標準型別 1.1 數字 ruby支援整數和浮點數。整數可以是任何長度,一定範圍內的整數在內部以二進位制形式儲存,它們是fixnum類的物件,範圍之外的整數儲存在bugnum類的物件中。ruby會自動管理它們之間的來回轉換。在書寫整數時,可以使用乙個可選的前導符號,可選的進製指示符 0b表示二進位...

Flask 中請求鉤子的理解和應用?

請求鉤子是通過裝飾器的形式實現的,支援以下四種 1,before first request 在處理第乙個請求前執行 2,before request 在每次請求前執行 3,after request 如果沒有未處理的異常丟擲,在每次請求後執行 4,teardown request 即使有未處理的異...

Ajax介紹和基本應用方法

中文音譯 阿賈克斯 屬於js中的知識點 ajax是瀏覽器提供的一套方法,通過呼叫這些方法可以實現頁面的無重新整理更新資料,提高使用者瀏覽 應用的體驗。ajax技術實現了使用者瀏覽網頁的過程中區域性的更新資料,提高了應用體驗。再不重新整理頁面的過程中向伺服器傳送請求家在資料 1 頁面上拉載入更多資料 ...