跳轉到內容

Ruby 程式設計/Ruby 基礎

來自華夏公益教科書

← 物件簡介 | 資料型別 →


與本教程的其餘部分一樣,我們假設您對程式語言概念(例如 if 語句、while 迴圈)有一定的瞭解,並且還對面向物件程式設計有一定的瞭解。

處理變數

[編輯 | 編輯原始碼]

當我們討論類和物件時,我們將更深入地處理變數。現在,讓我們簡單地說,您的基本區域性變數名稱應該以小寫字母或下劃線開頭,並且應該包含大寫或小寫字母、數字和下劃線字元。全域性變數以$.

程式流程

[編輯 | 編輯原始碼]

Ruby 包含一套非常標準的迴圈和分支結構if, whilecase

例如,這裡是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 中的語法,其中ifunless語句可以用作語句之後的條件修飾符。例如

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 是真正面向物件的

[編輯 | 編輯原始碼]

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 的。

華夏公益教科書