Ruby 基礎
作者:Ralf Wirdemann, Thomas Baustert
www.b-simple.de
2006.2.14
1.1 在線文檔和書籍
??? 語言資料上,如果要找核心和標準API的文檔可以去 www.ruby-lang.org,深步進階我們推薦下面的書籍:
Dave Thomas: Programming Ruby, Second Edition, Pragmatic Bookshelf, 2005
Ruby書籍中的標準著作,極具推薦價值。
Hal Fulton: The Ruby Way, Sams, 2001
這部書不僅僅有Ruby語言的最新狀況,還提供了一百個案例,很有意思。
1.2 引言
??? Ruby 是一個純粹的面向對象的動態型語言。Ruby 程序不是被編譯成二進制格式(如Java),而是直接由一個解釋器來處理。這門語言在1995年由松本行弘(Matsumoto Yukihiro)發布,除了 Smalltalk、Python 等語言以外,Perl 對它的影響是首當其沖的。
??? Ruby 里的一切都是對象,它沒有原始類型(如Java)。除了面對對象,Ruby還提供了垃圾回收、異常、正則表達式,為迭代器和方法作參數的“代碼塊”,運行期的類擴展,線程及更多的東西。Ruby 語言易懂易用,原因在于它簡單、語法干凈。
1.3 Ruby 程序
??? Ruby 程序保存在以 .rb 結尾的文件里。程序內容包含類、模塊、或者只是簡單的Ruby代碼。下面是地球人都知道的 Hello World 程序:
# hello.rb????????????????????????
puts "Hello World!"???????????????
??? 如果這個代碼是以 hello.rb 的文件名保存的,那么可以這樣調用:
> ruby hello.rb???????????????????
> Hello World!????????????????????
??? 在Windows下允許您以文件關聯的方式在IE中執行;在 Linux/Unix 下您可按照自已的操作系統情況使用 Shebang行:
#!/usr/local/bin/ruby?????????????
puts "Hello World!"???????????????
??????????????????????????????????
#!/usr/bin/env ruby???????????????
puts "Hello World!"???????????????
??? 隨后直接執行這個程序:
> chmod 744 hello.rb??????????????
> ./hello.rb??????????????????????
??? Ruby 的語句可以以分號結尾,但不是必須。 Ruby 是一個面向行的語言,也就是說,一個語句不需要以分號結尾,解釋器能夠明白下一行是進一步的語句。下面前幾個語句的輸出相同,最后一個是錯誤的:
puts "Hello World!";??????????????
puts "Hello World!"???????????????
puts "Hello " \???????????????????
?? "World!";??????????????????????
puts "Hello" +????????????????????
?? "World!";??????????????????????
puts "Hello"?? # 語句至此結束?????
?? + "World!"; # 無法被解釋的新語句
??? 多個語句可以用分號隔開寫到一行里面,這不是很地道的寫法,因為會影響閱讀的流暢。
# 可行,但不漂亮:????????????????
a = 42; b = 15; c = a + b????????
#這樣比較好:?????????????????????
a = 42???????????????????????????
b = 15???????????????????????????
c = a + b????????????????????????
??? Ruby 以兩個空格作為縮進的方式(不用Tab鍵),這是個推薦習慣并且應該盡可能地得到遵循:
# 非常棒的縮進???????????????????
while line = file.readline???????
? if !comment_line(line)?????????
??? lines.add(line)??????????????
? end????????????????????????????
end??????????????????????????????
# oh~,oh~,您這是和外星人學的吧?
while line = file.readline???????
??? if !comment_line(line)???????
??? ??? lines.add(line)??????????
??? end??????????????????????????
end??????????????????????????????
??? Ruby 提供了全系列的標準類型,如數字、字符串、正則表達式、數組、哈希(Hash),等等。所有這些元素通過類和模塊的方式以備使用,無需在程序(文件)中綁定,它們來自于核心庫并在整個程序中自動生效。
??? 另外一些是以其它類和模塊構成系列的標準庫方式以備使用的,例如 Date、Logger、Test::Unit 等等。一旦要自行開發就必須在每個程序里通過關鍵字 require 來明確綁定。于是在 require 后加上或有或無結尾(.rb)的文件名。
require "date"? # date.rb 用到 Date類??????????????
require "my_class" # my_class.rb 用到MyClass類?????
require "my_module" # my_module.rb 用到 MyModule模塊
??? 對此處文件名的處理不是按絕對路徑,Ruby 會在所有的標準目錄下尋找這個文件,它們被包含在全局變量$: 里面,您可以在命令行用 ruby -e "puts $:" 或其它方式得到這些路徑。一個裝載了類和模塊的程序里的所有名字都可以通過全局變量 $" 輸出。
1.4 注釋
??? 在 Ruby 中注釋行是以#號開始的,注釋可出現在句首或句尾。
# 下面這行是被注釋掉的???????????
# a = b - c??????????????????????
a = b + c # 注釋到行尾???????????
??? 一個注釋塊開始于 =begin 結束于 =end,這幾個關鍵字必須在行首,不能有空格。
=begin???????????????????????????
? def my_method??????????????????
??? ...??????????????????????????
? end????????????????????????????
=end?????????????????????????????
1.5 數字
??? Ruby支持整數和浮點數。Ruby 里面沒有原始類型,都是數字對象。整數從負2的30次冪到正2的30次冪 (在64位機器上從負2的62次冪到正2的62次冪) 被定義成FixNum類型 超出此范圍的整數被定義成BigNum類型,類型的劃歸與轉換是自動完成的,一個數字的長度最終由主存來判定。
value = 42 # FixNum???????????????????????????????
big_value = 123456789012345678901234567890 # BigNum
??? 數字可以用16進制、8進制或者2進制的數字系統來表示:
# 42?????????????????????????????
0x2A?????????????????????????????
0052?????????????????????????????
b101010??????????????????????????
??? 有相應的數學運算符以供使用,數字的增減用運算符 += 與 -= 來實現, 出自 C 和 Java 的 ++ 與 -- 在 Ruby 里是沒有的。
a = 2????????????????????????????
b = 3????????????????????????????
c = a + b??? # 5?????????????????
c = a - b??? # -1????????????????
c = a / b??? # 0?????????????????
c = 2.0 / b? # 0.666666666666667?
c = a * b??? # 6?????????????????
c = a**b???? # 2*2*2 = 8?????????
a += 1?????? # a = 3?????????????
a -= 1?????? # a = 2?????????????
a++????????? # Ruby里非法????????
??? FixNum與BigNum 繼承于基類 Integer,以下是可用的函數,是與塊(見1.14節)結合的:
1.upto(3) { [i] puts i }??? # 1 2 3?????????????
3.downto(3) { [i] puts i }? # 3 2 1?????????????
0.step(10,2) { [i] puts i } # 0 2 4 6 8 10??????
3.times { puts *42* }?????? # 42 42 42??????????
??? 浮點數在 Ruby 里是用 Float 類來表示的。像其它語言一樣,Ruby 里的浮點也有卷折誤差。為了計算精確(如 合值),建議使用 Ruby 標準庫里的 BigDecimal 類,相對于 Float,這個類描述了更為豐富的浮點數并且避開了卷折誤差。
1.6 字符串
?
??? 在 Ruby 里,字符串被放置在兩個單引號或雙引號之間。引號常會出現在另一個引號里面:
?
str = "Hello"????????? # Hello
str = "Hello 'Thomas'" # Hello 'Thomas'
str = 'Hello'????????? # Hello
str = 'Hello "Thomas"' # Hello "Thomas"
?
??? 字符串可以通過 %q 和 %Q 產生,這是為了避免當一個字符串內出現過多的引號或其它符號時會出現這樣或那樣的錯誤。%q 產生一個被包含在單引號中的字符串,%Q 產生一個被包含在雙引號中的字符串,文本以分隔符為界來限定,分隔符可以是除字母與數字以外的所有符號。
%q{a string}
%q(a string)
%Q$a string$
?
??? %Q 可以替換 #{Ausdruck}這樣的表達式,而%q不能:
?
表格1.1 字符串中帶雙引號的逃脫符
\a 響鈴 \b 退格 \e 逃脫 \f 換頁 \n 換行 \r 回車 | \s 空格 \t Tab \v 垂直表格跳位 \nnn 八進制 \xnn 十六進制? \cx Control-x | \C-x???? Control-x \M-x???? Meta-x \M-\C-x? Meta-Control-x \x?????? x #{code}? code |
puts %q{result: #{42.0/3} EUR}???? # result: #{42.0/3} EUR
puts %Q{result: #{42.0/3} EUR}???? # result: 14.0 EUR
?
??? 在花括號、圓括號、角括號的情況下字符串是括號括起來的部分,其它則是到那個符號再次出現為止。字符串也可多行顯示,Ruby 在此并不清除起始空格符。
?
s = %Q@ein String über mehrere?
?Zeile mit "" und '' und durch
? einen Klammeraffen begrenzt@
puts s
=>
ein String über mehrere?
?Zeile mit "" und '' und durch
? einen Klammeraffen begrenzt
puts s.inspect
=>
"ein String \374ber mehrere\n Zeile mit \"\" und '' ...
...und durch \n? einen Klammeraffen begrenzt"
?
???? 一個表達式的結果可以通過#{Ausdruck}插入到一個字符串中,然而這只有在雙引號之間有效。
?
"Ergebnis #{42*7/100} %" # Ergebnis?????? #{2.94} %
"Die Anwort ist: #{answer(x)}"??????????? # Die Anwort ist: 42
?
??? 如C與Java所慣用的,特殊符號由斜杠逃脫,表1.1列舉了所有的特殊符號:
?
"Ein Slash: \\"????????????? # Ein Slash: \
"Er rief: \"Ralf!\""???????? # Er rief: "Ralf!"
'War\'s okey?'?????????????? # War\'s okey?
"Neue\nZeile"??????????????? # Neue
???????????????????????????? #Zeile
'Neue\nZeile'??????????????? # Neue\nZeile
?
??? 兩個字符串的內容可以用 == 方法來比較,與之相對照的是 equal? ,它用來判斷是否是同一個字符串實例(參看1.15.5節):
?
s1 = "Thomas"
s2 = "Thomas"
s3 = "Ralf"
s1 == s2 # => true
s1 == s3 # => false
s1.equal? s1 => true
s1.equal? s2 => false
s1.equal? s3 => false
?
??? 字符串可以用+和<<這兩個方法連接。使用 * 可實現多重累加。
?
"Thomas" + "/Ralf"??? # Thomas/Ralf
s = "Thomas"?
s << " und Ralf"????? # Thomas und Ralf
"Ralf " * 2?????????? # Ralf Ralf
?
?
??? 字符串類提供了大量的方法,讓你隨心所欲,下面是幾個例子;
?
s = "Thomas und Ralf"
s[3]????????????????? # 109
s[3].chr????????????? # m
s[7,3]??????????????? # und
s[0..6]?????????????? # Thomas
?
"Thomas und Ralf".delete("a")???????? # Thoms und Rlf
"Thomas und Ralf".delete("aou")?????? # Thms nd Rlf
"Thomas und Ralf".gsub("und", "oder") # Thomas oder Ralf
"Thomas und Ralf".gsub(/[aou]/, "$")? # Th$m$s $nd R$lf
?
"Thomas und Ralf".index('a')????????? # 4
"Thomas und Ralf".index('a',5)??????? # 12
?
"Thomas und Ralf".split?????????????? # ["Thomas", "und", "Ralf"]
?
??? 為字符串轉換成整數和浮點數提供兩種途徑,安全一些的是使用核心方法 Integer 和 Float, 它們在出錯的時候拋出異常; 另一種是 String 類的方法 to_i 和 to_f,限制較少 。
"42".to_i??????????? # => 42
nil.to_i???????????? # => 0
"42x".to_i?????????? # => 42
Integer("42")??????? # => 42
Integer(nil)???????? # => 0
Integer("42x")?????? # => 參數錯誤
posted on 2006-07-24 17:36
小強 閱讀(1775)
評論(0) 編輯 收藏 所屬分類:
ruby