標籤:
Ruby塊塊,在我看來就是插入一段可變的函數
block_name{ statement1 statement2 ..........}
看起來不知道是什麼,不過別急,繼續往下看。塊函數通過yield來調用yield 語句yield英文就是 屈服,放棄,不知道為什麼用這個單詞,難道是 此處函數就放棄了控制權?例子
#!/usr/bin/ruby# -*- coding: UTF-8 -*-def test puts "在 test 方法內" yield puts "你又回到了 test 方法內" yieldendtest {puts "你在塊內"}
運行了這段後的效果是
在 test 方法內你在塊內你又回到了 test 方法內你在塊內
在yield的部分運行了你調用時傳入的塊語句。
所以yield是不是看起來沒啥用?繼續往下看
yield可以帶參數您也可以傳遞帶有參數的 yield 語句。下面是一個執行個體:
#!/usr/bin/ruby# -*- coding: UTF-8 -*-def test yield 5 puts "在 test 方法內" yield 100endtest {|i| puts "你在塊 #{i} 內"}
塊和方法如果方法的最後一個參數前帶有 &,那麼您可以向該方法傳遞一個塊,且這個塊可被賦給最後一個參數。如果 * 和 & 同時出現在參數列表中,& 應放在後面。
#!/usr/bin/rubydef test(&block) block.callendtest { puts "Hello World!"}
是不是令你想起了javascript裡面的回呼函數?
結合上yield傳參,可以實現傳入一段回呼函數,並且該回呼函數中可以根據函數執行的過程中傳入的不同參數做出不同的行為。
總算感覺塊這個特性有點用了。。。
BEGIN 和 END 塊BEGIN和END塊就像java中的攔截器,一個是before攔截器,一個是after攔截器
#!/usr/bin/rubyBEGIN { # BEGIN 代碼塊 puts "BEGIN 代碼塊"} END { # END 代碼塊 puts "END 代碼塊"} # MAIN 代碼塊puts "MAIN 代碼塊"
一個程式可以包含多個 BEGIN 和 END 塊。BEGIN 塊按照它們出現的順序執行。END 塊按照它們出現的相反順序執行。當執行時,上面的程式產生產生以下結果:
BEGIN 代碼塊MAIN 代碼塊END 代碼塊
Ruby模組模組(Module)是一種把方法、類和常量組合在一起的方式。模組(Module)為您提供了兩大好處
- 模組提供了一個命名空間和避免名字衝突
- 模組實現了 mixin 裝置
模組(Module)定義了一個命名空間,相當於一個沙箱,在裡邊您的方法和常量不會與其他地方的方法常量衝突。
- 模組類似與類,但有一下不同模組不能執行個體化
- 模組沒有子類
- 模組只能被另一個模組定義
module Identifier statement1 statement2 ...........end
模組常量命名與類常量命名類似,以大寫字母開頭。方法定義看起來也相似:模組方法定義與類方法定義類似。
例子
#!/usr/bin/ruby# 定義在 trig.rb 檔案中的模組module Trig PI = 3.141592654 def Trig.sin(x) # .. end def Trig.cos(x) # .. endend
require 語句
終於看到require語句了!沒有require功能簡直是不能寫代碼啊,所以結合上require,module功能是我看到最重要的功能了執行個體
$LOAD_PATH << ‘.‘require ‘trig.rb‘y = Trig.sin(Trig::PI/4)
注意這句話 $LOAD_PATH << ‘.‘ 這句話是把require的路徑定到當前的檔案路徑,我剛開始require總是失敗就是因為沒有這句話如果不想用 $LOAD_PATH 還可以使用 require_relative 方法
require_relative ‘trig.rb‘y = Trig.sin(Trig::PI/4)
也可以!而且
我更喜歡 require_relative 因為更好記!
include 語句您可以在類中嵌入模組。你肯定跟我會有一樣的疑問:“可是,我都有require了為什麼還要include?!”
假設以下代碼寫在 support.rb 裡面
module Week FIRST_DAY = "Sunday" def Week.weeks_in_month puts "You have four weeks in a month" end def Week.weeks_in_year puts "You have 52 weeks in a year" endend
我們來嵌入一下
#!/usr/bin/ruby$LOAD_PATH << ‘.‘require "support"class Decadeinclude Week no_of_yrs=10 def no_of_months puts Week::FIRST_DAY number=10*12 puts number endendd1=Decade.newputs Week::FIRST_DAYWeek.weeks_in_monthWeek.weeks_in_yeard1.no_of_months
你會發現,
有沒有那行 include Week 代碼執行結果根本就沒有區別!那include有什麼卵用呢?!要解釋include究竟有什麼用,就要介紹一下 ruby 的 mixins 特性Ruby 中的 MixinsRuby中並沒有多重繼承,取而代之的是Mixin。當你將模組include到類定義中,模組中的方法就被mix到了類裡面執行個體代碼,看A, B 如何被mix到 Sample裡面
module A def a1 end def a2 endendmodule B def b1 end def b2 endendclass Sampleinclude Ainclude B def s1 endendsamp=Sample.newsamp.a1samp.a2samp.b1samp.b2samp.s1
include & require & load
原來include跟require有以下的區別(這邊還要提到load方法)
- require不需要跟上尾碼,會自動識別 xxx.rb
- require如果調用2次就會報錯,如果要調用多次就用load,但是用load得寫上檔案尾碼名
- require一般用於載入庫檔案,load一般使用者載入設定檔
- include 用於把一個檔案中的模組mix到類中
- include並不會把module的執行個體方法拷貝到類中,只是做了引用,包含module的不同類都指向了同一個對象。如果你改變了module的定義,即使你的程式還在運行,所有包含module的類都會改變行為
有趣的Ruby-學習筆記4