一些基礎的Ruby語言編程知識打賞

我們開始于一個簡單的Ruby程序,我們寫一個方法來返回一個字符串,給這個字符串附加一個人名,我們會調用兩次這個方法。

def sayGoodnight(name) 
 result = "Goodnight, " + name
 return result
end
# Time for bed...
puts sayGoodnight("John-Boy")
puts sayGoodnight("Mary-Ellen") 

首先,發表一下大致的感觀。Ruby語法是干凈的,不需要在行尾加上分號,一行一個語句。Ruby注釋開始于#號,結束在行尾,代碼布局非常適合你,縮排沒有什么意義。(譯者:譯者不太明白這句的意思)

方法是由關鍵字def來定義的,緊跟著方法的名字(本例中是“sayGoodnight”),方法的參數括在圓括號中。Ruby不使用大括號來劃定復合語句和定義的界限,而是簡單地用關鍵詞end來結束它們。我們的方法的主體很簡單,第一行把字符串“Goodnight, ”和參數name連接,然后把返回值賦值給局部變量result,第二行把result返回給調用者。注意我們不需要聲明變量result,當我們賦值給它的時候,它就存在了。

定義了方法后,我們調用了它兩次,每次我們都把返回值傳遞給puts方法,它簡單地把參數輸出到一個新行。

Goodnight, John-Boy
Goodnight, Mary-Ellen
“puts sayGoodnight("John-Boy")”這行包含了兩個方法調用,一個調用sayGoodnight另一個調用puts,為什么這兩個方法中有一個它的參數括在圓括號中,而另一個卻沒有圓括號,這種情況純粹取決于感覺,下面的行是完全等價的:

puts sayGoodnight "John-Boy"
puts sayGoodnight("John-Boy")
puts(sayGoodnight "John-Boy")
puts(sayGoodnight("John-Boy"))
但是,生活不是那么簡單的,優先規則會使哪個參數被哪個方法使用變得復雜,所以我們建議除了極簡單的情況,還是使用圓括號為好。

這個例子也展示了Ruby的string對象,有很多種方法來創建字符串對象,不過最通用的莫過于使用字符串的字面值(譯者注:literal不好翻,參考其它翻譯作品,這里采用字面值的翻譯,大概意思就是字符串本身):在單引號或者雙引號之間的字符序列。兩者之間的不同是Ruby在轉換字面值到字符串對象時所處理的數量,單引號的情況下會少。除了一些例外,字符串字面值就是字符串的值。

雙引號的情況下,Ruby要做更多的處理,首先,它要尋找替代序列就是反斜杠開頭的字符,把它替換成二進制值。最常見的是"\n",它被替換成換行符,一個字符串如果包含換行符,那么"\n"強制換行。

puts "And Goodnight,\nGrandma"
produces:
And Goodnight,
Grandma
第二件事就是Ruby要修改雙引號括住的字符串,字符串中的#{表達式}序列要用表達式的值來替換,我們用這個來重寫前面的方法。

def sayGoodnight(name)
 result = "Goodnight, #{name}"
 return result
end 

當Ruby構造這個字符串對象時,它找到name的當前值,并在字符串中替換它。#{...}結構中可以放入任意復雜的表達式,一個簡潔的寫法是,如果表達式是一個簡單的全局變量、實例或者類變量,那么就不必寫出大括號。

最后,我們可以讓這個方法更加簡化,一個Ruby方法的返回值默認是最后被求的表達式的值,所以我們可以省略掉return語句。

def sayGoodnight(name)
 "Goodnight, #{name}"
end 

我們知道這一節很簡單,我們討論了至少一個話題:Ruby名稱,為了簡單,我們在定義的時候使用了一些術語(像類變量),但是,現在我們要談到規則,趕在你打游戲之前讓我們看看實例變量和類似的一些東西。

Ruby使用一個約定來幫助它區別一個名字的用法:名字前面的第一個字符表明這個名字的用法,局部變量、方法參數和方法名稱應該用一個小寫字母開頭或者一個下劃線;全局變量用美元符作為前綴($),而實例變量用@開頭,類變量用兩個@開頭;最后,類名、模塊名和常量應該大寫字母開頭。

詞首字母后面可以是字母、數字和下劃線的任意組合(規則規定,@后面不可以直接跟數字)。

Example variable and class names
Variables                                         Constants and 
Local         Global     Instance     Class       Class Names  
name          $debug     @name        @@total     PI  
fishAndChips  $CUSTOMER  @point_1     @@symtab    FeetPerMile  
x_axis        $_         @X           @@N         String  
thx1138       $plan9     @_           @@x_pos     MyClass  
_26           $Global    @plan9       @@SINGLE    Jazz_Song  

數組和哈希

Ruby的數組和哈希是有序集合。兩者都保存對象的集合,都可以通過鍵來訪問元素。數組的鍵是一個整數,而哈希支持任何對象作鍵。數組和哈希都可以生長以便容納新的元素,對訪問元素來說,數組的效率高,但哈希卻更靈活。數組和哈希都可以容納不同類型的對象,你可以使用數組來包含一個整數、一個字符串和一個浮點數,就像你馬上看到的那樣。

你可以使用數組的字面值來創建和初始化一個數組----一個方括號括起來的元素集合。有了數組對象,就可以訪問單個的數組元素,在方括號中寫上一個序號就可以,下面的例子就是這樣。

a = [ 1, 'cat', 3.14 ]   # 三個元素的數組  

# 訪問第一個元素
a[0]         >>   1  
# 設置第三個元素的值
a[2] = nil  
# 輸出數組的值 
a            >>   [1, "cat", nil] 

你可以創建一個空數組,用一個沒有元素的數組的字面值,或者用數組對象的構造器,Array.new。

empty1 = []
empty2 = Array.new
有時創建一個字符串的數組會變成一種痛苦,充滿了引號和逗號,幸運的是,有一個快捷方式%w幫我們完成。

a =?%w{ ant bee cat dog elk }  
a[0]         >>      "ant"  
a[3]         >>      "dog"   

Ruby的哈希和數組相似,一個哈希的字面值使用大括號而不是方括號,字面值至少要為每一個條目提供兩個對象:一個是鍵,一個是值。

舉例來說,你可能希望把管弦樂團的樂器歸類,使用哈希的話就是:

instSection = {
 'cello'     => 'string',
 'clarinet'  => 'woodwind',
 'drum'      => 'percussion',
 'oboe'      => 'woodwind',
 'trumpet'   => 'brass',
 'violin'    => 'string'
} 

這里譯為

instSection = {
 '大提琴'     => '弦樂器',
 '單簧管'     => '木管樂器',
 '鼓'         => '打擊樂器',
 '雙簧管'     => '木管樂器',
 '小號'       => '銅管樂器',
 '小提琴'     => '弦樂器'
} 

索引哈希使用和數組一樣的方括號。

instSection['oboe'] >> "woodwind"
instSection['cello'] >> "string"
instSection['bassoon'] >> nil
最后這個例子顯示出,如果使用一個不存在的鍵來索引哈希,默認返回nil。正常情況下這是很方便的,因為nil用在條件表達式中就是false。有時你希望改變這種默認值,例如,如果你使用哈希來計算每一個鍵出現的次數,那么比較方便的情況是默認值為0,在你創建一個新的空的哈希時改變默認值是很容易的。

histogram = Hash.new(0)
histogram['key1'] >> 0
histogram['key1'] = histogram['key1'] + 1
histogram['key1'] >> 1

控制結構

Ruby包括所有常見的控制結構,像if語句和while循環,Java、C、Perl程序員會感到這些語句的主體周圍缺少了大括號,在Ruby中要表示一段主體的結束,我們使用end關鍵字。

if count > 10
 puts "Try again"
elsif tries == 3
 puts "You lose"
else
 puts "Enter a number"
end 

同樣,while語句也由end來結束。

while weight < 100 and numPallets <= 30
 pallet = nextPallet()
 weight += pallet.weight
 numPallets += 1
end 

如果if語句或者while語句的主體是一個簡單的表達式,這時Ruby語句修飾符就是一個很有用的快捷方式。簡單地寫下這個表達式,后面跟上if或者while和條件語句。下面的例子是一個簡單的if語句:

if radiation>3000
  puts "Danger,Will Robinson"
end 

再來一次,這次用語句修飾符來重寫。

puts "Danger,Will Robinson" if radiation>3000
同樣的,一個while循環如下:

while square < 1000
  square = square*square
end 

變得更簡潔,

square = square*square while square < 1000 這些語句修飾符看起來和Perl程序員使用的很相似。 正則表達式 Ruby的大多數內置類型對所有的程序員來說都很熟悉,大部分語言都有字符串、整數、浮點數等等類型。但是,直到Ruby產生的時候,正則表達式還只被所謂的腳本語言支持,像Perl,Python,awk等,這應該讓人慚愧:正則表達式雖然晦澀難懂,但確實是處理文本的絕佳工具。 要寫正則表達式的話能寫整整一本書(像《Mastering Regular Expressions》),所以我們不會覆蓋所有的內容而只是寫一個短篇。我們來看一些正則表達式的例子,你要找到完整的資料看56頁的正則表達式。 一個正則表達式就是在一個字符串中用來匹配的特定的模式字符。在Ruby中,用兩個斜線括住的模式來顯式地創建一個正則表達式(/pattern/),而且,由于Ruby之所以為Ruby的原因,正則表達式當然的也是對象,并且能被處理。 舉例,你要寫一個模式來匹配一個包含"Perl"或者"Python"的字符串,就用下面的正則表達式: /Perl|Python/ 斜線界定了模式,它包括我們要匹配的兩個字符串,用管道符("|")分隔開,你可以在模式中使用圓括號,就像在算術表達中那樣,你可以把模式寫成這樣: /P(erl|ython)/ 也可以在模式中重復聲明,/ab+c/匹配一個字符串,它包含一個"a",然后是一個或者多個"b",然后是一個"c"。如果把加號改成星號,就是/ab*c/那么創建的正則表達式是匹配一個"a",0或者更多的"b",和一個"c"。 你也可以用一個模式來匹配一組字符,常見的如"\s"匹配空白字符(空格、Tab、換行符等),"\d"匹配所有的數字,"\w"匹配所有的可打印字符,簡單的一個字符"."(一個點號)匹配任意字符。 我們把它們放在一起就可以組合成非常有用的正則表達式。

/\d\d:\d\d:\d\d/    #  類似12:34:56這樣的時間
/Perl.*Python/            #  Perl,0或者更多的字符,然后是Python
/Perl\s+Python/           #  Perl,1個或者更多空格,然后是Python
/Ruby (Perl|Python)/      #  Ruby,1個空格,然后是Perl或者Python 

匹配算符"=~"用在正則表達式匹配一個字符串的時候。當模式在字符串中被匹配到后,=~返回它開始的位置,否則返回nil。這意味著你可以在if語句或者while語句中使用正則表達式。例如,下面的代碼片斷顯示當一個字符串中包含"Perl"或者"Python"時的情況。

if line =~ /Perl|Python/
 puts "Scripting language mentioned: #{line}"
end 

字符串中與正則表達式匹配的部分也可以被替換成不同的文本,這要使用Ruby的替代方法。

line.sub(/Perl/, 'Ruby') # 用"Ruby"替換第一個"Perl"
line.gsub(/Python/, 'Ruby') # 用"Ruby"替換所有的"Python"
隨著本書的進行,我們還要討論正則表達式的更多內容。
代碼塊和迭代器

這一節簡短介紹一下Ruby的一個非常特別的功能,我們來認識一下代碼塊:可以和方法調用關聯的一系列代碼,就好像這些代碼是方法的參數一樣,這是一個令人難以置信的強大特性。你可以使用代碼塊實現回調(但不像Java的匿名內部類那么簡單),傳遞一系列代碼(但要比C的函數指針更加復雜),和實現迭代器。

代碼塊是用大括號或者do...end括起來的一系列代碼。

{ puts "Hello" }       # 這是一個代碼塊
do                           #
 club.enroll(person)        # 這也是代碼塊
 person.socialize           #
end                          # 

一旦你創建了一個代碼塊,就可以把它和一個方法調用關聯在一起。那個方法能夠調用代碼塊一次或者更多次,用Ruby的yield語句。下面的例子顯示了這個過程。我們定義一個方法,這個方法調用yield兩次。然后我們調用這個方法,把代碼塊放在同一行中方法調用的后面(也是方法的所有參數的后面)。[有些人喜歡把和方法關聯的代碼塊當作是一種傳遞過來的參數。它們雖然是一個級別的,但這沒有顯示出所有的內涵。最好把代碼塊和方法當成是協同工作的關系,在它們之間控制在來回交換。]

def callBlock
 yield
 yield
end
callBlock { puts "In the block" } 
結果:
In the block
In the block 

看看代碼塊中的代碼(puts "In the block") 是如何被執行兩次的,就是對yield的每一次調用。

你可以在調用yield時給出參數,這些參數傳遞給代碼塊。在代碼塊中,列舉變量的名字來接受參數,這些參數被用"|"括著。

 def callBlock
   yield , 
 end
 callBlock { |, | ... } 

代碼塊貫穿在實現迭代器的Ruby庫中,迭代器就是一種方法,用來連續返回某種集合的元素,比如一個數組。

a =?%w( ant bee cat dog elk ) # 創建一個數組
a.each { |animal| puts animal } # 迭代所有的內容

produces:
ant
bee
cat
dog
elk
我們來看看實現Array類的each迭代器的可能的方法,我們要用到前面的例子。each迭代器遍歷數組的每個元素,每次都調用yield,類似的代碼可能會是下面這樣:

# 在Array類中...
def each
 for each element
   yield(element)
 end
end 

這樣你就可以使用數組的each方法來迭代數組元素提供給代碼塊,代碼塊依次在每個元素返回時被調用一次。

[ 'cat', 'dog', 'horse' ].each do |animal|
 print animal, " -- "
end 
結果:
cat -- dog -- horse -- 

類似的,內置在語言比如C或者Java中的許多循環結構在Ruby中就是簡單的方法調用,這個方法調用所關聯的代碼塊0次或者更多次。

5.times {  print "*" }
3.upto(6) {|i|  print i }
('a'..'e').each {|char| print char } 
結果: 
*****3456abcde 

在這里,我們讓數字5調用一個代碼塊5次,然后讓數字3調用一個代碼塊,傳遞給它連續的數值直到6,最后,字符"a"到"e"的區間使用each方法調用一個塊。
讀寫

Ruby帶著很完善的I/O庫,不過,這本書的大部分例子只介紹了一些很簡單的方法,我們已經看到過兩個用來輸出的方法,puts把它的所有參數寫出來,每一個都加入一個新行,print也寫出它的參數,不過沒有新行。它們兩個都能向任意的I/O對象寫入,不過默認是寫入控制臺。

另一個常用的輸出方法是printf,它按格式輸出參數(就像C或者Perl的printf)。

printf "Number:?%5.2f, String:?%s", 1.23, "hello"

結果:
Number: 1.23, String: hello
這個例子中,格式字符串"Number:?%5.2f, String:?%s" 告訴printf用一個浮點數(總共允許5位,小數點后兩位)和一個字符串來代替。

有很多種方式來把輸入讀取到你的程序中,也許,最傳統的就是使用gets例程,它從你的程序的標準輸入流中返回下一行。

line = gets
print line
gets例程有一個附帶效果,它除了返回讀取的行,還把它儲存到全局變量$_中,這個變量很特殊,在很多環境中它作為默認變量使。如果你調用print而沒有帶參數,它顯示$_的內容;如果你寫一個if或者while語句時僅僅使用一個正則表達式作為條件,那么這個表達式匹配的對象是$_。盡管一些純粹主義者把這看作是令人討厭的野蠻行徑,但是這些簡寫確實又能幫助我們寫出簡潔的程序來。例如,下面的程序現實輸入流中的所有行中包含"Ruby"單詞的行。

while gets           # assigns line to $_
 if /Ruby/          # matches against $_
   print            # prints $_
 end
end 

Ruby方式的寫法是使用迭代器:

ARGF.each { |line| print line if line =~ /Ruby/ }
這里使用了預定義對象ARGF,它描述可以被程序讀取的輸入流。
就是這些,我們已經完成了這個閃電般的Ruby基礎特性的旅行,我們簡單地看了一下對象、方法、字符串、容器和正則表達式,看了一些簡單的控制結構,和迭代器。

以上內容轉載自網絡,小子覺得對了解ruby有一定用途。

一些基礎的Ruby語言編程知識
文章《一些基礎的Ruby語言編程知識》二維碼
  • 微信打賞
  • 支付寶打賞

已有14條評論

  1. 游客 400

    好復雜啊,看的我都暈呢

    2012-07-02 14:47 回復
  2. 張衡Henry

    技術文章很多,支持一下。我來回訪,支持一下。

    2012-07-02 11:22 回復
  3. edusqf

    不錯,很給力!

    2012-07-01 12:37 回復
  4. 捕魚達人攻略

    謝謝樓主的分享,很久沒來碰這東西,忘了也差不多了

    2012-06-28 11:21 回復
  5. 游客 438

    本站http://www.gslante.com/。歡迎博主回訪.

    2012-06-27 11:26 回復
  6. 游客 232

    博主寫的文章很好!贊一個!http://www.seo167.cn

    2012-06-27 10:43 回復
  7. 游客 344

    又是技術貼,后續的了解吧。技術我也蠻喜歡的

    2012-06-26 22:18 回復
  8. 游客 234

    博主博客很不錯哦~我的小站www.renshenblog.com歡迎回訪!

    2012-06-26 17:58 回復
  9. 蘑菇街包包

    呵呵 有沒有php教程啊

    2012-06-26 14:12 回復
  10. 愛玩

    溫習下,看看!

    2012-06-26 14:03 回復
  11. 宜家購物

    果斷的表示看不懂

    2012-06-26 11:56 回復
    • 窮小子

      又是seo,能不能下次換個名稱或者干脆別來我這,小博客養不起你們這樣大神

      2012-06-26 13:27 回復

(必填)

(必填)

(可選)

黑龙江22选5开奖