欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁 > 知識庫 > ruby元編程實際使用實例

ruby元編程實際使用實例

熱門標簽:柯城手機地圖如何做地圖標注 征服者企業地圖標注 天津外呼系統怎么收費 中牟外呼系統違法嗎 漯河電銷 AI電銷機器人 線路 外呼線路從哪里出來的 巫師3地圖標注魔力之所 淮安自動外呼系統供應商

很喜歡ruby元編程,puppet和chef用到了很多ruby的語言特性,來定義一個新的部署語言。
分享幾個在實際項目中用到的場景,能力有限,如果有更優方案,請留言給我:)

rpc接口模板化——使用eval、alias、defind_method

require 'rack/rpc'

class Server  Rack::RPC::Server
 def hello_world
  "Hello, world!"
 end

 rpc 'hello_world' => :hello_world
end

上面是一個rpc server,編寫一個函數,調用rpc命令進行注冊。

采用define_method、eval、alias方法,可以實現一個判斷rpc/目錄下的*.rb文件,進行加載和rpc接口注冊的功能,實現代碼如下:

module RPC
  require 'rack/rpc'
  #require rpc/*.rb文件
  Dir.glob(File.join(File.dirname(__FILE__), 'rpc', "*.rb")) do |file|
   require file
  end
  class Runner  Rack::RPC::Server
   #include rpc/*.rb and regsiter rpc call
   #eg. rpc/god.rb  god.hello
   @@rpc_list = []
   Dir.glob(File.join(File.dirname(__FILE__), 'rpc', "*.rb")) do |file|
    rpc_class = File.basename(file).split('.rb')[0].capitalize
    rpc_list = []
    
    #加載module下的方法到Runner這個類下面
    eval "include Frigga::RPC::#{rpc_class}"
    #獲取聲明的RPC接口
    eval "rpc_list = Frigga::RPC::#{rpc_class}::RPC_LIST"
    rpc_list.each do |rpc_name|
     #alias一個新的rpc方法,叫old_xxxx_xxxx
     eval "alias :old_#{rpc_class.downcase}_#{rpc_name} :#{rpc_name}"

     #重新定義rpc方法,添加一行日志打印功能,然后再調用old_xxxx_xxxx rpc方法
     define_method "#{rpc_class.downcase}_#{rpc_name}".to_sym do |*arg|
      Logger.info "[#{request.ip}] called #{rpc_class.downcase}.#{rpc_name} #{arg.join(', ')}"
      eval "old_#{rpc_class.downcase}_#{rpc_name} *arg"
     end 

     #注冊RPC調用
     rpc "#{rpc_class.downcase}.#{rpc_name}" => "#{rpc_class.downcase}_#{rpc_name}".to_sym

     #添加到全局變量,匯總所有的rpc方法
     @@rpc_list  "#{rpc_class.downcase}.#{rpc_name}"
    end
   end
   
   def help
    rpc_methods = (['help'] + @@rpc_list.sort).join("\n")
   end
   rpc "help" => :help

  end
 end #RPC

完成上述功能后,可以非常方便的開發rpc接口,例如下面這個IP地址增、刪、查的代碼,注冊ip.list, ip.add和ip.del方法:

module RPC
  module Ip
   #RPC_LIST used for regsiter rpc_call
   RPC_LIST = %w(list add del)

   def list
    $white_lists
   end   

   def add(ip) 
    if ip =~ /^((25[0-5]|2[0-4]\d|[0-1]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[0-1]?\d\d?)$/
     $white_lists  ip
     write_to_file
     return "succ"
    else
     return "fail"
    end
   end

   def del(ip)
    if $white_lists.include?(ip)
     $white_lists.delete ip
     write_to_file
     return "succ"
    else
     return "fail"
    end    
   end

   def write_to_file
     File.open(IP_yml, "w") do |f|
      $white_lists.uniq.each {|i| f  "- #{i}\n"}
     end
   end
  end 
 end

DSL——使用instance_eval

instance_eval是ruby語言中的瑞士軍刀,特別是支持DSL方面。
我們來看一下chef(一個開源的自動化部署工具)中設置文件模板的API:

復制代碼 代碼如下:

    template "/path/to/file.conf" do
      source "file.conf.erb"
      owner  "wilbur"
      mode   "0744"
    end

上述代碼中,source、owner、mode需要從外部block,傳遞到template內部的block中,為了實現該目的,采用了instance_eval代碼如下:

  class ChefDSL
   def template(path, block)
    TemplateDSL.new(path, block)
   end
  end

  class TemplateDSL
   def initialize(path, block)
    @path = path
    instance_eval block
   end

   def source(source); @source = source; end
   def owner(owner);  @owner = owner; end
   def mode(mode);   @mode  = mode;  end
  end

上面這個小技巧使得TemplateDSL對象可以應用block,和在自己的scope一樣。block可以訪問和調用TemplateDSL中的變量和方法。

如果沒有使用instance_eval,如下面的代碼,ruby就會拋出一個NoMethodError,因為source、owner、mode無法在block中被訪問到。

復制代碼 代碼如下:

    class TemplateDSL
      def initialize(path, block)
        @path = path
        block.call
      end
    end

當然也可以使用yeild傳遞變量的方式實現,但沒有instance_eval簡潔和靈活。

命令行交互——使用instance_eval

命令行交互,可以采用highline這個gem.
但highline在有些方面不能滿足我的需求,比如類似上面介紹的chef template功能,達到的效果如下,大大簡化了重復代碼:

復制代碼 代碼如下:

        #檢查frigga fail,詢問是否繼續
        Tip.ask frigga_fail? do
          banner "Check some frigga failed, skip failed host and continue deploy?"
          on :yes
          on :quit do
            raise Odin::TipQuitExcption
          end
        end
        ...

        #運行時顯示結果如下:
        Check some frigga failed, skip failed host and continue deploy? [yes/quit]
        #輸入yes繼續,輸入quit退出

實現代碼如下:

 require 'colorize'
 class Tip
  def self.ask(stat = true, block)
   new(block).ret if stat == true
  end

  attr_reader :ret
  def initialize(block)
   @opt = []
   @caller = {}
   @banner = ""
   @ret = false
   self.instance_eval(block)
   print "#{@banner} [#{@opt.join('/')}]: ".light_yellow
   loop do
    x = gets.chomp.strip.to_sym
    if @opt.include?(x)
     @ret = ( @caller[x].call if @caller.key?(x) )
     if @ret == :retry
      print "\n#{@banner} [#{@opt.join('/')}]: ".light_yellow
      next
     else
      return @ret
     end
    else
     print "input error, please enter [#{@opt.join('/')}]: ".light_yellow
    end
   end

  end

  def on(opt, block)
   @opt  opt
   @caller[opt] = block if block_given?
  end
  def banner(str)
   @banner = str
  end
 end
您可能感興趣的文章:
  • Ruby元編程的一些值得注意的地方
  • ruby元編程之創建自己的動態方法
  • ruby元編程之method_missing的一個使用細節
  • Ruby元編程之夢中情人method_missing方法詳解
  • Ruby元編程技術詳解(Ruby Metaprogramming techniques)
  • Ruby元編程小結
  • Ruby和元編程之萬物皆為對象
  • Ruby元編程基礎學習筆記整理

標簽:大慶 克拉瑪依 河池 西雙版納 南昌 甘孜 內江 棗莊

巨人網絡通訊聲明:本文標題《ruby元編程實際使用實例》,本文關鍵詞  ruby,元,編程,實際,使用,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《ruby元編程實際使用實例》相關的同類信息!
  • 本頁收集關于ruby元編程實際使用實例的相關信息資訊供網民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    日本 欧美 国产| 国产精品久久久久影视| 午夜免费久久看| 91福利视频免费观看| 色视频一区二区| 国产精品电影一区二区| 成人免费毛片片v| 婷婷久久综合网| 国产精品高潮呻吟| 波波电影院一区二区三区| 永久看片925tv| 中文字幕综合网| 91老师国产黑色丝袜在线| 欧亚洲嫩模精品一区三区| 一区二区三区精品| 中文字幕在线国产| 在线播放亚洲一区| 免费高清不卡av| 欧美人妻一区二区三区| 国产午夜久久久久| 国产成人aaaa| 91成人网在线| 午夜精品视频一区| 无码h肉动漫在线观看| 久久精品一区二区三区不卡 | 91精品国产高清一区二区三区| 亚洲va天堂va国产va久| 亚洲蜜桃精久久久久久久久久久久| 日韩欧美亚洲另类制服综合在线 | 无码国产69精品久久久久同性| 欧美精品一区二区三区一线天视频| 激情六月婷婷久久| 中国毛片直接看| 一卡二卡三卡日韩欧美| 一级国产黄色片| 久久精品亚洲精品国产欧美kt∨| 成人在线综合网站| 欧美日韩精品是欧美日韩精品| 日韩电影免费在线观看网站| 在线免费观看视频| 国产精品剧情在线亚洲| 欧美69精品久久久久久不卡| 这里只有精品免费| 激情都市一区二区| 国产高清在线免费观看| 亚洲bdsm女犯bdsm网站| 日本精品在线观看视频| 国产精品高潮呻吟久久| 日本人添下边视频免费| 久久男人中文字幕资源站| 成人av网站在线观看| 欧美精品丝袜中出| 国产一区二区三区国产| 91国偷自产一区二区使用方法| 偷拍与自拍一区| 男女全黄做爰文章| 亚洲国产视频直播| 亚洲色图日韩精品| 亚洲综合免费观看高清在线观看| 中文字幕一区二区人妻在线不卡| 中文在线资源观看网站视频免费不卡| 亚洲AV无码久久精品国产一区| 日韩视频一区二区| 成人丝袜18视频在线观看| 91麻豆精品国产综合久久久久久| 国产伦精一区二区三区| 欧美日韩成人综合在线一区二区| 韩国欧美国产1区| 欧美色综合网站| 国产一区二区在线免费观看| 欧美私人免费视频| 国产一区在线不卡| 欧美视频自拍偷拍| 国产精品一区二区在线观看网站 | 精品污污网站免费看| 黄网站免费久久| 欧美精品精品一区| 成人午夜视频免费看| 精品国产凹凸成av人网站| 91麻豆国产香蕉久久精品| 久久久久亚洲蜜桃| 69xxx免费视频| 中文字幕日韩av资源站| 老牛影视av老牛影视av| 亚洲一卡二卡三卡四卡 | 国产精品免费人成网站酒店 | 欧美日韩和欧美的一区二区| 国产精品亚洲第一区在线暖暖韩国 | 精品国精品国产| 熟妇女人妻丰满少妇中文字幕| 日本一二三不卡| 亚洲一级中文字幕| 亚洲第一福利一区| 色视频成人在线观看免| 国产精品一区二区黑丝| 精品国产伦一区二区三区观看方式 | 精品一二三四在线| 51精品国自产在线| 97免费公开视频| 亚洲天堂av一区| 免费精品在线视频| 国产永久精品大片wwwapp| 欧美α欧美αv大片| 少妇献身老头系列| 一区二区三区欧美| 日本高清无吗v一区| 福利91精品一区二区三区| 久久老女人爱爱| 狠狠人妻久久久久久综合蜜桃| 亚洲成人中文在线| 欧美视频第二页| 国产伦精品一区二区三区妓女下载 | xfplay精品久久| 国产精品成人无码专区| 亚洲午夜一区二区| 欧美色区777第一页| 成人高清视频在线观看| 中文无字幕一区二区三区| 亚洲久久久久久久| 麻豆成人av在线| 欧美成人三级电影在线| 在线观看av中文字幕| 三级亚洲高清视频| 欧美一级久久久| a天堂视频在线观看| 午夜精品福利一区二区三区av| 欧美性大战久久久| 亚洲黄色小说在线观看| 亚洲成人www| 7777精品伊人久久久大香线蕉完整版 | 欧美天堂一区二区三区| 亚洲熟妇一区二区| 亚洲777理论| 日韩女同互慰一区二区| 三上悠亚影音先锋| 国产在线一区观看| 中文字幕第一区第二区| 岛国毛片在线观看| aaa欧美大片| 一区二区三区日韩精品| 欧美二区三区的天堂| 800av在线播放| 免费xxxx性欧美18vr| 欧美精品一区二区三区很污很色的| 久操视频免费看| 国模大尺度一区二区三区| 国产女人水真多18毛片18精品视频| 无码人妻精品中文字幕 | 久久色.com| 日韩激情小视频| 制服下的诱惑暮生| 日韩精品电影一区亚洲| 欧美精品一区视频| 日本青青草视频| 在线播放第一页| 美国十次综合导航| 国产欧美va欧美不卡在线| 色又黄又爽网站www久久| 国产精品99精品无码视亚| 奇米亚洲午夜久久精品| 久久久久久9999| 中文字幕影音先锋| 国产a级黄色片| 精东粉嫩av免费一区二区三区| 国产精品欧美一区二区三区| 欧美午夜精品久久久久久超碰 | 色婷婷av一区二区三区大白胸| 2018国产精品| 黑人巨大精品欧美一区| 国产精品福利一区二区三区| 欧美人伦禁忌dvd放荡欲情| 实拍女处破www免费看| 成人免费毛片片v| 偷拍与自拍一区| 中国色在线观看另类| 欧美日韩亚洲综合一区| 欧美激情亚洲色图| 92国产精品观看| 麻豆精品国产91久久久久久| 国产精品美女久久久久高潮| 欧美疯狂做受xxxx富婆| 美女网站视频色| 91色视频在线| 黑人巨大精品欧美一区| 亚洲一级二级在线| 国产午夜三级一区二区三| 欧美日韩卡一卡二| 国产在线免费av| 四川一级毛毛片| 国产在线精品一区在线观看麻豆| 亚洲精品国久久99热| 久久婷婷国产综合国色天香| 欧美视频在线一区| 青青草华人在线视频| 91视频在线免费| aaa欧美色吧激情视频| 狠狠狠色丁香婷婷综合激情 | 91国产精品成人| 国产成人免费观看网站| 老熟女高潮一区二区三区|