国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 編程 > Ruby > 正文

ruby元編程實際使用實例

2020-03-29 12:08:58
字體:
來源:轉載
供稿:網友

很喜歡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_worldend

上面是一個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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
最新天堂资源在线| 亚洲www色| 最近中文av字幕在线中文| 九九热视频在线观看| 久久久久久77777| 中文字幕在线影院| 国产福利图片| www.操.com| 最近久乱中文字幕| 精品国产高清a毛片无毒不卡 | 波多野结衣中文字幕久久| 日本欧美在线视频免费观看| 国产不卡在线| 四虎国产精品永久| 国产一级黄色大片| 欧美视频免费一区二区三区| 国产网红在线观看| 免费a级毛片在线观看| 国产啊啊啊视频在线观看| 超碰在线观看免费版| 91麻豆免费在线视频| 91超碰在线免费| 九九热视频精品在线观看| 中文字幕av高清| 国产精品欧美色图| 开心婷婷激情五月| 亚洲最新永久在线观看| 交换国产精品视频一区| 伊人网站在线| 国产精品18久久久久久久久久| 白浆爆出在线观看| 中文在线视频观看| 国产黄色高清在线| 国产视频福利| 国产一二三区在线| 五月婷婷在线视频| 国产一级性片| 国产网站麻豆精品视频| 国产乱人视频免费播放| 激情丁香在线| 午夜免费福利在线观看| 国产有码在线| 黄色毛片在线| 尤物视频免费在线观看| 国产免费a∨片在线观看不卡| 四虎a级欧美在线观看| 亚洲天堂电影在线观看| 亚洲xxxxxx| 九九视频九九热| 天天操人人爽| 国产成人无吗| 亚洲精品少妇久久久久久| 亚洲成年人视频| 欧美午夜电影一区二区三区| 久久久久久77777| 国产三级在线| 天天插天天操| 久热免费视频| 91视频黄色| 欧美96在线| 国产系列在线观看| 亚洲天堂久久久| 成人精品一区二区三区免费| 国产精品剧情一区二区三区| 在线āv视频| 国产字幕在线看| 国产福利小视频在线| 四虎一区二区三区| 最新国产在线| 亚洲日本一区二区三区在线观看| 青青草在线视频免费观看| 最近久乱中文字幕| 伊人中文字幕在线| 午夜免费福利在线观看| 亚洲免费国产| 国产秀色在线www免费观看| 99在线视频观看| 最近中文av字幕在线中文| 99免费视频| 国产亚洲精品拍拍拍拍拍| 一区二区三区四区在线免费视频| wwww亚洲| 精品麻豆国产| 国产视频在线播放| 狠狠综合久久久综合| 97国产视频| 综合蜜桃精品| 伊人春色在线| 9999在线视频| 国产高清在线| 国产日产一区二区三区| 九九热在线视频观看| 四虎国产精品永久| 亚洲久草视频| www.91av| 欧美激情福利视频在线观看免费| 99久久精品免费观看国产| 国产精品入口麻豆完整版| 久久精品蜜桃| 超碰免费在线观看| 久久精品免视着国产成人| www.99av| a视频免费看| jizz在线视频| 黄色免费av| 国产丝袜视频在线播放| 国产精品日日爱| 精品亚洲成a人片在线观看| 国产区视频在线观看| 国产丝袜在线| 精品无人区乱码1区2区3区免费| 国产精品视频流白浆免费视频| 国产精品视频一区麻豆| 99在线播放| 蜜桃视频网站在线| 中文字幕一区二区三区免费视频| 国产卡二和卡三的视频| 精品中文字幕不卡在线视频| 成年网在线观看免费观看网址| 最近高清中文在线字幕在线观看| 国产日本视频| 性网站在线看| 狠狠操五月天| 91麻豆福利| 国产麻豆精品高清在线播放| 国产精品合集一区二区| 夜夜嗨yeyeh| 91av资源在线| 国产区视频在线播放| 中文在线有码| 国产在线一区二区视频| 精品亚洲成a人片在线观看| 中文产幕区在线观看| 久久久久久77777| 国产videos| 免费a在线观看| 99爱视频在线观看| 天堂在线免费视频| 阿v免费在线观看| 国产白浆在线| 国产偷窥洗澡视频| 免费久久网站| h网址在线观看| 国产二区在线播放| 国产色a在线观看| 久久亚洲资源| 欧美视频免费一区二区三区| 国产精品人人| 国产美女一区视频| www.香蕉视频在线观看| 在线亚洲精品自拍| 国产对白叫床清晰在线播放| 国产精品一区二区三区四区色| 亚洲91av| 亚洲国产成人综合| 伊人中文在线| 亚洲综合在线免费| 精品成人一区二区三区免费视频| 国产一区二区三区四区尤物| 日本视频一二三区中文字幕| 亚洲最新永久观看在线| 69视频在线观看| 国产精美视频| 国产成人亚洲综合小说区| 国产香蕉视频在线观看| 天堂在线中文| 国产天堂在线| 2018狠狠干| 亚洲精品aaaa| 久久久久久久久久久久网站| 免费在线观看a| 国产毛片视频| 国产午夜视频| 精品999视频| sm国产在线调教视频| 全网国产福利在线播放| 九七电影韩国女主播在线观看| av在线首页| 日本成a人片在线观看| 国产主播色在线| 国产黄色网页| 欧美婷婷久久五月精品三区| 福利视频网站导航| 国产欧美日韩精品综合| 香蕉视频在线观看网站| 久久精品最新免费国产成人| 国产视频2区| 日本欧美在线视频免费观看| 狠狠干在线视频| 精品无人区乱码1区2区3区免费| 中文av在线播放| 蜜桃av网站| 国产女主播在线| 免费影视观看网站入口| 国产区视频在线播放| 日本国产在线| 18激情网站| 天天操天天是| 九九在线视频| sese在线视频|