小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 nbtymm 2006-11-22

說ruby是怪異的語法有點(diǎn)不妥當(dāng),動(dòng)態(tài)語言里面不乏這樣的語法出現(xiàn)。但是看了一些源碼后發(fā)現(xiàn),使用ruby的用法真的各有不同,就像大家以前說的,ruby每個(gè)人寫出來的可能都不同。

現(xiàn)來說Rails里面如何加載config的吧。

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

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

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

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

這里的config其實(shí)是Initializer內(nèi)部的一個(gè)變量,掌控全局的配置信息,我們可以使用這個(gè)config來配置我們想要的。Rails::Initializer.run的源碼是這樣的,yield再一次顯示了他的威力,讓我們?cè)谂渲梦募械靡耘渲胏onfig。然后實(shí)例化了一個(gè)initializer 之后,把config作為參數(shù)傳入了。

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的設(shè)定,路由的初始化,和activerecord的初始化。我們關(guān)心的還是配置如何起作用,那么來看看environments目錄下面的配置文件是如何導(dǎo)入的吧。

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

最絕的還是initialize_framework_settings,使用了有一個(gè)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個(gè)個(gè)組件的名字,比方說active_record之類。然后把這個(gè)名字大寫轉(zhuǎn)換,然后用constantize取得ActiveRecord這個(gè)Module(注意,這些東在都在activerecord里面呢,activesupport/lib/active_support/core_ext/string/inflections.rb )。然后用const_get取得這個(gè)模塊的Base類,也就是ActiveRecord::Base這個(gè)類了(下面都叫做Base類),所有的Rails的組件都是這個(gè)命名規(guī)則改天我們自己想要做一個(gè)Rails的組件加進(jìn)來,也可以這樣(但是要稍微修改一個(gè)源碼)。

然后,我們吧config里面的內(nèi)容給Base類。configuration.send(framework)是調(diào)用一個(gè)組件名稱的方法,比方說active_record,就是去的config里面的active_record屬性(這是最基本的),通過后面的do我們可以看到config返回的是一個(gè)hash,然后把hash中每一個(gè)key作為變量,value為傳入值,傳入Base類。。。這里大家應(yīng)該沒什么問題了,看看我們的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就是我們的配置對(duì)象,按照我們上面的說法,config.action_view之類framework的變量應(yīng)該是一個(gè)hash才對(duì)呀,如果是hash的話,不應(yīng)該用這樣的方式傳入,可能會(huì)用 config.action_view = {:debug_rjs => true}來傳入。

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

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

在初始化這些變量的時(shí)候,Rails給他賦值為OrderedOptions.new。這個(gè)特殊的類型可能就是關(guān)鍵。

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~~~??! 如果調(diào)用一個(gè)**=的方法 ,就像當(dāng)用傳入一個(gè)HASH的值,key就是方法的名字。

也就是:config.action_view.debug_rjs  = true 相當(dāng)于config.action_view[:debug_rjs] = true

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

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多