01 autoload & ActiveSupport::Autoload的作用以及源碼分析
02 ActiveRecord Query源碼分析
補(bǔ)充1:rack
補(bǔ)充2:plugin
01 autoload & ActiveSupport::Autoload的作用以及源碼分析
查看activerecord源碼
#必須在某個生成的項(xiàng)目文件夾下面
bundle show activerecord
ruby中include竹椒、extend袋马、require娱俺、autoload方法區(qū)別
#include和extend方法
include方法將模塊的實(shí)例方法引入作為類的實(shí)例方法
extend方法將模塊的實(shí)例方法引入作為類的類方法
#require會運(yùn)行執(zhí)行這個文文件绳瘟,直接加載到內(nèi)存中,只能加載一次
#同一個文件夾中存在demo.rb和test.rb
#demo.rb
puts "this is the demo"
#test.rb
puts(require "./demo") #=>this is the demo, true
puts(require "./demo") #=>false
puts(require "./demo") #=>false
#load方法加載這個文件,可以重復(fù)加載,不會自動添加擴(kuò)展名
#同一個文件夾中存在demo.rb和test.rb
#demo.rb
puts "this is the demo"
#test.rb
puts(load "./demo.rb") #=>this is the demo, true
puts(load "./demo.rb") #=>this is the demo, true
puts(load"./demo.rb") #=>this is the demo, true
autoload對模塊進(jìn)行注冊寞忿,當(dāng)?shù)谝淮问褂迷撃K的時候,對該文件進(jìn)行require
#demo.rb和test.rb位于同一個文件夾下面
#test.rb
module Test
def self.simulate
puts "this is the simulate method"
end
end
#demo.rb
class Demo
autoload(:Test, "./test")
end
Demo.simulate #=> this is the simulate method
介紹autoload方法的源碼:
#active_record.rb
require "active_support"
require "active_support/rails"
module ActiveRecord
extend ActiveSupport::Autoload
autoload :Attribute
autoload :Base
…
end
#autoload.rb
require "active_support/inflector/methods"
module ActiveSupport
module Autoload
def self.extended(base) # :nodoc:
base.class_eval do
@_autoloads = {}
@_under_path = nil
@_at_path = nil
@_eager_autoload = false
end
end
def autoload(const_name, path = @_at_path)
unless path
full = [name, @_under_path, const_name.to_s].compact.join("::")
path = Inflector.underscore(full)
end
if @_eager_autoload
@_autoloads[const_name] = path
end
super const_name, path
end
end
02 ActiveRecord Query源碼分析
在development環(huán)境中添加方便調(diào)試的gem
gem 'pry'
gem 'pry-byebug'
gem 'pry-doc'
gem 'pry-rails'
補(bǔ)充1:rack
rack作用:提供了連接ruby框架和web服務(wù)器的應(yīng)用接口顶岸。rails和sintra就是基于rack生成的rack應(yīng)用腔彰。rack的作用是用來簡單處理http請求和相應(yīng)。
一個rack應(yīng)用就是一個ruby對象辖佣,能響應(yīng)call方法霹抛,接受environment的hash參數(shù)(對應(yīng)著http請求),返回一個數(shù)組卷谈,數(shù)組內(nèi)容包括杯拐,status[大于100的數(shù)值],headers[hash對象],body[包含字符對象的數(shù)組],整個數(shù)組對應(yīng)http響應(yīng)世蔗。rack包含了連接各種web服務(wù)器的handlers端逼,也包括和對應(yīng)各種web框架的adapter。在web服務(wù)器和框架中污淋,rack可以通過使用middleware定制到應(yīng)用程序中顶滩。
安裝和使用rack
#安裝
gem install rack
#引入
require 'rack' #=>true
#使用lambda建立簡單的rack應(yīng)用my_rack_proc,需要滿足上述的條件
my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
my_rack_proc.call({}) #=> [200, {"Content-Type" => "text/plain"}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
Rack::Handler.constants #=>[:CGI, :FastCGI, :WEBrick, :LSWS, :SCGI, :Thin]
Rack::Handler.WEBrick.run my_rack_proc #使用webrick服務(wù)啟動該rack應(yīng)用
[2017-01-02 15:40:33] INFO WEBrick 1.3.1
[2017-01-02 15:40:33] INFO ruby 2.3.0 (2015-12-25) [x86_64-darwin15]
[2017-01-02 15:40:33] INFO WEBrick::HTTPServer#start: pid=4434 port=8080
#瀏覽器中輸入如下語句進(jìn)行訪問
localhost:8080 #=>Hello. The time is 2017-01-02 15:41:00 +0800
#也可以指定端口
Rack::Handler::WEBrick.run my_rack_proc, :Port => 9876
#使用方法對象建立rack應(yīng)用
def my_method env
[200, {}, ["method called"]]
end
#使用webrick服務(wù)器進(jìn)行啟動
Rack::Handler::WEBrick.run method(:my_method) #=>method called
使用rackup
rackup是方便啟動rack應(yīng)用的工具寸爆,被包含在rack這個gem中诲祸。
#建立config.ru文件,文件中輸入如下內(nèi)容
#不指定服務(wù)器名稱而昨,run使用默認(rèn)的服務(wù)器
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
#也可以在相同的文件夾中建立類文件,在config.ru文件中導(dǎo)入
#my_app.rb
class MyApp
def call env
[200, {"Content-Type"=>"text/html"}, ["hello world"]]
end
end
#config.ru
require_relative 'my_app' #或者 require './my_app'
run MyApp.new
使用middleware和創(chuàng)建middleware
不知從哪里看rack使用了哪些middleware找田,只能查看通過rails middleware查看rails的middleware歌憨。
#添加Rack::Reloader,每次改變內(nèi)容不需要重新啟動
#通過use middleware名稱的方式添加middleware的方式
#config.ru
require_relative 'my_app'
use Rack::Reloader
run MyApp.new
#創(chuàng)建middleware
一個middleware是一個用于包裝了內(nèi)在程序的rack應(yīng)用墩衙。其程序的通用模板如下:
class MyRackMiddleware
def initialize(appl)
@appl = appl #appl是被包裝的程序名稱
end
def call(env)
end
end
#完整的middleware代碼务嫡,用于為body添加內(nèi)容
class MyRackMiddleware
def initialize(appl)
@appl = appl
end
def call(env)
status, headers, body = @appl.call(env)
append_s = "... greetings from RubyLearning!!"
new_body = ""
body.each { |string| new_body << " " << string }
new_body << " " << append_s
[status, headers, [new_body]]
end
end
# my_app.rb
class MyApp
def call(env)
[200, {"Content-Type" => "text/html"}, ["Hello Rack Participants from across the globe"]]
end
end
#config.ru
require './my_app'
require './myrackmiddleware'
use Rack::Reloader
use MyRackMiddleware
run MyApp.new
補(bǔ)充2:plugin
為String添加實(shí)例方法甲抖。
#建立lib/yaffle/string_core.rb文件,內(nèi)容如下
String.class_eval do
def to_squawk
"squawk! #{self}".strip
end
end
#在lib/yaffle.rb文件中require如上的文件
require_relative 'string_core'