说说Rails吧,config的幕后工作 - 差沙的密码 -- SSHWSFC‘s cod...
来源:百度文库 编辑:神马文学网 时间:2024/03/29 22:35:03
说说Rails吧,config的幕后工作
说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的基本,在以后的深入研究中我们就能看到了。
说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的基本,在以后的深入研究中我们就能看到了。
说说Rails吧,config的幕后工作 - 差沙的密码 -- SSHWSFC‘s cod...
说说Rails吧,启动开始。 - 差沙的密码 -- SSHWSFC‘s code - Bl...
差模放大器的工作原理
rails 内置的时间格式化
主题班会——班主任的幕后工作
Lucene的工作原理 - HillMover‘s BLOG -
一夜情“专业户”的大学生涯 成绩太差难找工作
Ruby on Rails有用的插件
欢迎进入JRuby on Rails的世界
config
ASP.NET中web.config文件的配置
C#——web.config文件的配置
ASP.NET中web.config文件的配置
Struts-config.xml配置文件《action-mappings》元素的详解 -...
哪位能说说c/s、b/s、多层结构的定义及优缺点? Delphi / VCL组件开发及应用
[rails] 我的订餐系统 -- 小试ruby on rails
康熙 的 说说人 说说心 说说人心
焦点访谈:"猪案"的幕后
《人工智能》的幕后真相
解毒《蜗居》的幕后
丁香花幕后的故事
Facebook的幕后
我在苹果工作过,说说老板乔布斯的那些事 / 这雷人的 / 第5页
幕后故事 Mike Walling 的工作流程(镜头制作步骤)