Ruby 程式設計/Ruby 基礎
與本教程的其餘部分一樣,我們假設您對程式語言概念(例如 if 語句、while 迴圈)有一定的瞭解,並且還對面向物件程式設計有一定的瞭解。
當我們討論類和物件時,我們將更深入地處理變數。現在,讓我們簡單地說,您的基本區域性變數名稱應該以小寫字母或下劃線開頭,並且應該包含大寫或小寫字母、數字和下劃線字元。全域性變數以$.
Ruby 包含一套非常標準的迴圈和分支結構if, while和case
例如,這裡是if在行動中
a = 10 * rand
if a < 5
puts "#{a} less than 5"
elsif a > 7
puts "#{a} greater than 7"
else
puts "Cheese sandwich!"
end
[與其他語言一樣,rand函式生成 0 到 1 之間的隨機數]
在後面的章節中,我們將有更多時間討論條件語句。上面的例子應該非常清楚。
Ruby 還包含if的否定形式,稱為unless它有點像
unless a > 5 puts "a is less than or equal to 5" else puts "a is greater than 5" end
一般來說,Ruby 會保持一個if語句直線,只要條件(if ...)和相關的程式碼塊在不同的行上。如果您必須將所有內容放在一行上,您需要在條件之後放置then關鍵字
if a < 5 then puts "#{a} less than 5" end
if a < 5 then puts "#{a} less than 5" else puts "#{a} greater than 5" end
請注意,if語句也是一個表示式;它的值是執行的塊的最後一行。因此,上面的行也可以寫成
puts(if a < 5 then "#{a} less than 5" else "#{a} greater than 5" end)
Ruby 還採用了 Perl 中的語法,其中if和unless語句可以用作語句之後的條件修飾符。例如
puts "#{a} less than 5" if a < 5
puts "Cheese sandwich" unless a == 4
while的行為與其他語言中的行為相同 - 只要條件為真,就會執行後面的程式碼塊,執行零次或多次
while a > 5 a = 10*rand end
與if一樣,也存在while的否定形式,稱為until的否定版本,它直到條件為真才執行程式碼塊。
最後是case語句,我們將在這裡簡單舉例說明。case實際上是if ... elsif...系統
a = rand(11) # Outputs a random integer between 0 and 10
case a
when 0..5
puts "#{a}: Low"
when 6
puts "#{a}: Six"
else
puts "#{a}: Cheese toast!"
end
的非常強大的超級版本。在這個例子中,有一些其他有趣的事情,但是case語句是關注的中心。
為了保持 Ruby 的始終面向物件的設計,函式通常被稱為方法。沒有區別。當我們進入物件和類時,我們將更詳細地介紹方法。現在,基本的函式編寫如下所示(將以下程式碼儲存在名為 func1.rb 的檔案中)
# Demonstrate a method with func1.rb
def my_function( a )
puts "Hello, #{a}"
return a.length
end
len = my_function( "Giraffe" )
puts "My secret word is #{len} characters long"
現在執行指令碼
$ func1.rb Hello, Giraffe My secret word is 7 characters long
方法是用def關鍵字定義的,後面是函式名稱。與變數一樣,區域性方法和類方法應該以小寫字母開頭。
在這個例子中,函式接受一個引數(a)並返回一個值。請注意,輸入引數沒有型別(即a不需要是字串)... 這允許很大的靈活性,但也可能導致很多麻煩。該函式還使用return關鍵字返回單個值。從技術上講,這不是必需的 - 函式中執行的最後一行程式碼的值用作返回值 - 但大多數情況下,使用return明確地使事情更加清晰。
與其他語言一樣,Ruby支援引數的預設值和可變長度引數列表,我們將在適當的時候介紹這兩者。還支援程式碼塊,如下所述。
Ruby 中一個非常重要的概念是程式碼塊。這實際上並不是一個特別革命性的概念 - 每當你編寫過if ... { ... }在 C 或 Perl 中,你已經定義了一個程式碼塊,但在 Ruby 中,程式碼塊有一些隱藏的秘密力量...
Ruby 中的程式碼塊是用關鍵字do..end或花括號{..}
do
print "I like "
print "code blocks!"
end
{
print "Me too!"
}
程式碼塊的一個非常強大的用法是,方法可以將程式碼塊作為一個引數並執行它。
[編者注:The Pragmatic Programmers 實際上想要指出,這樣描述它沒有太大用處。相反,程式碼塊的行為就像一個“夥伴”,函式偶爾會將控制權交給它]
這個概念第一次解釋時可能很難理解。這裡有一個例子
$ irb --simple-prompt
>> 3.times { puts "Hi!" }
Hi!
Hi!
Hi!
=> 3
驚喜!你一直認為 3 只是一個數字,但它實際上是一個物件(型別為Fixnum)。因為它是一個物件,它有一個成員函式times,它將一個程式碼塊作為引數。該函式執行程式碼塊 3 次。
程式碼塊實際上可以接收引數,使用特殊符號|..|。在這種情況下,快速檢查times的文件表明它將把一個引數傳遞給程式碼塊,指示它是哪個迴圈
$ irb --simple-prompt
>> 4.times { |x| puts "Loop number #{x}" }
Loop number 0
Loop number 1
Loop number 2
Loop number 3
=> 4
該times函式將一個數字傳遞給程式碼塊。程式碼塊在變數x中獲得該數字(由|x|設定),然後打印出結果。
函式透過yield與程式碼塊互動。每次函式呼叫yield時,控制權就會傳遞給程式碼塊。只有當代碼塊完成時,它才會返回到函式。這裡有一個簡單的例子
# Script block2.rb
def simpleFunction
yield
yield
end
simpleFunction { puts "Hello!" }
$ block2.rb Hello! Hello!
該simpleFunction只是簡單地將控制權讓給程式碼塊兩次 - 所以程式碼塊執行兩次,我們得到兩倍的輸出。這裡有一個函式將引數傳遞給程式碼塊的例子
# Script block1.rb
def animals
yield "Tiger"
yield "Giraffe"
end
animals { |x| puts "Hello, #{x}" }
$ block1.rb Hello, Tiger Hello, Giraffe
可能需要閱讀幾遍才能弄清楚這裡發生了什麼。我們定義了函式“animals” - 它期望一個程式碼塊。當執行時,該函式呼叫程式碼塊兩次,第一次使用引數“Tiger”,然後再次使用引數“Giraffe”。在這個例子中,我們編寫了一個簡單的程式碼塊,它只是打印出對動物的問候。我們可以編寫一個不同的程式碼塊,例如
animals { |x| puts "It's #{x.length} characters long!" }
這將給出
It's 5 characters long! It's 7 characters long!
使用相同的函式執行兩個不同的程式碼塊會得到完全不同的結果。
程式碼塊有很多強大的用途。您遇到的第一個用途之一是each函式用於陣列 - 它為陣列中的每個元素執行一個程式碼塊 - 非常適合迭代列表。
Ruby 是非常面向物件的。一切都是物件 - 即使是您可能認為是常量的東西。這也意味著,您可能認為的“標準函式”絕大多數並不存在於某個庫中的某個地方,而是給定變數的方法。
這裡有一個我們已經看到的例子
3.times { puts "Hi!" }
即使 3 看起來只是一個常數,但它實際上是類Fixnum(它繼承自類Numeric,它又繼承自類Object)的例項。方法times來自Fixnum,並且它只是做它聲稱做的事情。
這裡有一些其他例子
$ irb --simple-prompt >> 3.abs => 3 >> -3.abs => 3 >> "giraffe".length => 7 >> a = "giraffe" => "giraffe" >> a.reverse => "effarig"
在接下來的章節中,我們將有充足的時間來考慮面向物件設計是如何貫穿 Ruby 的。