Ruby快速入門(30分鐘)

在本教程中,將探討使用Ruby開始編程所需的基本語法,以及如何在30分鐘內學習並使用Ruby編程語言。

注:如果您還尚未安裝Ruby開發環境,請訪問環境設置頁面並按照說明安裝: http://www.yiibai.com/ruby/ruby-installation.html

Ruby歷史

Ruby被許多人認爲是一種「新」編程語言,但實際上是由一個叫作Matz的開發人員於1994年發佈的。 Matz自我描述是一個「語言極客」,也是Perl大粉絲。 他對Ruby的想法是創建一種像Perl這樣靈活而強大的語言,但在其語法上更具表現力 - 甚至可以具有類似於英語那樣的可讀性。

Ruby在日本迅速成長,直到2000年,真的沒有關於除了日本語言以外的任何文檔。所以如果想要學習Ruby,那得必須先學習日語。 敏捷編程的先驅Dave Thomas被Ruby迷住,並決定創建Ruby的其它語言文檔。

自Ruby有了英文開始,Ruby就開始在英語世界中增長,儘管緩慢。 系統管理員變得流行,編寫維護和「粘貼」腳本 - 類似Perl的用法。從2000年到2005年美國的Ruby社區已達數百個。

在2004-2005年,一家名爲37Signals的芝加哥公司聘請了一名年輕的開發人員來構建一個Web應用程序。 公司給了他幾乎完全的執行自由; 他們只關心客戶端的設計和功能。 當時主要的Web技術是Perl CGI,PHP,Java的JSP和Microsoft的ASP。 但是他們都是有點痛苦,但DHH的**大衛(DHH)**選擇了自己的方向。他在Ruby中寫了這個應用程序。 他依靠核心庫和少數庫的幫助下,同時自己創建了整個堆棧(或多或少)。37Signals在Web應用程序使用Ruby來編寫,這個項目今天被稱爲Basecamp

當建立了Basecamp,DHH就會從中提取出Web框架。 這是一個非常不同的方法,從Java/Sun.NET/Microsoft,Web框架都是從高處往下傳播。 相反,Rails從現實世界中抽出來。 它側重於常規配置,使常見問題更容易解決。

這種方法是一個很大的打擊,Rails自從以來一直推動了Ruby/Rails社區的發展。 現在,在亞馬遜上有數十本書,全球近一百個會議,有成千上萬的人是Ruby/Rails開發人員。

如果你想學習Rails,需要先學習Ruby! 現在就開始咯 …..

1. Ruby解釋器

Ruby是一種「解釋」的編程語言,它不能直接在處理器上運行,它的代碼必須饋送到稱爲「虛擬機」或虛擬機的中間件。 虛擬機的一方面是Ruby代碼,另一方面則是操作系統和處理器。 這種方法的好處是您可以編寫一次Ruby代碼,就可以在許多不同的操作系統和硬件平臺上執行了。

Ruby程序無法運行自己的程序,它需要加載虛擬機。 使用VM執行Ruby的方式有兩種:通過IRB和命令行。

從命令行運行Ruby代碼

這是編寫Ruby代碼的耐用方法,因爲要將指令保存到文件中。 該文件可以備份,傳輸,添加到源代碼管理等。

一個Ruby代碼文件示例

這裏創建一個名稱爲:first-ruby.rb的文件,如下所示:

#!/usr/bin/ruby   
# filename : first-ruby.rb

class Sample
  def hello
    puts "Hello, World!"
  end
end

s = Sample.new
s.hello

那麼可以這樣運行程序:

Ruby快速入門(30分鐘)

當您運行ruby first-ruby.rb時,實際上正在加載ruby虛擬機,然後再加載first-ruby.rb文件中的代碼。

從IRB運行Ruby代碼

Ruby是第一批語言推廣所謂「REPL」:閱讀,評估,打印,循環的編程語言。想像它就像一個計算器 - 就像在每個完整的指令中,IRB執行這些指令並顯示結果。

IRB最好用作實驗的便箋簿。 許多開發人員在編寫他們的「真實」程序時,一般都保持IRB窗口打開,使用它來記住某個方法如何工作或用於調試某個代碼塊。

要打開IRB進行實驗,可通過打開終端(Mac)或命令提示符(Win)並打開或輸入irb來啓動IRB。以Windows系統爲例,如下所示 -

Ruby快速入門(30分鐘)

注: 按 Ctrl + D 可退出 irb 模式。

2. Ruby變量

編程都是要創建抽象的代碼來描述和處理數據,要創建抽象,必須要爲在代碼中分配名稱來表示事物。 變量只不過是爲數據創建一個名稱的一種方式。

創建和分配變量

在某些語言中,需要在爲一個變量分配值之前聲明這個變量。 當爲變量分配值時,會自動創建Ruby變量。下面來試試一個例子:

Ruby快速入門(30分鐘)

a = 250表示創建一個名稱爲a的變量,並將值250存儲到其中。

右邊優先

在英文表達式中,是從左到右閱讀,所以從左到右讀取代碼是很自然的。 但是當使用單個等於號(=)評估求值一個賦值時,Ruby實際上首先評估求值右側。 舉個例子:

irb(main):010:0> b = 10 + 20
=> 30
irb(main):011:0> b
=> 30
irb(main):012:0>

上面示例中,首先對10 + 20進行評估求值,再將求值結果存儲到b變量中。

靈活輸入

Ruby的變量可以容納任何類型的數據,甚至可以更改其持有的數據類型。 例如:

irb(main):012:0> c = 200
=> 200
irb(main):013:0> c = "Flexible Typing"
=> "Flexible Typing"
irb(main):014:0> c
=> "Flexible Typing"
irb(main):015:0> c = 0.0001
=> 0.0001
irb(main):016:0> c
=> 0.0001
irb(main):017:0>

第一次賦予c變量爲一個200的整數值。第二次賦值是將c變量的值更改其爲「Flexible Typing」。

命名變量

大多數Ruby變量(局部變量)的命名都有一些由VM強制的要求。這些要求約定如下 -

  • 始終以小寫字母開頭(允許下劃線,雖然不常見)
  • 不能使用空格
  • 不要包含特殊字符,如$@

除了那些虛擬機的要求,Ruby開發者對變量名稱有幾個常見風格偏好:

  • 使用蛇形大小寫,即:名稱中的每個字都是小寫字母,並用下劃線(_)連接
  • 以其內容的含義命名,而不是其內容的類型
  • 不使用縮寫

好的變量名的示例如下:counttotal_productsstudents_in_classfirst_lesson

一些不好的Ruby變量名稱的幾個例子,如下所示:

  • studentsInClass – 使用駱駝案而不是蛇形大小寫,應該命名爲:students_in_class
  • 1st_lesson – 變量不能以數字開頭,應該命名爲:first_lesson
  • students_array – 包括名稱的數據類型,應該命名爲:students
  • sts – 不使用縮寫,應該命名爲:students

練習

使用IRB存儲每個以下變量名稱的值。 哪些名字是好的,哪些是是無效的Ruby變量名稱,哪些是有效的,哪些是Ruby不建議使用的風格?

  • time_machine
  • student_count_integer
  • homeworkAssignment
  • 3_sections
  • top_ppl

3. 字符串

在現實世界中,字符串是將一個個字符串聯起來的。 編程中的字符串與真實字符串無關。

編程中的字符串用於存儲字母和數字的集合。它可以是一個單一的字母,如「a」,或者像「hi」這樣一個單詞,或者「Hello my friends.」這樣的一段話。

編寫一個字符串

Ruby字符串被定義爲一個引號("),後跟零個或多個字母,數字或符號,後跟一個閉包引號(")。 最短的字符串稱爲空字符串:""。 單個字符串包含文本的段落甚至頁面也很常見。

子字符串

通常使用字符串,可從整個長字符串提取出來的一部分 - 這提取出來的部分稱爲子字符串。在 irb 嘗試這些例子:

irb(main):017:0> string = "Ruby in 30 Minutes at yiibai.com"
=> "Ruby in 30 Minutes at yiibai.com"
irb(main):018:0> string[0..8]
=> "Ruby in 3"
irb(main):019:0> string[8..16]
=> "30 Minute"
irb(main):020:0> string[8..-1]
=> "30 Minutes at yiibai.com"
irb(main):021:0> string[8..-2]
=> "30 Minutes at yiibai.co"
irb(main):022:0>

正號和負號的位置

字符串中的字符每個都有一個位置編號,它們從零開始。 所以對於字符串中的開頭「Ru」,「R」位置編號爲0,「u」所在的位置編號爲1

要在主字符串中提取出一個子串,可指定提取的起始位置和結束位置。 因此,上面的string[0..8]提取出位置從08的字母,也就是:「Ruby in 3」。

Ruby解釋負的位置從字符串的末尾返回。所以在上面示例中,結尾的字符串「com」的字母分別對應爲「m」位於-1,「o」位於-2 和 「c」位於-3

所以如果一個字母同時有正數和負數的位置,那麼應該使用哪個? 建議使用正數,因爲這樣它們更容易理解。 但是,如果要基於字符串末尾查找東西(例如「該字符串的最後一個字符是什麼?」),則使用負數指定位置。

常用的字符串方法

在IRB中使用字符串(對象)中一些常用的方法。

.length

length方法用於求出字符串中有多少個字符(包括空格):

irb(main):022:0> string = "0123456789"
=> "0123456789"
irb(main):023:0> string.length
=> 10
irb(main):024:0> string = "maxsu"
=> "maxsu"
irb(main):025:0> string.length
=> 5
irb(main):026:0>

嘗試:計算你的名字的總長度

.split

有時想要將一個字符串分成幾部分。 例如,假設有一個存儲爲字符串的句子,並將其分解成單詞:

C:\Users\Administrator>irb
irb(main):001:0> string = "This is my sample sentence."
=> "This is my sample sentence."
irb(main):002:0> string.split
=> ["This", "is", "my", "sample", "sentence."]
irb(main):003:0>

.split方法返回一個數組,這將在後面的部分講解中瞭解到。 它默認使用空格(「 」)字符將字符串分割成多個部分。

.split使用參數

但有時要分割的不是一個帶有空格的字符。 .split方法接受一個參數來指定分隔符,看看下面示例就明白了。

irb(main):003:0> numbers = "1,2,3,4,5,6,7,8"
=> "1,2,3,4,5,6,7,8"
irb(main):004:0> numbers.split
=> ["1,2,3,4,5,6,7,8"]
irb(main):005:0> numbers.split(",")
=> ["1", "2", "3", "4", "5", "6", "7", "8"]
irb(main):006:0>

在第一次分割的調用中,它嘗試使用空格作爲分隔符,但字符串中沒有分隔符,所以得到一個整個字符串的數組。 在第二次嘗試中,指定使用逗號(「,「)作爲分隔符,所以得到一個8個數字值的數組。

.sub 和 .gsub

這兩種方法可以用來替換字符串的部分。它們就像在文字處理器中使用「查找和替換」。 .sub替換隻發生一次。 而.gsub全局替換的縮寫,替換所有的發生(如「全部替換」)。

對於.sub.gsub,需要指定兩個參數:首先是要替換的子字符串,然後再替換要替換的字符串。

irb(main):013:0> greeting = "Hello, Hello Everyone!"
=> "Hello, Hello Everyone!"
irb(main):014:0> greeting.sub("Hello","Hi")
=> "Hi, Hello Everyone!"
irb(main):015:0> greeting.gsub("Hello","Hi")
=> "Hi, Hi Everyone!"
irb(main):016:0>

組合字符串和變量

將變量的值與字符串相結合這是在開發應用程序中最經常使用的。 例如,現在從下面這個例子開始:

"Good morning, ?? !"

當把上面語句放入IRB時,它只是打印輸出同一個字符串。 如果編寫一個應用程序,希望它以用戶名而不是「??」來跟用戶打招呼,那麼需要怎麼做?

需要做的就是將變量與字符串組合。有兩種方法可以做到這一點。

方法-1. 字符串連接

第一種方法,可使用字符串連接,它將字符串與加號連接:

irb(main):021:0> name = "Maxsu"
=> "Maxsu"
irb(main):022:0> puts "Good morning, " + name + " ! "
Good morning, Maxsu !
=> nil
irb(main):023:0>

在第一行中,設置了一個name變量來保存名稱。 在第二行,打印字符串「Good morning「 並結合」name「變量和字符串」!「的值。

方法-2. 字符串插值

第二種方法是使用字符串插值,將數據粘貼到字符串的中間。

字符串插值僅適用於雙引號字符串。在字符串內使用插值標記#{}。 在這些括號中可以把任何變量或Ruby代碼放入其中,這些變量或Ruby代碼將被評估求值,其結果轉換爲一個字符串,並輸出到外部字符串的那個位置。 上面的例子可以這樣重寫:

irb(main):023:0> name = "Maxsu"
=> "Maxsu"
irb(main):024:0> puts "Good morning, #{name}!"
Good morning, Maxsu!
=> nil
irb(main):025:0>

如果比較輸出結果,就會看到它們輸出的是完全相同的結果。 內插樣式往往是輸入較少的字符類型,較少的雙引號打開/關閉,所以可避免加雙引號時忘記書寫對稱(往往有輸入多一個,少一個的問題)。

內插插入代碼

還可以將任何Ruby代碼或計算表達式內置在括號內,如下所示:

irb(main):025:0> modifier = "very "
=> "very "
irb(main):026:0> mood = "excited"
=> "excited"
irb(main):028:0> puts "I am #{modifier * 3 + mood} for today's play!"
I am very very very excited for today's play!
=> nil
irb(main):029:0>

首先對#{modifier * 3 + mood}代碼塊進行評估求值,然後將結果注入外部字符串中。

4. 符號

符號有點難以解釋,它們是字符串和數字的一半。但是可以很容易識別一個符號,因爲它是以冒號開始一個或多個字母,如:flag:best_friend

新程序員的符號

如果你是編程的新手,可將一個符號看作是一個幾乎沒有任何方法和沒有字符串插值的被剝離下來的字符串。 將正確的字符串與類似符號的方法列表進行比較,如下所示:

2.1.1 :001> "hello".methods
2.1.1 :002> "hello".methods.count
2.1.1 :003> :hello.methods
2.1.1 :004> :hello.methods.count

有經驗的程序員的符號

如果你是一個有經驗的程序員,想象一個符號是一個「命名整數」。 符號引用的實際值無關緊要。 我們所關心的是,虛擬機內對該值的任何引用將返回相同的值。 因此,符號在全局符號表中定義,它們的值不能改變。

5. 數字值

數字有兩種基本類型:整數(整數)和浮點數(有小數點)。
整數對於您和計算機來說都要容易一些。 您可以使用包括+-/*在內的整數的正常數學運算。 整數有一些方法可以用來做數學相關的事情,過調用5.methods方法就可看到一些常用的方法。

重複指令

重複執行指令在其他語言中的常見模式是for循環,用於重複執行某些指令一定次數。 例如,在JavaScript中可以寫:

for(var i = 0; i < 5; i++){
  console.log("Hello, World");
}

對於循環是很常見的,但它們的代碼不是很容易閱讀。 因爲Ruby的整數是它們擁有方法的對象。 其中的一個方法:times是重複執行指令的方法。

以Ruby樣式重寫上述循環:

5.times do
  puts "Hello, World!"
end

在這個例子中,使用times方法和具體的執行代碼塊。 在下一節中將討論塊。 但是請先在IRB中運行這個例子,看看結果會是什麼。

6. 塊

塊是Ruby中經常使用的強大概念。 可將塊視爲一組捆綁在其他地方使用的指令的方式。

塊的開始和結束

在上一節中有一個使用.times方法的塊用整數表示:

5.times do
  puts "Hello, World!"
end

該塊以關鍵字do開始,以關鍵字end結束。 do/end風格總是可以被Ruby解釋器所接受的。

支架塊

當塊僅包含單個指令時,經常使用備用標記{}來標識塊的開始和結束:

5.times{ puts "Hello, World!" }

塊被傳遞給方法

那麼使用塊來做什麼? 塊可以用來作爲傳遞給方法調用的參數。

例如,如果調用了5.times,Ruby就不會知道要執行五次了。當通過塊時,就會說「這裏是希望每次運行的說明」。

塊中有很多的方法。 就像前面看到的.gsub方法一樣,字符串早就爲每個匹配運行一個塊:

irb(main):038:0> "this is a sentence".gsub("e"){ puts "Found an E!"}
Found an E!
Found an E!
Found an E!
=> "this is a sntnc"
irb(main):039:0>

請注意,」Found an E!「顯示了三次,因爲字符串中有三個E字母。

塊參數

通常,在塊內指示需要引用正在使用的值。 當在編寫塊代碼時,可以在管道字符中指定一個塊參數:

5.times do |i|
  puts "Hello, World! "
end

什麼值應該放入該塊參數,這取決於要調用的方法。 在本示例中,times方法放入當前運行的數值。嘗試上面的塊,觀察輸出,然後嘗試這樣修改:

5.times do |i|
  puts "#{i}: Hello, World!"
end

上面代碼輸出結果如下 -

irb(main):045:0> 5.times do |i|
irb(main):046:1*   puts "#{i}: Hello, World!"
irb(main):047:1> end
0: Hello, World!
1: Hello, World!
2: Hello, World!
3: Hello, World!
4: Hello, World!
=> 5
irb(main):048:0>

.gsub在找到的字符串中傳遞。 嘗試這個(用括號表示法):

irb(main):048:0> "this is a sentence".gsub("e"){|letter| letter.upcase}
=> "this is a sEntEncE"
irb(main):049:0>

在上面結果中看到gsub正在使用塊的結果作爲原始匹配的替換。

7.數組

通常當編寫程序時,我們需要處理數據的集合。先來看看最常見的數據集合 - 數組。

可視化模型

數組是數字索引列表。 想象一下,有一張空白的紙,畫了三個小盒子:

 ---  ---  ---
|   ||   ||   |
 ---  ---  ---

可以按照從左到右對每一個位置進行編號:

 ---  ---  ---
|   ||   ||   |
 ---  ---  ---
  0    1    2

然後在每個框中放入字符串(或其它值):

 -------------  ---------  ----------
| "Breakfast" || "Lunch" || "Dinner" |
 -------------  ---------  ----------
       0            1           2

現在變成一個有三元素的數組。 Ruby數組的大小可以增長和縮小,所以如果添加一個元素,它通常會在結束位置添加,索引值也會變遞增1

 -------------  ---------  ----------  -----------
| "Breakfast" || "Lunch" || "Dinner" || "Dessert" |
 -------------  ---------  ----------  -----------
       0            1           2           3

請注意,最後一個元素的位置總是比元素的數量小1

數組中在索引爲2位置對應的數據值爲「Dinner」。最後一個元素對應的數據值爲「Dessert」。

代碼中的數組

以下是Ruby代碼中相同建模的方法:

irb(main):049:0> meals = ["Breakfast", "Lunch", "Dinner"]
=> ["Breakfast", "Lunch", "Dinner"]
irb(main):050:0> meals << "Dessert"
=> ["Breakfast", "Lunch", "Dinner", "Dessert"]
irb(main):051:0> meals[2]
=> "Dinner"
irb(main):052:0> meals.last
=> "Dessert"
irb(main):053:0>

在上面代碼運行結果中,觀察到…

  • 該數組是通過將數據片段放在方括號([])之間並用逗號分隔來創建的。

  • 通過使用「鏟子運算符」(<<)添加一個元素到數組的末尾

  • 通過使用方括號([])在指定索引位置來獲取元素

  • 數組中一些方便的方法,如.last

常用數組方法

數組有很多很酷的東西。 以下是幾個例子:

.sort方法

sort方法將返回一個新的數組,其中元素是已經被排序過了。 如果元素是字符串,它們將以字母順序返回。 如果它們是數字,它們將按升值順序回來。嘗試下面示例:

irb(main):056:0> array1 = ["this", "is", "an", "array"]
=> ["this", "is", "an", "array"]
irb(main):057:0> array1.sort
=> ["an", "array", "is", "this"]
irb(main):058:0> array1
=> ["this", "is", "an", "array"]
irb(main):059:0>

可以使用sort方法重新排列元素的順序。使用each方法遍歷每個元素。使用join方法將它們一起混合成一個字符串。使用index方法找到特定元素的地址。可以使用include?方法詢問數組是否包含指定的元素。

使用數組只要需要一個列表,其中元素是以特定的順序排序的。

其他的嘗試

在數組上嘗試下面這些常見的方法:

  • each
  • collect
  • firstlast
  • shuffle

可以參考這個文檔瞭解更多詳細信息:http://www.ruby-doc.org/core-2.1.2/Array.html

8.哈希

哈希是數據的集合,哈希中的數據的每個元素是按名稱來尋址。作爲一個比喻,想一下冰箱。 如果要跟蹤放在冰箱內的東西,我們並不關心它的放在哪裏 - 順序並不重要。 相反只是按名稱去組織這些東西。如名稱「apples」可能具有值3,則名稱「oranges」可能具有值1,並且「carrots」值爲12。 在本示例中,就可使用哈希。

鍵/值對

哈希是無序的集合,其中數據被組織成「鍵/值對」。 哈希的語法更復雜,需要一些習慣:

irb(main):001:0> produce = {"apples" => 3, "oranges" => 1, "carrots" => 12}
=> {"apples"=>3, "oranges"=>1, "carrots"=>12}
<e are #{produce['oranges']} oranges in the fridge."
There are 1 oranges in the fridge.
=> nil
irb(main):003:0>

鍵用作爲地址,值是該地址的數據。 在produce哈希中有包括「apples」和「oranges」的鍵,其值分別爲123。當創建哈希時,鍵和值使用=>符號鏈接。 所以哈希從一個大括號{開始,(由一個鍵,一個=>標識符和一個由逗號分隔的值組成的零個或多個條目,然後以一個關閉的大括號}結束。

再嘗試一些代碼:

irb(main):006:0> produce["grapes"] = 219
=> 219
irb(main):007:0> produce
=> {"grapes"=>219}
irb(main):008:0> produce["oranges"] = 66
=> 66
irb(main):009:0> produce
=> {"grapes"=>219, "oranges"=>66}
irb(main):010:0> produce.keys
=> ["grapes", "oranges"]
irb(main):011:0> produce.values
=> [219, 66]
irb(main):012:0>

在這些說明的第一行中,向哈希添加了一個新值。 由於「grapes」鍵不在原始哈希中,所以它的值爲221。 哈希中的鍵必須是唯一的,所以當對product [「oranges」]使用相同的語法時,它會看到鍵「oranges」已經在列表中,並且用6替換值。keysvalues方法會列出所有鍵和值。

簡化哈希語法

通常會使用符號作爲哈希的鍵。 當所有的鍵都是符號時,可以使用一個速記語法:

irb(main):012:0> produce = {apples: 3, oranges: 1, carrots: 12}
=> {:apples=>3, :oranges=>1, :carrots=>12}
irb(main):013:0> puts "There are #{produce[:oranges]} oranges in the fridge."
There are 1 oranges in the fridge.
=> nil
irb(main):014:0>

請注意,鍵以冒號結尾,而不是以冒號開始,即使這些是符號。 這個簡化的語法能在Ruby 1.9及更高版本配合使用。要了解正在使用的是哪個版本的Ruby,可在控制檯中輸入「ruby -v」。

9. 條件

條件語句評估求值結果爲truefalse。 最常見的條件運算符是==(相等),>(大於),>=(大於或等於),<(小於)和<=(小於或等於)。

一些對象也有返回truefalse的方法,因此它們在條件語句中使用。 例如,每個對象都有方法.nil? 只有當對象爲nil時才返回:true。 數組有一個名稱爲.include的方法 如果數組包含指定的元素,則返回true。 Ruby中的約定方法名稱以結尾返回truefalse

條件分支/指令

爲什麼要有條件語句? 最常見的是控制條件指令,特別是:if/elsif/else結構。在IRB中添加一個這樣的方法來寫一個例子:

def water_status(minutes)
  if minutes < 7
    puts "The water is not boiling yet."
  elsif minutes == 7
    puts "It's just barely boiling"
  elsif minutes == 8
    puts "It's boiling!"
  else
    puts "Hot! Hot! Hot!"
  end
end

# run method with difference parameter
water_status(5)
water_status(7)
water_status(8)
water_status(9)

嘗試使用:water_status(5)water_status(7)water_status(8)water_status(9)運行該方法。

理解執行流程

minutes值爲5時,執行結果是什麼?因爲minutes = 5小於7,所以打印出來的結果爲:「The water is not boiling yet.

minutes值爲7時,執行結果是什麼?因爲minutes值等於7,所以打印出來的結果爲:「It's just barely boiling

minutes值爲8時,執行結果是什麼?因爲minutes值等於8,所以打印出來的結果爲:「It's boiling!

minutes值爲9時,執行結果是什麼?因爲minutes = 9,它比較了前面的幾個值:578,但是都沒有匹配項,所以最後執行到else語句塊中,打印出來的結果爲:「Hot! Hot! Hot!

if語句可能的結構

if語句有以下可能的結構:

  • if語句的指令只有在語句爲真時執行。
  • if語句後面可有零或多個elsif語句,其指令僅在語句爲真時執行
  • if語句後面零或一個else語句,如果沒有一個ifelsif語句爲真,則執行else語句中的指令。

if/else if/else結構中只能在一個部分可以運行它的指令。例如,如果if是真的,Ruby將永遠不會執行elseifelse,也就是說永遠只執行其中一塊。

相等與分配值

編寫條件語句時遇到常見錯誤是書寫===,以及它們的區別。

  • =符號表示賦值。表示「拿右邊的東西,把它粘在左邊的任何東西」
  • ==表示爲這是一個問題。表示「右邊的東西是等於左邊的東西嗎?」

還可以使用邏輯運算符組合條件語句。 最常見的是「邏輯與」和「邏輯或」。 在Ruby中,您可以使用這樣的雙符號(&&)來書寫表示一個「邏輯和」。可以用這樣的雙管道(||)書寫表示一個「邏輯或」。

10. Nil和虛無

什麼是虛無? 當我們表達一個東西,沒有確定它是什麼東西的暫時可以叫它爲:虛無,不是沒有什麼東西嗎? 好的,這太多哲學了,這有確實點難解釋了。

nil是Ruby中用於表達「虛無」的方式。

如果有三個雞蛋,您吃三個雞蛋,那麼可能認爲現在您「沒有什麼」蛋了,但是在雞蛋方面有「0」個。0是什麼?它是一個數字,它並不是「虛無」。

如果使用一個單詞,如「hello」這樣的字符串,那麼刪除「h」,「e」,「l」和「o」,你可能會認爲沒有什麼,但是現在真的有「」,它是一個空字符串,並不是「虛無」。

nil是Ruby的虛無的想法的表示。 當要求不存在的東西時,通常會遇到這種情況。 例如,當查看數組時,創建了一個包含五個元素的列表,然後要獲取列表中添加第六個元素。但是沒有第六個元素,所以Ruby給了nil。 在第六個元素的地方它並不是空白(「」),也不是數字0,它是空/nil

編寫Ruby代碼時遇到的大部分錯誤是涉及nil值的。以爲某個位置有數據值,試圖使用使用這個數據值去做一些事情,但沒有這樣的數據值,不能做任何事情,所以Ruby引發了一個錯誤。

11. 對象,屬性和方法

Ruby是面向對象的編程語言

Ruby是一種面向對象的編程語言,在與VM內部交互的所有東西都是對象。 每條數據都是一個對象。 對象保存的信息稱爲屬性,可以執行對象的方法。

作爲一個對象的例子,想像你是一個人。 你有像高度,重量和眼睛顏色的屬性。 你有「走路」,「跑步」,「洗碗」和「白日夢」的方法。不同類型的對象具有不同的屬性和方法。 在接下來的章節中,將介紹一些Ruby中常見的特定類型的對象。

類和實例

在面向對象編程中,我們定義了類,它們是類別或類型的東西的抽象描述。 它定義了該類型的所有對象的屬性和方法。

定義一個類

例如,考慮對一個學校信息建模。要創建一個名爲「Student」的類,表示學生的抽象。 Student類將定義如:first_namelast_nameprimary_phone_number的屬性。 它可以定義一個用於學生自我介紹的方法:introduction

嘗試在IRB編寫上面代碼:

class Student
  attr_accessor :first_name, :last_name, :primary_phone_number

  def introduction
    puts "Hi, I'm #{first_name}!"
  end
end

attr_accessor方法是用於定義類的實例的屬性。

創建類的實例

Student類本身不代表學生,這是學生信息表示模型。 要表示一個實際的學生,需要創建一個Student類的實例。

想像你就是一個學生,不是一個抽象的概念,因爲你是一個實際的人。這個實際的人是Student類的一個實例 - 它是一個抽象思想的實現。一個實際的人具有屬性:first_namelast_nameprimary_phone_number 的實際數據(比如:你的first_name是「愛華」,last_name是「」等等)。

另一方面,Student類有幾個抽象的屬性: first_namelast_nameprimary_phone_number,我們不能提前確定它們。

從文件運行Ruby

一般情況下,很少在IRB中定義類。這是因爲IRB只是一個便籤本(不能很好的保存代碼),記得嗎? 下面來看看如何從文件中運行Ruby。

  • 退出IRB會話(輸入:exitCtrl + D)
  • 注意終端當前在哪個文件夾,進入你的「工作目錄」(本教程中,代碼都是寫在:F:\worksp\ruby)
  • 使用純文本編輯器創建一個名爲student.rb的文件。
  • 將文件保存在student.rb文件中。
  • 從終端運行文件:
ruby student.rb

由於這個文件是空的,所以不應該得到任何輸出。

創建Student

在文本編輯器中,開始編寫類的結構:

class Student

end

在類的內部,通常使用def關鍵字定義一個或多個方法,如下:

class Student
  def introduction
    puts "Hi, I'm #{first_name}!"
  end
end

請注意,puts行正在計算求值一個名爲first_name的方法,該方法返回學生的名字。下面可以進一步添加之前使用的三個屬性:

class Student
  attr_accessor :first_name, :last_name, :primary_phone_number

  def introduction
    puts "Hi, I'm #{first_name}!"
  end
end

運行文件

回到終端,嘗試用ruby student.rb運行文件。應該不會看到有結果輸出。

這是爲什麼呢? 上面步驟中已經定義了一個Student類,並表示一個學生有一個名爲introduction的方法以及一些屬性 - 但是實際上並沒有創建Student類的實例或調用任何方法。

創建實例

當定義一個類後,還要創建類的一個實例,如下所示:

frank = Student.new

Student類上調用new方法並將其存儲到變量frank中。當有了這個類的實例以後,就可以調用實例的方法來設置或獲取其屬性。

使用以下語法調用方法:object.method_name。在上面示例中,創建一個實例變量:frank,現在可以通過調用 frank.introduction 來獲取學生的介紹信息了。

在文件中創建一個實例

student.rb文件的底部,在Student類的end關鍵字之後,添加以下內容:

frank = Student.new
frank.first_name = "Frank"
frank.introduction

最終完整的代碼如下所示 -

class Student
  attr_accessor :first_name, :last_name, :primary_phone_number

  def introduction
    puts "Hi, I'm #{first_name}!"
  end
end

frank = Student.new
frank.first_name = "Max"
frank.introduction

保存代碼並返回到終端,再次執行ruby student.rb。 現在應該輸出:「Hi, I'm Max!

方法參數

有時,方法使用一個或多個參數來完成一些事情。 例如,可以調用 frank.introduction('Minlee'),讓它向Minlee介紹自己。參數可以是數字,字符串或任何種類的對象,下面修改introduction方法,以使用一個參數:

class Student
  attr_accessor :first_name, :last_name, :primary_phone_number

  def introduction(target)
    puts "Hi #{target}, I'm #{first_name}!"
  end
end

frank = Student.new
frank.first_name = "Maxsu"
frank.introduction('Minlee')

保存代碼並返回到終端,再次執行ruby student.rb。 現在應該輸出:「Hi Minlee, I'm Maxsu!

返回值

在Ruby中,每次調用方法時都會得到一個值。 默認情況下,Ruby方法返回其評估求值的最後一個表達式的值。

現在向Stuent類中添加一個方法:favorite_number,如下所示 -

class Student
  attr_accessor :first_name, :last_name, :primary_phone_number

  def introduction(target)
    puts "Hi #{target}, I'm #{first_name}!"
  end

  def favorite_number
    7
  end
end

frank = Student.new
frank.first_name = "Maxsu"
puts "Maxsu's favorite number is #{frank.favorite_number}."

打開終端運行上面代碼,應該看到:「Maxsu's favorite number is 7」。文件的最後一行調用的是favorite_number方法。 該方法的最後一行(只有)行是第7行。這個表達式作爲方法的返回值,該值返回給調用該方法的任何人。在例子中,這7數字值返回並被插入到字符串中。

注意:寫在最後,需要注意的是:這篇教程包教不包會!