麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Ruby > 正文

Ruby中鉤子方法的運用實例解析

2020-10-29 19:34:46
字體:
來源:轉載
供稿:網友

通過使用鉤子方法,可以讓我們在Ruby的類或模塊的生命周期中進行干預,可以極大的提高編程的靈活性。
與生命周期相關的鉤子方法有下面這些:

類與模塊相關

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

單件類相關

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

示例代碼

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

除了上面列出來的一些方法外,也可以通過重寫父類的某個方法,進行一些過濾操作后,再通過調用super方法完成原函數的功能,從而實現類似鉤子方法的功效,如出一轍,環繞別名也可以作為一種鉤子方法的替代實現。

運用實例
任務描述:

寫一個操作方法類似attr_accessor的attr_checked的類宏,該類宏用來對屬性值做檢驗,使用方法如下:

class Person include CheckedAttributes attr_checked :age do |v|  v >= 18 endendme = Person.newme.age = 39 #okme.age = 12 #拋出異常

實施計劃:

使用eval方法編寫一個名為add_checked_attribute的內核方法,為指定類添加經過簡單校驗的屬性
重構add_checked_attribute方法,去掉eval方法,改用其它手段實現
添加代碼塊校驗功能
修改add_checked_attribute為要求的attr_checked,并使其對所有類都可用
通過引入模塊的方式,只對引入該功能模塊的類添加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 "endadd_checked_attribute(String, :my_attr)t = "hello,kitty"t.my_attr = 100puts t.my_attrt.my_attr = falseputs t.my_attr

這一步使用eval方法,用class和def關鍵詞分別打開類,且定義了指定的屬性的get和set方法,其中的set方法會簡單的判斷值是否為空(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 endend

這一步更換掉了eval方法,同時也分別用class_eval和define_method方法替換了之前的class與def關鍵字,實例變量的設置和獲取分別改用了instance_variable_set和instance_variable_get方法,使用上與第一步沒有任何區別,只是一些內部實現的差異。

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 endendadd_checked_attribute(String, :my_attr){|v| v >= 180 }t = "hello,kitty"t.my_attr = 100 #Invaild attribute (RuntimeError)puts t.my_attrt.my_attr = 200puts t.my_attr #200

沒有什么奇特的,只是加了通過代碼塊驗證,增加了校驗的靈活性,不再僅僅局限于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 endendString.add_checked(:my_attr){|v| v >= 180 }t = "hello,kitty"t.my_attr = 100 #Invaild attribute (RuntimeError)puts t.my_attrt.my_attr = 200puts t.my_attr #200

這里我們把之前頂級作用域中方法名放到了Class中,由于所有對象都是Class的實例, 所以這里定義的實例方法,也能被Ruby中的其它所有類訪問到,同時在class定義中,self就是當前類,所以也就省去了調用類這個參數和class_eval方法,并且我們把方法的名字也改成了attr_checked。

Step 5

module CheckedAttributes def self.included(base)  base.extend ClassMethods endendmodule 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 endendclass Person include CheckedAttributes attr_checked :age do |v|  v >= 18 endend

最后一步通過鉤子方法,在CheckedAttributes模塊被引入后,對當前類通過被引入模塊進行擴展, 從而使當前類支持引入后的方法調用,即這里的get與set方法組。

到此,我們已經得到了一個名為attr_checked,類似attr_accessor的類宏,通過它你可以對屬性進行你想要的校驗。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 日韩毛片在线看 | 欧美2区 | 天天操天天碰 | 久在线观看福利视频69 | 91热久久免费频精品黑人99 | 成人三级黄色片 | 欧美成人黄色小视频 | 精品一区二区三区日本 | 手机国产乱子伦精品视频 | av手机免费在线观看 | 国产一级一国产一级毛片 | 国产品久久 | 黄色一级毛片免费看 | 二级大黄大片高清在线视频 | 一区二区三区播放 | av视屏 | 一级免费看片 | 毛片在线免费观看视频 | 久色成人 | 毛片免费视频网站 | 国产精品久久久久永久免费 | 嗯~啊~用力~高h | 成人一级黄色大片 | 黄色视屏免费观看 | 亚洲卡通动漫在线观看 | 亚洲性在线视频 | 欧美精品久久天天躁 | 中国女警察一级毛片视频 | 日韩黄色片免费看 | 欧美va亚洲 | 黑人一区二区 | 99欧美视频 | 男女污污视频网站 | 91麻豆精品国产91久久久更新资源速度超快 | 国产麻豆交换夫妇 | 国产男女 爽爽爽爽视频 | 欧美成人三级大全 | sm高h视频 | 中国洗澡偷拍在线播放 | 国产91小视频在线观看 | 全黄性性激高免费视频 |