人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

Ruby中鉤子方法的運(yùn)用實(shí)例解析

發(fā)布日期:2022-01-08 15:58 | 文章來(lái)源:gibhub

通過(guò)使用鉤子方法,可以讓我們?cè)赗uby的類或模塊的生命周期中進(jìn)行干預(yù),可以極大的提高編程的靈活性。
與生命周期相關(guān)的鉤子方法有下面這些:

類與模塊相關(guān)

  • Class#inherited
  • Module#include
  • Module#prepended
  • Module#extend_object
  • Module#method_added
  • Module#method_removed
  • Module#method_undefined

單件類相關(guān)

  • BasicObject#singleton_method_added
  • BasicObject#singleton_method_removed
  • BasicObject#singleton_method_undefined

示例代碼

module M1
  def self.included(othermod)
 puts “M1 was included into #{othermod}”
  end
end
module M2
  def self.prepended(othermod)
 puts “M2 was prepended to #{othermod}”
  end
end
class C
  include M1
  include M2
end
# 輸出
M1 was included into C
M2 was prepended to C
module M
  def self.method_added(method)
 puts “New method: M##{method}”
  end
  def my_method; end
end
# 輸出
New method: M#my_method

除了上面列出來(lái)的一些方法外,也可以通過(guò)重寫父類的某個(gè)方法,進(jìn)行一些過(guò)濾操作后,再通過(guò)調(diào)用super方法完成原函數(shù)的功能,從而實(shí)現(xiàn)類似鉤子方法的功效,如出一轍,環(huán)繞別名也可以作為一種鉤子方法的替代實(shí)現(xiàn)。

運(yùn)用實(shí)例
任務(wù)描述:

寫一個(gè)操作方法類似attr_accessor的attr_checked的類宏,該類宏用來(lái)對(duì)屬性值做檢驗(yàn),使用方法如下:

class Person
 include CheckedAttributes
 attr_checked :age do |v|
  v >= 18
 end
end
me = Person.new
me.age = 39 #ok
me.age = 12 #拋出異常

實(shí)施計(jì)劃:

使用eval方法編寫一個(gè)名為add_checked_attribute的內(nèi)核方法,為指定類添加經(jīng)過(guò)簡(jiǎn)單校驗(yàn)的屬性
重構(gòu)add_checked_attribute方法,去掉eval方法,改用其它手段實(shí)現(xiàn)
添加代碼塊校驗(yàn)功能
修改add_checked_attribute為要求的attr_checked,并使其對(duì)所有類都可用
通過(guò)引入模塊的方式,只對(duì)引入該功能模塊的類添加attr_checked方法
Step 1

def add_checked_attribute(klass, attribute)
 eval "
  class #{klass}
def #{attribute}=(value)
 raise 'Invalid attribute' unless value
 @#{attribute} = value
end
def #{attribute}()
 @#{attribute}
end
  end
 "
end
add_checked_attribute(String, :my_attr)
t = "hello,kitty"
t.my_attr = 100
puts t.my_attr
t.my_attr = false
puts t.my_attr

這一步使用eval方法,用class和def關(guān)鍵詞分別打開類,且定義了指定的屬性的get和set方法,其中的set方法會(huì)簡(jiǎn)單的判斷值是否為空(nil 或 false),如果是則拋出Invalid attribute異常。

Setp 2

def add_checked_attribute(klass, attribute)
 klass.class_eval do
  define_method "#{attribute}=" do |value|
raise "Invaild attribute" unless value
instance_variable_set("@#{attribute}", value)
  end
  define_method attribute do
instance_variable_get "@#{attribute}"
  end
 end
end

這一步更換掉了eval方法,同時(shí)也分別用class_eval和define_method方法替換了之前的class與def關(guān)鍵字,實(shí)例變量的設(shè)置和獲取分別改用了instance_variable_set和instance_variable_get方法,使用上與第一步?jīng)]有任何區(qū)別,只是一些內(nèi)部實(shí)現(xiàn)的差異。

Step 3

def add_checked_attribute(klass, attribute, &validation)
 klass.class_eval do
  define_method "#{attribute}=" do |value|
raise "Invaild attribute" unless validation.call(value)
instance_variable_set("@#{attribute}", value)
  end
  define_method attribute do
instance_variable_get "@#{attribute}"
  end
 end
end
add_checked_attribute(String, :my_attr){|v| v >= 180 }
t = "hello,kitty"
t.my_attr = 100 #Invaild attribute (RuntimeError)
puts t.my_attr
t.my_attr = 200
puts t.my_attr #200

沒(méi)有什么奇特的,只是加了通過(guò)代碼塊驗(yàn)證,增加了校驗(yàn)的靈活性,不再僅僅局限于nil和false之間了。

Step 4

class Class
 def attr_checked(attribute, &validation)
define_method "#{attribute}=" do |value|
 raise "Invaild attribute" unless validation.call(value)
 instance_variable_set("@#{attribute}", value)
end
define_method attribute do
 instance_variable_get "@#{attribute}"
end
 end
end
String.add_checked(:my_attr){|v| v >= 180 }
t = "hello,kitty"
t.my_attr = 100 #Invaild attribute (RuntimeError)
puts t.my_attr
t.my_attr = 200
puts t.my_attr #200

這里我們把之前頂級(jí)作用域中方法名放到了Class中,由于所有對(duì)象都是Class的實(shí)例, 所以這里定義的實(shí)例方法,也能被Ruby中的其它所有類訪問(wèn)到,同時(shí)在class定義中,self就是當(dāng)前類,所以也就省去了調(diào)用類這個(gè)參數(shù)和class_eval方法,并且我們把方法的名字也改成了attr_checked。

Step 5

module CheckedAttributes
 def self.included(base)
  base.extend ClassMethods
 end
end
module ClassMethods
 def attr_checked(attribute, &validation)
define_method "#{attribute}=" do |value|
 raise "Invaild attribute" unless validation.call(value)
 instance_variable_set("@#{attribute}", value)
end
define_method attribute do
 instance_variable_get "@#{attribute}"
end
 end
end
class Person
 include CheckedAttributes
 attr_checked :age do |v|
  v >= 18
 end
end

最后一步通過(guò)鉤子方法,在CheckedAttributes模塊被引入后,對(duì)當(dāng)前類通過(guò)被引入模塊進(jìn)行擴(kuò)展, 從而使當(dāng)前類支持引入后的方法調(diào)用,即這里的get與set方法組。

到此,我們已經(jīng)得到了一個(gè)名為attr_checked,類似attr_accessor的類宏,通過(guò)它你可以對(duì)屬性進(jìn)行你想要的校驗(yàn)。

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開通

自選配置、實(shí)時(shí)開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問(wèn)服務(wù)

1對(duì)1客戶咨詢顧問(wèn)

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部