標籤:
Ruby語言中,以對象為基本單位,可以說所有的元素都是對象。按照之前對於物件導向程式的理解,對象是指包含了特定屬性和方法集合的一組程式。對象由類來定義,具體的表現為對象執行個體。也就是說,對象是類的執行個體化[2]。
Ruby語言的基礎元素
對象:數值對象、字串對象、Regex對象、時間對象、檔案對象、目錄對象、數組、雜湊、例外對象等
數值對象
由於Ruby中一切資料都是對象,所以我們處理的數字實際上也是對象。
a = 10,這樣一個簡單的指派陳述式,實際上應當理解為 a = Numeric.new(10) 這樣的一種執行個體化形式。
變數:局部變數(小寫字母或_開頭)、全域變數($)、執行個體變數(@)、類變數(@@)、虛擬變數。
Ruby中的變數在聲明時,也不需要指定類型,這有點類似於弱類型語言的PHP。但是在變數被使用時,他的類型就會被確定。
常量:以大寫字母開頭的變數就是常量
Ruby 中的保留字
Ruby中一般以換行來做為語句分割,也可以使用;來作為語義的分割符。在程式的書寫過程中,我們要注意保持良好的書寫風格。
運算子
操作運算子
+、-、*、/、%、**
比較子
>=、<=、==、<>、===
== 運算子只能進行兩個對象值的比較,如果要對對象進行比較,則需要使用特定的方法 obj1.eql?(obj2),obj1.equal?(obj2)
對於數值對象,比較方法做了自訂,所以結果會有些不同。
Ruby中,對於返回True或False這種方法,命名上一般以?結尾,例如 def AreUSure?()。
邏輯運算子
&&、||、and、or
位元運算符
&、|、~、^、>>、<<
Ruby中的真值與假值
Ruby中,在進行判斷時,false 和 nil 都為假,除此以外的所有值為真。nil 是一個特殊值,用於在Regex中表示沒有找到匹配的內容。也就是說,0 在ruby中也是真值。
Ruby中的Symbol
在Ruby中Symbol表示“名字”,比如字串的名字、標識符的名字,建立一個Symbol對象的方法是在名字或者字串之前加上":"。Ruby中每一個對象都有唯一的物件識別碼(Object Identifier),可以用object_id方法(Getter)獲得。
Ruby中的Block
代碼塊 Code Block 是Ruby的一個很強大的功能,同時又不是很容易理解其設計原理的一個元素。在《Programing Ruby》這本書中指出,block的存在可以用來實現Ruby中的一些Iterator,例如:
Array.each { |index| print Array[index] }
Block的定義方式有兩種,一種是{},另外一種是do/end。前一種比較適合編寫單行程式時使用,後一種比較適合多行程式的情況。具體例子如下:
def greet(name)
print "Hello #{name} "
yield
end
greet("Wang") do
print "Hi"
end
Blcok必須跟在方法調用的後面,通過方法中的yield出發Block的執行。
控制語句
條件判斷語句
在condition為真值時,執行對應區塊的內容。
if condition then
block 1
else
block 2
end
還可以有多個分支
if condition then
block 1
elsif condition then
block 2
else
block 3
end
Ruby中提供了一個與if相反的條件判斷語句 unless
unless condition then
block 1
else
block 2
end
分支判斷語句
case condition
when value1 then
block 1
when value2 then
block 2
else
block 3
end
值得一提的是,case語句中的判斷不僅僅只是變數數值的判斷,也可以使物件類型的判斷,也可以使Regex的判斷,所以Ruby的Case語句使用起來,功能可以非常的強大。
迴圈控制語句
迴圈控制語句用在我們希望重複執行一些動作時,使用迴圈控制語句,需要注意兩個要點:一個是迴圈的條件、一個是迴圈的次數。
Ruby中提供了for、while、until三個迴圈控制語句,each、times、loop三個迴圈控制方法,我們可以根據需要選擇不同的方式。
while condition do
block 1
end
for variable in object do
block
end
until condition do
block
end
object.each{|variable|
block
}
Number.times { | index variable |
block
}
loop {
block
}
Ruby同時提供了三個迴圈控制的語句,包括:break、next、redo。
Ruby中的類、方法與模組
Ruby中的類
類是對對象行為和屬性的描述。做為一門物件導向的指令碼語言,Ruby中支援類的概念,支援類的定義、繼承(不允許繼承多個父類)、限定方法的存取範圍、Setter和Getter的設定等。
類的定義
class ClassName
Version = "1.0"
attr_accessor :name
def initialize(parameter)
end
public
def publicMethod1
block
end
def publicMethod2
block
end
private
def privateMethod1
block
end
def privateMethod2
block
end
end
類的訪問限定符
Ruby中提供了 public、private、protected 三個方法訪問限定符,可以對單個或批量的方法制定訪問的限制條件。可以單獨對單個方法進行訪問限定,也可以使用批量的方式對多個方法使用訪問限定。
預設情況下,所有的方法都是 public ,除了 initialize 之外,它始終是一個 private 的方法。
類的繼承
class People
end
class Male < People
end
Ruby中的模組
命名空間的概念?
模組的定義
module moduleName
end
在其他檔案中使用模組時,首先需要使用require將模組檔案包含進來,AutoLoad?。模組可以在類中引入,這樣模組的方法就會成為類的方法。可以使用這個小技巧來實現Ruby的多重繼承。
Ruby中的方法(函數)
Ruby中的方法區分為執行個體的方法、類的方法、函數性方法。其區分的依據為方法接收者的不同。
執行個體方法的使用方式,執行個體方法的定義實際上是在類中完成的。
object.method( argument1, argument2, argument3 )
類方法的使用方式
f = File.open( filename )
函數性方法的定義
def functionName( parameter1, parameter2 = "default value")
block
return
end
函數性方法可以省略 return 語句,這時函數的傳回值就是方法中最後一個語句的值,就像 Perl 的處理一樣。省略 Return 語句可以為代碼書寫帶來一些方便,但我們需要謹慎對待。
Ruby的函數可以返回多個值,例如:
a, b, c = funca()
錯誤與例外處理
編寫任何程式都可能會發生錯誤,包括語法錯誤、邏輯錯誤。也可能會發生一些意外,比如說硬體的意外損壞。所以我們在編寫程式時,要多所有可能發生的意外情況進行考慮。在沒有例外處理的語言中,我們需要對每種可能發生錯誤的情況進行判斷。幸好,Ruby中提供了例外處理機制,它使我們的工作量大大的減輕了。
錯誤處理的一般形式
begine
block
rescue=> ex
print ex.message
block
ensure
block
retry
end
Ruby中提供了 resuce 來在遇到例外時進行錯誤處理,ensure 確保不管在什麼情況下它下面的代碼部分都會執行,retry 重新嘗試從 begin 開始的代碼。預設情況下 $! 返回例外對象,[email protected] 返回例外資訊。
Ruby 提供了 catch throw 的文法,但是這個和其他語言貌似區別很大。
Ruby提供了一個標準的例外類,其下有眾多的子類來表示不同的例外情況。
Ruby中常用的類
Numeric 類
Numeric類下包括了Integer、Fixnum、Bignum、Float四個子類,關係如所示。
為了方便數學運算,Ruby提供了Math模組,可以方便的進行三角函數等方面的公式運算。
Array類
數組在任何語言中都是非常重要的一個元素,數組提供了一個資料的容器,讓我們可以通過索引快速的遍曆和訪問需要的資料元素。
Ruby中的數組可以扮演三種角色:普通的索引數組、集合、隊列。藉由這三種不同的使用方式,我們可以利用數組來實現FIFO、LILO等多種資料結構。
數組的建立有多種方式:
1、使用 []。
2、使用 Array.new
3、類似於Perl的數組建立方式,使用%w進行建立。
4、使用 obj.to_a 方法,將對象轉換為數組。
5、使用split方法,將字串分割為數組。
Array類中提供了大量的函數方便進行數組的操作,包括:arr.at(index)、arr.pop()、arr.push(value)、arr.shift()、arr.unshift(value)、arr.last()、arr.first()、arr.next()、
、arr.slice()、arr.values_at()、arr.concat()、a.compact()、a.compact!()、a.delete()、a.delete_at()、a.delete_if{|item| ... }、a.reject(|item|)、a.reject!(|item|)、a.slice!()、a.uniq()、a.uniq!()、a.collect{|item| ... }、a.collect!{|item| ... }、a.map{|item| ... }、a.map!{|item| ... }、a.fill()、a.fill(value,begin)、a.fill(value,begin,len)、a.fill(value, n..m)、a.flattern()、a.flattern!()、a.reverse()、a.reverse!()、a.sort()、a.sort!()、a.sort{|i,j| ... }、a.sort!{|i,j| ... }、a.sort_by(|i| ...)、等。
對於數組的遍曆,我們可以採用迴圈配合索引的方式,也可以採用Array提供的一些函數來實現。Array提供的函數中,有一類不會改變數組本身的內容,這種方法稱為非破壞性方法,有一些方法會使數組的內容發生改變,這類方法稱為破壞性方法。對於兩種方式都提供的函數,一般在破壞性方法後加上!來進行區分。我們在使用時,應當特別注意。
String類
字串,是程式開發中非常常見的一種資料類型。Ruby中,建立字串的方式有:
1、直接使用"或者‘建立
2、String.new建立
3、使用%Q和%q的方式建立
因為都是繼承自Object類,所以和Array一樣,有一些公用的方法可以調用,比如is_a、delete、size、slice等方法(真的嗎?有點懷疑)。
字串中,應當注意內嵌運算式,例如 "a string is #{value}",和 內嵌文檔 Here Document。這兩個方法,在PHP等指令碼語言中也非常常見,能夠為處理變數和多行的文本輸出帶來很大的方便。
另外一個需要關心的問題,就是字串的編碼問題。對於西歐文字,如果使用ASCII編碼,那麼我們就可以認為字串的長度,就等於儲存字串的位元組的長度。但是在處理中文或其他類似文字時,往往不能夠使用一個位元組來儲存文字,所以字串的長度會同位元組的長度有不一致。
在程式開發中,字串處理常見的操作包括:去掉前後的空格(chomp)、去掉行尾的換行(strip)、尋找字串、替換字串(sub、gsub、tr、正則等)、截取字串(索引方式、函數方式)、計算字串的長度等。
Hash類
Hash做為一種資料結構,具有較快的存取速度,在處理一些Key-Value的情境中發揮重大的作用。
Ruby中的hash對象,建立方式包括:{}、Hash.new兩種。Hash的key理論上可以是任何對象,但是實際當中,我們一般選擇Numberic、String、Date等做為key值,因為這樣的key值在比較中更為準確,而其他的對象是否一致的比較則相對複雜。
Ruby中提供了擷取key、value的批量及迭代方式,方便我們擷取對象中的內容。
Regex類(Regexp)
Regex的曆史可以追溯到科學家對人類神經系統工作原理的早期研究。美國新澤西州的Warren McCulloch和出生在美國底特律的Walter Pitts這兩位神經生理方面的科學家,研究出了一種用數學方式來描述神經網路的新方法,他們創新地將神經系統中的神經元描述成了小而簡單的自動控制元,從而作出了一項偉大的工作革新。
The origins of regular expressions lie in automata theory and formal language theory, both of which are part of theoretical computer science. These fields study models of computation (automata) and ways to describe and classify formal languages. In the 1950s, mathematician Stephen Cole Kleene described these models using his mathematical notation called regular sets.[1] The SNOBOL language was an early implementation of pattern matching, but not identical to regular expressions. Ken Thompson built Kleene‘s notation into the editor QED as a means to match patterns in text files. He later added this capability to the Unix editor ed, which eventually led to the popular search tool grep‘s use of regular expressions ("grep" is a word derived from the command for regular expression searching in the ed editor: g/re/p where re stands for regular expression[2]). Since that time, many variations of Thompson‘s original adaptation of regular expressions have been widely used in Unix and Unix-like utilities including expr, AWK, Emacs, vi, and lex.
Regex是為了進行較為複雜的字串匹配而出現的。
Ruby中,建立Regex對象有幾種方法://、Regexp.new()、%r等。
Ruby中Regex的元字元與其他語言中的Regex保持一致。
String類提供了sub、gsub、scan三個方法可以接收Regex對象。
IO類
IO是每個程式語言必不可少的部分,通常IO有三個,標準輸入、標準輸出、錯誤輸出。
對於Console來說,Ruby中使用$stdin、$stdout、$stderr來表示。
檔案IO是我們平時編程中最常用到的一種。Ruby和其他語言一樣,提供了open、close、seek、popen、gets、readline、read等函數來協助我們完成檔案的讀取、修改、儲存操作。
File和Dir類
IO類為我們提供了操作輸入、輸出的標準方法,但是對於我們平時經常遇到的檔案系統來說,對於檔案和目錄的操作是我們經常要進行的,所以Ruby提供了File和Dir類,同時還提供了FileTest、fileutils等輔助類,來協助我們更方便的進行程式的編寫。
Time、Date、DateTime類
如果不熟悉的人,看到這三個類,一定會問為什麼要這麼多關於時間處理的類?
Ruby中的進程與線程
Fiber、Thread、Process。
Fibers提供了掛起程式的一部分,然後執行另外一部分程式的能力。實際上Fiber並不是完整意義上的多線程,因為程式的執行會產生中斷,仍然是單條線索在執行。基本形式如下:
fiber = Fiber.new do
Fiber.yield 1
2
end
puts fiber.resume
Firber建立後,並不自動運行,而是等到Fiber#resume方法調用後,開始執行block內的語句。遇到Fiber.yield後,暫停程式的執行,直到下一次調用Fiber#resume或者程式執行結束。
Thread。
在1.9之前,Ruby的多線程由解譯器實現,在1.9之後,多線程開始由系統來實現。但是由此帶來了一個問題,很多Ruby的擴充並不是Thread Safe的,所以有時候會遇到問題,這個需要比較注意。Thread的建立方法。
threads = []
10.times{
threads << Thread.new(parameter) do |p|
end
}
threads.each{ |thr| thr.join }
Ruby中的工具
ri 文檔查看利器。通過 ri options names 的方式,可以查看ruby的文檔,真是非常方便啊!
irb 使用irb進行互動編程。
參考資料:
1、Ruby Programming 高橋征義
2、百度百科-對象的定義
3、百度百科-Ruby on rails
4、Ruby Doc
5、百度百科-Regex
6、Stephen Cole Kleene
7、Programming Ruby by Dave Thomas
8、Ruby中的Symbol
9、Ruby之Symbol研究
Ruby學習筆記