Rails5源碼分析(蛋人)

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'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末心铃,一起剝皮案震驚了整個濱河市准谚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌去扣,老刑警劉巖柱衔,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愉棱,居然都是意外死亡唆铐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門奔滑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艾岂,“玉大人,你說我怎么就攤上這事朋其⊥踉。” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵梅猿,是天一觀的道長氓辣。 經(jīng)常有香客問我,道長粒没,這世上最難降的妖魔是什么筛婉? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮癞松,結(jié)果婚禮上爽撒,老公的妹妹穿的比我還像新娘。我一直安慰自己响蓉,他們只是感情好硕勿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著枫甲,像睡著了一般源武。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上想幻,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天粱栖,我揣著相機(jī)與錄音,去河邊找鬼脏毯。 笑死闹究,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的食店。 我是一名探鬼主播渣淤,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼赏寇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了价认?” 一聲冷哼從身側(cè)響起嗅定,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎用踩,沒想到半個月后渠退,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捶箱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年智什,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丁屎。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡荠锭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晨川,到底是詐尸還是另有隱情证九,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布共虑,位于F島的核電站愧怜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏妈拌。R本人自食惡果不足惜拥坛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尘分。 院中可真熱鬧猜惋,春花似錦、人聲如沸培愁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽定续。三九已至谍咆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間私股,已是汗流浹背摹察。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倡鲸,地道東北人港粱。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親查坪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Awesome Ruby Toolbox Awesome A collection of awesome Ruby...
    debbbbie閱讀 2,800評論 0 3
  • ruby 的命名規(guī)則局部變量:以英文字母或者_(dá)開頭宁炫,如:name = "this is a local varia...
    云莉6閱讀 769評論 0 0
  • 同心斷偿曙,空留癡心長消黯。長消黯羔巢,塵影往復(fù)望忆,無據(jù)殘照。 潮來潮去紛紛散竿秆,重來亦是情隔岸启摄。情隔岸,多年獨(dú)闖幽钢,天涯別遠(yuǎn)歉备。
    何瀟湘閱讀 325評論 0 3
  • 碧水廊腰,容姿曼嬈匪燕,一江東流煙飄渺蕾羊,待我妝整,換洗舊袍帽驯,時年少龟再。 最怕猶是,傷春時候尼变,十二橋欄桿倚遍利凑,愁不勝,當(dāng)年...
    落宸風(fēng)閱讀 307評論 0 1