久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    說說Rails吧,config的幕后工作 - 差沙的密碼 -- SSHWSFC‘s cod...

     nbtymm 2006-11-22

    說ruby是怪異的語法有點不妥當,動態語言里面不乏這樣的語法出現。但是看了一些源碼后發現,使用ruby的用法真的各有不同,就像大家以前說的,ruby每個人寫出來的可能都不同。

    現來說Rails里面如何加載config的吧。

    在java里面config絕對是一個resource文件,然后通過讀取配置的工具加入進來,在分析處理。

    在ROR里面完全不是這么回事。

    1.首先大家要了解的是,在我們啟動 ruby script/server 的時候,rails做了一系列的處理,最后他執行了environment.rb

    ruby 代碼
    Rails::Initializer.run do  | config |     
      
    #  這里能插入我們自己的配置。    
       #  config. 之類    
    end   

    這里的config其實是Initializer內部的一個變量,掌控全局的配置信息,我們可以使用這個config來配置我們想要的。Rails::Initializer.run的源碼是這樣的,yield再一次顯示了他的威力,讓我們在配置文件中得以配置config。然后實例化了一個initializer 之后,把config作為參數傳入了。

    ruby 代碼
    def  self.run(command  =  :process, configuration  =  Configuration.new)    
      
    yield  configuration  if  block_given?    
      initializer 
    =  new configuration    
      initializer.send(command)    
      initializer    
    end   

    我們接著往下走,可以看到initializer 做了一系列的初始化工作,包括load_path的設定,路由的初始化,和activerecord的初始化。我們關心的還是配置如何起作用,那么來看看environments目錄下面的配置文件是如何導入的吧。

    ruby 代碼

    def  load_environment    
      silence_warnings do   
        config 
    =  configuration    
        constants 
    =  self. class .constants    
        eval(IO.read(configuration.environment_path), binding)    
        (self.
    class .constants  -  constants).each do  | const |     
          Object.const_set(const, self.
    class .const_get(const))    
        end   
      end   
    end   

    IO.read(configuration.environment_path) ,,這里就不使用什么回調不回調了,而是干脆IO拿出來eval一把,這里也是吃了一驚,這樣也可以呀~~~~~~~然后,我們可以看看,他處理常量的方法,把自己配置文件中的常量全部放入Object里面,起到全局常量的目的。

    最絕的還是initialize_framework_settings,使用了有一個ruby的技巧。

    ruby 代碼

    def  initialize_framework_settings    
      configuration.frameworks.each do 
    | framework |     
        base_class 
    =  framework.to_s.camelize.constantize.const_get( " Base " )    
       
        configuration.send(framework).each do 
    | setting, value |     
          base_class.send(
    " #{setting}= " , value)    
        end   
      end   
    end   

    configuration.frameworks里面存放的是rails個個組件的名字,比方說active_record之類。然后把這個名字大寫轉換,然后用constantize取得ActiveRecord這個Module(注意,這些東在都在activerecord里面呢,activesupport/lib/active_support/core_ext/string/inflections.rb )。然后用const_get取得這個模塊的Base類,也就是ActiveRecord::Base這個類了(下面都叫做Base類),所有的Rails的組件都是這個命名規則改天我們自己想要做一個Rails的組件加進來,也可以這樣(但是要稍微修改一個源碼)。

    然后,我們吧config里面的內容給Base類。configuration.send(framework)是調用一個組件名稱的方法,比方說active_record,就是去的config里面的active_record屬性(這是最基本的),通過后面的do我們可以看到config返回的是一個hash,然后把hash中每一個key作為變量,value為傳入值,傳入Base類。。。這里大家應該沒什么問題了,看看我們的config文件是怎么寫的吧。

    ruby 代碼
    #  Settings specified here will take precedence over those in config/environment.rb    
       
    #  In the development environment your application‘s code is reloaded on    
    #
     every request.  This slows down response time but is perfect for development    
    #
     since you don‘t have to restart the webserver when you make code changes.    
    config.cache_classes  =  false   
       
    #  Log error messages when you accidentally call methods on nil.    
    config.whiny_nils  =  true   
       
    #  Enable the breakpoint server that script/breakpointer connects to    
    config.breakpoint_server  =  true   
       
    #  Show full error reports and disable caching    
    config.action_controller.consider_all_requests_local  =  true   
    config.action_controller.perform_caching             
    =  false   
    config.action_view.cache_template_extensions         
    =  false   
    config.action_view.debug_rjs                         
    =  true   
       
    #  Don‘t care if the mailer can‘t send    
    config.action_mailer.raise_delivery_errors  =  false   

    哦,看著很暈吧,config就是我們的配置對象,按照我們上面的說法,config.action_view之類framework的變量應該是一個hash才對呀,如果是hash的話,不應該用這樣的方式傳入,可能會用 config.action_view = {:debug_rjs => true}來傳入。

    OK.我們來看這個變量到底是什么樣的hash。

    ruby 代碼
    def  initialize    
      .    
      .    
      
    for  framework  in  default_frameworks    
        self.send(
    " #{framework}= " , OrderedOptions.new)    
      end   
    end   

    在初始化這些變量的時候,Rails給他賦值為OrderedOptions.new。這個特殊的類型可能就是關鍵。

    ruby 代碼
    class  OrderedOptions  <  OrderedHash  # :nodoc:    
       def  [] = (key, value)    
        super(key.to_sym, value)    
      end   
          
      
    def  [](key)    
        super(key.to_sym)    
      end   
       
      
    def  method_missing(name,  * args)    
        
    if  name.to_s  =~   / (. * ) = $ /     
          self[$
    1 .to_sym]  =  args.first    
        
    else    
          self[name]    
        end   
      end   
    end   

    看到其中的玄妙了么,method_missing~~~!! 如果調用一個**=的方法 ,就像當用傳入一個HASH的值,key就是方法的名字。

    也就是:config.action_view.debug_rjs  = true 相當于config.action_view[:debug_rjs] = true

    OK ,大體上描述了一下,可以看到簡單的一個Rails初始化已經給我們展示了幾乎全部ruby的靚麗之處,這能說明,這個亮點肯定是貫穿rails的基本,在以后的深入研究中我們就能看到了。

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 亚洲AV日韩AV不卡在线观看| 久久久久国产精品免费免费搜索| 午夜免费国产体验区免费的| 精品久久久久久无码中文野结衣 | 国产在线高清视频无码| 无码国产精品一区二区免费模式 | 午夜无码区在线观看亚洲| 精品免费看国产一区二区| 成人无码视频97免费| 中文字幕国产精品综合| 青青草原国产AV福利网站| 在线 | 18精品免费1区2| 亚洲伊人五月丁香激情| 奇米四色7777中文字幕| 亚洲欧美中文字幕日韩一区二区| 精品久久久久久无码中文野结衣 | 国产69精品久久久久777| 成年女人片免费视频播放A| 无码国产精品久久一区免费| 在线播放亚洲成人av| 天干天干天啪啪夜爽爽AV| 免费现黄频在线观看国产| 国内精品久久久久影院优| 久久精品国产福利一区二区| 日产高清砖码砖专区| 色偷偷人人澡久久超碰97| 在线a亚洲老鸭窝天堂| 亚洲日本VA午夜在线电影| 国产AV影片麻豆精品传媒| 中文字幕无码日韩专区免费| 日本一高清二区视频久二区| 久久精品国产亚洲av天海翼| 嫩草院一区二区乱码| 免费现黄频在线观看国产| 色香欲天天影视综合网| 久久久久久久波多野结衣高潮| 久青草国产在视频在线观看| A级大胆欧美人体大胆666| 国产高跟黑色丝袜在线| 少妇粗大进出白浆嘿嘿视频| 欧美人与禽2o2o性论交|