在本教程中,將探討使用Ruby開始編程所需的基本語(yǔ)法,以及如何在30分鐘內(nèi)學(xué)習(xí)并使用Ruby編程語(yǔ)言。
注:如果您還尚未安裝Ruby開發(fā)環(huán)境,請(qǐng)?jiān)L問(wèn)環(huán)境設(shè)置頁(yè)面并按照說(shuō)明安裝: http://www.yiibai.com/ruby/ruby-installation.html
Ruby被許多人認(rèn)為是一種“新”編程語(yǔ)言,但實(shí)際上是由一個(gè)叫作Matz的開發(fā)人員于1994年發(fā)布的。 Matz自我描述是一個(gè)“語(yǔ)言極客”,也是Perl大粉絲。 他對(duì)Ruby的想法是創(chuàng)建一種像Perl這樣靈活而強(qiáng)大的語(yǔ)言,但在其語(yǔ)法上更具表現(xiàn)力 - 甚至可以具有類似于英語(yǔ)那樣的可讀性。
Ruby在日本迅速成長(zhǎng),直到2000年,真的沒(méi)有關(guān)于除了日本語(yǔ)言以外的任何文檔。所以如果想要學(xué)習(xí)Ruby,那得必須先學(xué)習(xí)日語(yǔ)。 敏捷編程的先驅(qū)Dave Thomas被Ruby迷住,并決定創(chuàng)建Ruby的其它語(yǔ)言文檔。
自Ruby有了英文開始,Ruby就開始在英語(yǔ)世界中增長(zhǎng),盡管緩慢。 系統(tǒng)管理員變得流行,編寫維護(hù)和“粘貼”腳本 - 類似Perl的用法。從2000年到2005年美國(guó)的Ruby社區(qū)已達(dá)數(shù)百個(gè)。
在2004-2005年,一家名為37Signals的芝加哥公司聘請(qǐng)了一名年輕的開發(fā)人員來(lái)構(gòu)建一個(gè)Web應(yīng)用程序。 公司給了他幾乎完全的執(zhí)行自由; 他們只關(guān)心客戶端的設(shè)計(jì)和功能。 當(dāng)時(shí)主要的Web技術(shù)是Perl CGI,PHP,Java的JSP和Microsoft的ASP。 但是他們都是有點(diǎn)痛苦,但DHH的大衛(wèi)(DHH)選擇了自己的方向。他在Ruby中寫了這個(gè)應(yīng)用程序。 他依靠核心庫(kù)和少數(shù)庫(kù)的幫助下,同時(shí)自己創(chuàng)建了整個(gè)堆棧(或多或少)。37Signals在Web應(yīng)用程序使用Ruby來(lái)編寫,這個(gè)項(xiàng)目今天被稱為Basecamp。
當(dāng)建立了Basecamp,DHH就會(huì)從中提取出Web框架。 這是一個(gè)非常不同的方法,從Java/Sun或.NET/Microsoft,Web框架都是從高處往下傳播。 相反,Rails從現(xiàn)實(shí)世界中抽出來(lái)。 它側(cè)重于常規(guī)配置,使常見(jiàn)問(wèn)題更容易解決。
這種方法是一個(gè)很大的打擊,Rails自從以來(lái)一直推動(dòng)了Ruby/Rails社區(qū)的發(fā)展。 現(xiàn)在,在亞馬遜上有數(shù)十本書,全球近一百個(gè)會(huì)議,有成千上萬(wàn)的人是Ruby/Rails開發(fā)人員。
如果你想學(xué)習(xí)Rails,需要先學(xué)習(xí)Ruby! 現(xiàn)在就開始咯 …..
Ruby是一種“解釋”的編程語(yǔ)言,它不能直接在處理器上運(yùn)行,它的代碼必須饋送到稱為“虛擬機(jī)”或虛擬機(jī)的中間件。 虛擬機(jī)的一方面是Ruby代碼,另一方面則是操作系統(tǒng)和處理器。 這種方法的好處是您可以編寫一次Ruby代碼,就可以在許多不同的操作系統(tǒng)和硬件平臺(tái)上執(zhí)行了。
Ruby程序無(wú)法運(yùn)行自己的程序,它需要加載虛擬機(jī)。 使用VM執(zhí)行Ruby的方式有兩種:通過(guò)IRB和命令行。
這是編寫Ruby代碼的耐用方法,因?yàn)橐獙⒅噶畋4娴轿募小?該文件可以備份,傳輸,添加到源代碼管理等。
一個(gè)Ruby代碼文件示例
這里創(chuàng)建一個(gè)名稱為:first-ruby.rb的文件,如下所示:
#!/usr/bin/ruby
# filename : first-ruby.rb
class Sample
def hello
puts "Hello, World!"
end
end
s = Sample.new
s.hello
那么可以這樣運(yùn)行程序:

當(dāng)您運(yùn)行ruby first-ruby.rb時(shí),實(shí)際上正在加載ruby虛擬機(jī),然后再加載first-ruby.rb文件中的代碼。
Ruby是第一批語(yǔ)言推廣所謂“REPL”:閱讀,評(píng)估,打印,循環(huán)的編程語(yǔ)言。想像它就像一個(gè)計(jì)算器 - 就像在每個(gè)完整的指令中,IRB執(zhí)行這些指令并顯示結(jié)果。
IRB最好用作實(shí)驗(yàn)的便箋簿。 許多開發(fā)人員在編寫他們的“真實(shí)”程序時(shí),一般都保持IRB窗口打開,使用它來(lái)記住某個(gè)方法如何工作或用于調(diào)試某個(gè)代碼塊。
要打開IRB進(jìn)行實(shí)驗(yàn),可通過(guò)打開終端(Mac)或命令提示符(Win)并打開或輸入irb來(lái)啟動(dòng)IRB。以Windows系統(tǒng)為例,如下所示 -

注: 按 Ctrl + D 可退出
irb模式。
編程都是要?jiǎng)?chuàng)建抽象的代碼來(lái)描述和處理數(shù)據(jù),要?jiǎng)?chuàng)建抽象,必須要為在代碼中分配名稱來(lái)表示事物。 變量只不過(guò)是為數(shù)據(jù)創(chuàng)建一個(gè)名稱的一種方式。
在某些語(yǔ)言中,需要在為一個(gè)變量分配值之前聲明這個(gè)變量。 當(dāng)為變量分配值時(shí),會(huì)自動(dòng)創(chuàng)建Ruby變量。下面來(lái)試試一個(gè)例子:

a = 250表示創(chuàng)建一個(gè)名稱為a的變量,并將值250存儲(chǔ)到其中。
右邊優(yōu)先
在英文表達(dá)式中,是從左到右閱讀,所以從左到右讀取代碼是很自然的。 但是當(dāng)使用單個(gè)等于號(hào)(=)評(píng)估求值一個(gè)賦值時(shí),Ruby實(shí)際上首先評(píng)估求值右側(cè)。 舉個(gè)例子:
irb(main):010:0> b = 10 + 20
=> 30
irb(main):011:0> b
=> 30
irb(main):012:0>
上面示例中,首先對(duì)10 + 20進(jìn)行評(píng)估求值,再將求值結(jié)果存儲(chǔ)到b變量中。
靈活輸入
Ruby的變量可以容納任何類型的數(shù)據(jù),甚至可以更改其持有的數(shù)據(jù)類型。 例如:
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變量為一個(gè)200的整數(shù)值。第二次賦值是將c變量的值更改其為“Flexible Typing”。
命名變量
大多數(shù)Ruby變量(局部變量)的命名都有一些由VM強(qiáng)制的要求。這些要求約定如下 -
$,@和&除了那些虛擬機(jī)的要求,Ruby開發(fā)者對(duì)變量名稱有幾個(gè)常見(jiàn)風(fēng)格偏好:
_)連接好的變量名的示例如下:count,total_products,students_in_class或first_lesson。
一些不好的Ruby變量名稱的幾個(gè)例子,如下所示:
studentsInClass – 使用駱駝案而不是蛇形大小寫,應(yīng)該命名為:students_in_class1st_lesson – 變量不能以數(shù)字開頭,應(yīng)該命名為:first_lessonstudents_array – 包括名稱的數(shù)據(jù)類型,應(yīng)該命名為:studentssts – 不使用縮寫,應(yīng)該命名為:students使用IRB存儲(chǔ)每個(gè)以下變量名稱的值。 哪些名字是好的,哪些是是無(wú)效的Ruby變量名稱,哪些是有效的,哪些是Ruby不建議使用的風(fēng)格?
time_machinestudent_count_integerhomeworkAssignment3_sectionstop_ppl在現(xiàn)實(shí)世界中,字符串是將一個(gè)個(gè)字符串聯(lián)起來(lái)的。 編程中的字符串與真實(shí)字符串無(wú)關(guān)。
編程中的字符串用于存儲(chǔ)字母和數(shù)字的集合。它可以是一個(gè)單一的字母,如“a”,或者像“hi”這樣一個(gè)單詞,或者“Hello my friends.”這樣的一段話。
Ruby字符串被定義為一個(gè)引號(hào)("),后跟零個(gè)或多個(gè)字母,數(shù)字或符號(hào),后跟一個(gè)閉包引號(hào)(")。 最短的字符串稱為空字符串:""。 單個(gè)字符串包含文本的段落甚至頁(yè)面也很常見(jiàn)。
通常使用字符串,可從整個(gè)長(zhǎng)字符串提取出來(lái)的一部分 - 這提取出來(lái)的部分稱為子字符串。在 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>
正號(hào)和負(fù)號(hào)的位置
字符串中的字符每個(gè)都有一個(gè)位置編號(hào),它們從零開始。 所以對(duì)于字符串中的開頭“Ru”,“R”位置編號(hào)為0,“u”所在的位置編號(hào)為1。
要在主字符串中提取出一個(gè)子串,可指定提取的起始位置和結(jié)束位置。 因此,上面的string[0..8]提取出位置從0至8的字母,也就是:“Ruby in 3”。
Ruby解釋負(fù)的位置從字符串的末尾返回。所以在上面示例中,結(jié)尾的字符串“com”的字母分別對(duì)應(yīng)為“m”位于-1,“o”位于-2 和 “c”位于-3 。
所以如果一個(gè)字母同時(shí)有正數(shù)和負(fù)數(shù)的位置,那么應(yīng)該使用哪個(gè)? 建議使用正數(shù),因?yàn)檫@樣它們更容易理解。 但是,如果要基于字符串末尾查找東西(例如“該字符串的最后一個(gè)字符是什么?”),則使用負(fù)數(shù)指定位置。
在IRB中使用字符串(對(duì)象)中一些常用的方法。
.length
length方法用于求出字符串中有多少個(gè)字符(包括空格):
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>
嘗試:計(jì)算你的名字的總長(zhǎng)度
.split
有時(shí)想要將一個(gè)字符串分成幾部分。 例如,假設(shè)有一個(gè)存儲(chǔ)為字符串的句子,并將其分解成單詞:
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方法返回一個(gè)數(shù)組,這將在后面的部分講解中了解到。 它默認(rèn)使用空格(“ ”)字符將字符串分割成多個(gè)部分。
.split使用參數(shù)
但有時(shí)要分割的不是一個(gè)帶有空格的字符。 .split方法接受一個(gè)參數(shù)來(lái)指定分隔符,看看下面示例就明白了。
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>
在第一次分割的調(diào)用中,它嘗試使用空格作為分隔符,但字符串中沒(méi)有分隔符,所以得到一個(gè)整個(gè)字符串的數(shù)組。 在第二次嘗試中,指定使用逗號(hào)(“,“)作為分隔符,所以得到一個(gè)8個(gè)數(shù)字值的數(shù)組。
.sub 和 .gsub
這兩種方法可以用來(lái)替換字符串的部分。它們就像在文字處理器中使用“查找和替換”。 .sub替換只發(fā)生一次。 而.gsub全局替換的縮寫,替換所有的發(fā)生(如“全部替換”)。
對(duì)于.sub和.gsub,需要指定兩個(gè)參數(shù):首先是要替換的子字符串,然后再替換要替換的字符串。
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>
將變量的值與字符串相結(jié)合這是在開發(fā)應(yīng)用程序中最經(jīng)常使用的。 例如,現(xiàn)在從下面這個(gè)例子開始:
"Good morning, ?? !"
當(dāng)把上面語(yǔ)句放入IRB時(shí),它只是打印輸出同一個(gè)字符串。 如果編寫一個(gè)應(yīng)用程序,希望它以用戶名而不是“??”來(lái)跟用戶打招呼,那么需要怎么做?
需要做的就是將變量與字符串組合。有兩種方法可以做到這一點(diǎn)。
方法-1. 字符串連接
第一種方法,可使用字符串連接,它將字符串與加號(hào)連接:
irb(main):021:0> name = "Maxsu"
=> "Maxsu"
irb(main):022:0> puts "Good morning, " + name + " ! "
Good morning, Maxsu !
=> nil
irb(main):023:0>
在第一行中,設(shè)置了一個(gè)name變量來(lái)保存名稱。 在第二行,打印字符串“Good morning“ 并結(jié)合”name“變量和字符串”!“的值。
方法-2. 字符串插值
第二種方法是使用字符串插值,將數(shù)據(jù)粘貼到字符串的中間。
字符串插值僅適用于雙引號(hào)字符串。在字符串內(nèi)使用插值標(biāo)記#{}。 在這些括號(hào)中可以把任何變量或Ruby代碼放入其中,這些變量或Ruby代碼將被評(píng)估求值,其結(jié)果轉(zhuǎn)換為一個(gè)字符串,并輸出到外部字符串的那個(gè)位置。 上面的例子可以這樣重寫:
irb(main):023:0> name = "Maxsu"
=> "Maxsu"
irb(main):024:0> puts "Good morning, #{name}!"
Good morning, Maxsu!
=> nil
irb(main):025:0>
如果比較輸出結(jié)果,就會(huì)看到它們輸出的是完全相同的結(jié)果。 內(nèi)插樣式往往是輸入較少的字符類型,較少的雙引號(hào)打開/關(guān)閉,所以可避免加雙引號(hào)時(shí)忘記書寫對(duì)稱(往往有輸入多一個(gè),少一個(gè)的問(wèn)題)。
內(nèi)插插入代碼
還可以將任何Ruby代碼或計(jì)算表達(dá)式內(nèi)置在括號(hào)內(nèi),如下所示:
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>
首先對(duì)#{modifier * 3 + mood}代碼塊進(jìn)行評(píng)估求值,然后將結(jié)果注入外部字符串中。
符號(hào)有點(diǎn)難以解釋,它們是字符串和數(shù)字的一半。但是可以很容易識(shí)別一個(gè)符號(hào),因?yàn)樗且悦疤?hào)開始一個(gè)或多個(gè)字母,如:flag或:best_friend。
如果你是編程的新手,可將一個(gè)符號(hào)看作是一個(gè)幾乎沒(méi)有任何方法和沒(méi)有字符串插值的被剝離下來(lái)的字符串。 將正確的字符串與類似符號(hào)的方法列表進(jìn)行比較,如下所示:
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
如果你是一個(gè)有經(jīng)驗(yàn)的程序員,想象一個(gè)符號(hào)是一個(gè)“命名整數(shù)”。 符號(hào)引用的實(shí)際值無(wú)關(guān)緊要。 我們所關(guān)心的是,虛擬機(jī)內(nèi)對(duì)該值的任何引用將返回相同的值。 因此,符號(hào)在全局符號(hào)表中定義,它們的值不能改變。
數(shù)字有兩種基本類型:整數(shù)(整數(shù))和浮點(diǎn)數(shù)(有小數(shù)點(diǎn))。
整數(shù)對(duì)于您和計(jì)算機(jī)來(lái)說(shuō)都要容易一些。 您可以使用包括+, - ,/和*在內(nèi)的整數(shù)的正常數(shù)學(xué)運(yùn)算。 整數(shù)有一些方法可以用來(lái)做數(shù)學(xué)相關(guān)的事情,過(guò)調(diào)用5.methods方法就可看到一些常用的方法。
重復(fù)執(zhí)行指令在其他語(yǔ)言中的常見(jiàn)模式是for循環(huán),用于重復(fù)執(zhí)行某些指令一定次數(shù)。 例如,在JavaScript中可以寫:
for(var i = 0; i < 5; i++){
console.log("Hello, World");
}
對(duì)于循環(huán)是很常見(jiàn)的,但它們的代碼不是很容易閱讀。 因?yàn)镽uby的整數(shù)是它們擁有方法的對(duì)象。 其中的一個(gè)方法:times是重復(fù)執(zhí)行指令的方法。
以Ruby樣式重寫上述循環(huán):
5.times do
puts "Hello, World!"
end
在這個(gè)例子中,使用times方法和具體的執(zhí)行代碼塊。 在下一節(jié)中將討論塊。 但是請(qǐng)先在IRB中運(yùn)行這個(gè)例子,看看結(jié)果會(huì)是什么。
塊是Ruby中經(jīng)常使用的強(qiáng)大概念。 可將塊視為一組捆綁在其他地方使用的指令的方式。
在上一節(jié)中有一個(gè)使用.times方法的塊用整數(shù)表示:
5.times do
puts "Hello, World!"
end
該塊以關(guān)鍵字do開始,以關(guān)鍵字end結(jié)束。 do/end風(fēng)格總是可以被Ruby解釋器所接受的。
當(dāng)塊僅包含單個(gè)指令時(shí),經(jīng)常使用備用標(biāo)記{和}來(lái)標(biāo)識(shí)塊的開始和結(jié)束:
5.times{ puts "Hello, World!" }
那么使用塊來(lái)做什么? 塊可以用來(lái)作為傳遞給方法調(diào)用的參數(shù)。
例如,如果調(diào)用了5.times,Ruby就不會(huì)知道要執(zhí)行五次了。當(dāng)通過(guò)塊時(shí),就會(huì)說(shuō)“這里是希望每次運(yùn)行的說(shuō)明”。
塊中有很多的方法。 就像前面看到的.gsub方法一樣,字符串早就為每個(gè)匹配運(yùn)行一個(gè)塊:
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>
請(qǐng)注意,”Found an E!“顯示了三次,因?yàn)樽址杏腥齻€(gè)E字母。
通常,在塊內(nèi)指示需要引用正在使用的值。 當(dāng)在編寫塊代碼時(shí),可以在管道字符中指定一個(gè)塊參數(shù):
5.times do |i|
puts "Hello, World! "
end
什么值應(yīng)該放入該塊參數(shù),這取決于要調(diào)用的方法。 在本示例中,times方法放入當(dāng)前運(yùn)行的數(shù)值。嘗試上面的塊,觀察輸出,然后嘗試這樣修改:
5.times do |i|
puts "#{i}: Hello, World!"
end
上面代碼輸出結(jié)果如下 -
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在找到的字符串中傳遞。 嘗試這個(gè)(用括號(hào)表示法):
irb(main):048:0> "this is a sentence".gsub("e"){|letter| letter.upcase}
=> "this is a sEntEncE"
irb(main):049:0>
在上面結(jié)果中看到gsub正在使用塊的結(jié)果作為原始匹配的替換。
通常當(dāng)編寫程序時(shí),我們需要處理數(shù)據(jù)的集合。先來(lái)看看最常見(jiàn)的數(shù)據(jù)集合 - 數(shù)組。
數(shù)組是數(shù)字索引列表。 想象一下,有一張空白的紙,畫了三個(gè)小盒子:
--- --- ---
| || || |
--- --- ---
可以按照從左到右對(duì)每一個(gè)位置進(jìn)行編號(hào):
--- --- ---
| || || |
--- --- ---
0 1 2
然后在每個(gè)框中放入字符串(或其它值):
------------- --------- ----------
| "Breakfast" || "Lunch" || "Dinner" |
------------- --------- ----------
0 1 2
現(xiàn)在變成一個(gè)有三元素的數(shù)組。 Ruby數(shù)組的大小可以增長(zhǎng)和縮小,所以如果添加一個(gè)元素,它通常會(huì)在結(jié)束位置添加,索引值也會(huì)變遞增1:
------------- --------- ---------- -----------
| "Breakfast" || "Lunch" || "Dinner" || "Dessert" |
------------- --------- ---------- -----------
0 1 2 3
請(qǐng)注意,最后一個(gè)元素的位置總是比元素的數(shù)量小1。
數(shù)組中在索引為2位置對(duì)應(yīng)的數(shù)據(jù)值為“Dinner”。最后一個(gè)元素對(duì)應(yīng)的數(shù)據(jù)值為“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>
在上面代碼運(yùn)行結(jié)果中,觀察到…
該數(shù)組是通過(guò)將數(shù)據(jù)片段放在方括號(hào)([])之間并用逗號(hào)分隔來(lái)創(chuàng)建的。
通過(guò)使用“鏟子運(yùn)算符”(<<)添加一個(gè)元素到數(shù)組的末尾
通過(guò)使用方括號(hào)([])在指定索引位置來(lái)獲取元素
數(shù)組中一些方便的方法,如.last
數(shù)組有很多很酷的東西。 以下是幾個(gè)例子:
.sort方法
sort方法將返回一個(gè)新的數(shù)組,其中元素是已經(jīng)被排序過(guò)了。 如果元素是字符串,它們將以字母順序返回。 如果它們是數(shù)字,它們將按升值順序回來(lái)。嘗試下面示例:
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方法遍歷每個(gè)元素。使用join方法將它們一起混合成一個(gè)字符串。使用index方法找到特定元素的地址??梢允褂?code>include?方法詢問(wèn)數(shù)組是否包含指定的元素。
使用數(shù)組只要需要一個(gè)列表,其中元素是以特定的順序排序的。
其他的嘗試
在數(shù)組上嘗試下面這些常見(jiàn)的方法:
eachcollectfirst 和 lastshuffle可以參考這個(gè)文檔了解更多詳細(xì)信息:http://www.ruby-doc.org/core-2.1.2/Array.html
哈希是數(shù)據(jù)的集合,哈希中的數(shù)據(jù)的每個(gè)元素是按名稱來(lái)尋址。作為一個(gè)比喻,想一下冰箱。 如果要跟蹤放在冰箱內(nèi)的東西,我們并不關(guān)心它的放在哪里 - 順序并不重要。 相反只是按名稱去組織這些東西。如名稱“apples”可能具有值3,則名稱“oranges”可能具有值1,并且“carrots”值為12。 在本示例中,就可使用哈希。
哈希是無(wú)序的集合,其中數(shù)據(jù)被組織成“鍵/值對(duì)”。 哈希的語(yǔ)法更復(fù)雜,需要一些習(xí)慣:
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>
鍵用作為地址,值是該地址的數(shù)據(jù)。 在produce哈希中有包括“apples”和“oranges”的鍵,其值分別為12和3。當(dāng)創(chuàng)建哈希時(shí),鍵和值使用=>符號(hào)鏈接。 所以哈希從一個(gè)大括號(hào){開始,(由一個(gè)鍵,一個(gè)=>標(biāo)識(shí)符和一個(gè)由逗號(hào)分隔的值組成的零個(gè)或多個(gè)條目,然后以一個(gè)關(guān)閉的大括號(hào)}結(jié)束。
再嘗試一些代碼:
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>
在這些說(shuō)明的第一行中,向哈希添加了一個(gè)新值。 由于“grapes”鍵不在原始哈希中,所以它的值為221。 哈希中的鍵必須是唯一的,所以當(dāng)對(duì)product [“oranges”]使用相同的語(yǔ)法時(shí),它會(huì)看到鍵“oranges”已經(jīng)在列表中,并且用6替換值。keys 和 values方法會(huì)列出所有鍵和值。
通常會(huì)使用符號(hào)作為哈希的鍵。 當(dāng)所有的鍵都是符號(hào)時(shí),可以使用一個(gè)速記語(yǔ)法:
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>
請(qǐng)注意,鍵以冒號(hào)結(jié)尾,而不是以冒號(hào)開始,即使這些是符號(hào)。 這個(gè)簡(jiǎn)化的語(yǔ)法能在Ruby 1.9及更高版本配合使用。要了解正在使用的是哪個(gè)版本的Ruby,可在控制臺(tái)中輸入“ruby -v”。
條件語(yǔ)句評(píng)估求值結(jié)果為true或false。 最常見(jiàn)的條件運(yùn)算符是==(相等),>(大于),>=(大于或等于),<(小于)和<=(小于或等于)。
一些對(duì)象也有返回true或false的方法,因此它們?cè)跅l件語(yǔ)句中使用。 例如,每個(gè)對(duì)象都有方法.nil? 只有當(dāng)對(duì)象為nil時(shí)才返回:true。 數(shù)組有一個(gè)名稱為.include的方法 如果數(shù)組包含指定的元素,則返回true。 Ruby中的約定方法名稱以?結(jié)尾返回true或false。
為什么要有條件語(yǔ)句? 最常見(jiàn)的是控制條件指令,特別是:if/elsif/else結(jié)構(gòu)。在IRB中添加一個(gè)這樣的方法來(lái)寫一個(gè)例子:
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)運(yùn)行該方法。
理解執(zhí)行流程
當(dāng)minutes值為5時(shí),執(zhí)行結(jié)果是什么?因?yàn)?code>minutes = 5小于7,所以打印出來(lái)的結(jié)果為:“The water is not boiling yet.”
當(dāng)minutes值為7時(shí),執(zhí)行結(jié)果是什么?因?yàn)?code>minutes值等于7,所以打印出來(lái)的結(jié)果為:“It's just barely boiling”
當(dāng)minutes值為8時(shí),執(zhí)行結(jié)果是什么?因?yàn)?code>minutes值等于8,所以打印出來(lái)的結(jié)果為:“It's boiling!”
當(dāng)minutes值為9時(shí),執(zhí)行結(jié)果是什么?因?yàn)?code>minutes = 9,它比較了前面的幾個(gè)值:5,7,8,但是都沒(méi)有匹配項(xiàng),所以最后執(zhí)行到else語(yǔ)句塊中,打印出來(lái)的結(jié)果為:“Hot! Hot! Hot!”
if語(yǔ)句可能的結(jié)構(gòu)
if語(yǔ)句有以下可能的結(jié)構(gòu):
if語(yǔ)句的指令只有在語(yǔ)句為真時(shí)執(zhí)行。if語(yǔ)句后面可有零或多個(gè)elsif語(yǔ)句,其指令僅在語(yǔ)句為真時(shí)執(zhí)行if語(yǔ)句后面零或一個(gè)else語(yǔ)句,如果沒(méi)有一個(gè)if或elsif語(yǔ)句為真,則執(zhí)行else語(yǔ)句中的指令。if/else if/else結(jié)構(gòu)中只能在一個(gè)部分可以運(yùn)行它的指令。例如,如果if是真的,Ruby將永遠(yuǎn)不會(huì)執(zhí)行elseif或else,也就是說(shuō)永遠(yuǎn)只執(zhí)行其中一塊。
編寫條件語(yǔ)句時(shí)遇到常見(jiàn)錯(cuò)誤是書寫=和==,以及它們的區(qū)別。
=符號(hào)表示賦值。表示“拿右邊的東西,把它粘在左邊的任何東西” ==表示為這是一個(gè)問(wèn)題。表示“右邊的東西是等于左邊的東西嗎?” 還可以使用邏輯運(yùn)算符組合條件語(yǔ)句。 最常見(jiàn)的是“邏輯與”和“邏輯或”。 在Ruby中,您可以使用這樣的雙符號(hào)(&&)來(lái)書寫表示一個(gè)“邏輯和”。可以用這樣的雙管道(||)書寫表示一個(gè)“邏輯或”。
什么是虛無(wú)? 當(dāng)我們表達(dá)一個(gè)東西,沒(méi)有確定它是什么東西的暫時(shí)可以叫它為:虛無(wú),不是沒(méi)有什么東西嗎? 好的,這太多哲學(xué)了,這有確實(shí)點(diǎn)難解釋了。
nil是Ruby中用于表達(dá)“虛無(wú)”的方式。
如果有三個(gè)雞蛋,您吃三個(gè)雞蛋,那么可能認(rèn)為現(xiàn)在您“沒(méi)有什么”蛋了,但是在雞蛋方面有“0”個(gè)。0是什么?它是一個(gè)數(shù)字,它并不是“虛無(wú)”。
如果使用一個(gè)單詞,如“hello”這樣的字符串,那么刪除“h”,“e”,“l”和“o”,你可能會(huì)認(rèn)為沒(méi)有什么,但是現(xiàn)在真的有“”,它是一個(gè)空字符串,并不是“虛無(wú)”。
nil是Ruby的虛無(wú)的想法的表示。 當(dāng)要求不存在的東西時(shí),通常會(huì)遇到這種情況。 例如,當(dāng)查看數(shù)組時(shí),創(chuàng)建了一個(gè)包含五個(gè)元素的列表,然后要獲取列表中添加第六個(gè)元素。但是沒(méi)有第六個(gè)元素,所以Ruby給了nil。 在第六個(gè)元素的地方它并不是空白(“”),也不是數(shù)字0,它是空/nil。
編寫Ruby代碼時(shí)遇到的大部分錯(cuò)誤是涉及nil值的。以為某個(gè)位置有數(shù)據(jù)值,試圖使用使用這個(gè)數(shù)據(jù)值去做一些事情,但沒(méi)有這樣的數(shù)據(jù)值,不能做任何事情,所以Ruby引發(fā)了一個(gè)錯(cuò)誤。
Ruby是一種面向?qū)ο蟮木幊陶Z(yǔ)言,在與VM內(nèi)部交互的所有東西都是對(duì)象。 每條數(shù)據(jù)都是一個(gè)對(duì)象。 對(duì)象保存的信息稱為屬性,可以執(zhí)行對(duì)象的方法。
作為一個(gè)對(duì)象的例子,想像你是一個(gè)人。 你有像高度,重量和眼睛顏色的屬性。 你有“走路”,“跑步”,“洗碗”和“白日夢(mèng)”的方法。不同類型的對(duì)象具有不同的屬性和方法。 在接下來(lái)的章節(jié)中,將介紹一些Ruby中常見(jiàn)的特定類型的對(duì)象。
在面向?qū)ο缶幊讨?,我們定義了類,它們是類別或類型的東西的抽象描述。 它定義了該類型的所有對(duì)象的屬性和方法。
定義一個(gè)類
例如,考慮對(duì)一個(gè)學(xué)校信息建模。要?jiǎng)?chuàng)建一個(gè)名為“Student”的類,表示學(xué)生的抽象。 Student類將定義如:first_name,last_name和primary_phone_number的屬性。 它可以定義一個(gè)用于學(xué)生自我介紹的方法: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方法是用于定義類的實(shí)例的屬性。
創(chuàng)建類的實(shí)例
Student類本身不代表學(xué)生,這是學(xué)生信息表示模型。 要表示一個(gè)實(shí)際的學(xué)生,需要?jiǎng)?chuàng)建一個(gè)Student類的實(shí)例。
想像你就是一個(gè)學(xué)生,不是一個(gè)抽象的概念,因?yàn)槟闶且粋€(gè)實(shí)際的人。這個(gè)實(shí)際的人是Student類的一個(gè)實(shí)例 - 它是一個(gè)抽象思想的實(shí)現(xiàn)。一個(gè)實(shí)際的人具有屬性:first_name,last_name 和 primary_phone_number 的實(shí)際數(shù)據(jù)(比如:你的first_name是“愛(ài)華”,last_name是“李”等等)。
另一方面,Student類有幾個(gè)抽象的屬性: first_name,last_name 和 primary_phone_number,我們不能提前確定它們。
一般情況下,很少在IRB中定義類。這是因?yàn)?code>IRB只是一個(gè)便簽本(不能很好的保存代碼),記得嗎? 下面來(lái)看看如何從文件中運(yùn)行Ruby。
exit或 Ctrl + D)F:\worksp\ruby)student.rb的文件。student.rb文件中。ruby student.rb
由于這個(gè)文件是空的,所以不應(yīng)該得到任何輸出。
創(chuàng)建Student類
在文本編輯器中,開始編寫類的結(jié)構(gòu):
class Student
end
在類的內(nèi)部,通常使用def關(guān)鍵字定義一個(gè)或多個(gè)方法,如下:
class Student
def introduction
puts "Hi, I'm #{first_name}!"
end
end
請(qǐng)注意,puts行正在計(jì)算求值一個(gè)名為first_name的方法,該方法返回學(xué)生的名字。下面可以進(jìn)一步添加之前使用的三個(gè)屬性:
class Student
attr_accessor :first_name, :last_name, :primary_phone_number
def introduction
puts "Hi, I'm #{first_name}!"
end
end
回到終端,嘗試用ruby student.rb運(yùn)行文件。應(yīng)該不會(huì)看到有結(jié)果輸出。
這是為什么呢? 上面步驟中已經(jīng)定義了一個(gè)Student類,并表示一個(gè)學(xué)生有一個(gè)名為introduction的方法以及一些屬性 - 但是實(shí)際上并沒(méi)有創(chuàng)建Student類的實(shí)例或調(diào)用任何方法。
創(chuàng)建實(shí)例
當(dāng)定義一個(gè)類后,還要?jiǎng)?chuàng)建類的一個(gè)實(shí)例,如下所示:
frank = Student.new
在Student類上調(diào)用new方法并將其存儲(chǔ)到變量frank中。當(dāng)有了這個(gè)類的實(shí)例以后,就可以調(diào)用實(shí)例的方法來(lái)設(shè)置或獲取其屬性。
使用以下語(yǔ)法調(diào)用方法:object.method_name。在上面示例中,創(chuàng)建一個(gè)實(shí)例變量:frank,現(xiàn)在可以通過(guò)調(diào)用 frank.introduction 來(lái)獲取學(xué)生的介紹信息了。
在文件中創(chuàng)建一個(gè)實(shí)例
在student.rb文件的底部,在Student類的end關(guān)鍵字之后,添加以下內(nèi)容:
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
保存代碼并返回到終端,再次執(zhí)行ruby student.rb。 現(xiàn)在應(yīng)該輸出:“Hi, I'm Max!”
有時(shí),方法使用一個(gè)或多個(gè)參數(shù)來(lái)完成一些事情。 例如,可以調(diào)用 frank.introduction('Minlee'),讓它向Minlee介紹自己。參數(shù)可以是數(shù)字,字符串或任何種類的對(duì)象,下面修改introduction方法,以使用一個(gè)參數(shù):
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')
保存代碼并返回到終端,再次執(zhí)行ruby student.rb。 現(xiàn)在應(yīng)該輸出:“Hi Minlee, I'm Maxsu!”
在Ruby中,每次調(diào)用方法時(shí)都會(huì)得到一個(gè)值。 默認(rèn)情況下,Ruby方法返回其評(píng)估求值的最后一個(gè)表達(dá)式的值。
現(xiàn)在向Stuent類中添加一個(gè)方法: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}."
打開終端運(yùn)行上面代碼,應(yīng)該看到:“Maxsu's favorite number is 7”。文件的最后一行調(diào)用的是favorite_number方法。 該方法的最后一行(只有)行是第7行。這個(gè)表達(dá)式作為方法的返回值,該值返回給調(diào)用該方法的任何人。在例子中,這7數(shù)字值返回并被插入到字符串中。
注意:寫在最后,需要注意的是:這篇教程包教不包會(huì)!