亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄 搜索
Ruby用戶指南 3、開始 4、簡單的例子 5、字符串 6、正則表達(dá)式 7、數(shù)組 8、回到那些簡單的例子 9、流程控制 10、迭代器 11、面向?qū)ο笏季S 12、方法 13、類 14、繼承 15、重載方法 16、訪問控制 17、單態(tài)方法 18、模塊 19、過程對象 20、變量 21、全局變量 22、實變量 23、局部變量 24、類常量 25、異常處理:rescue 26、異常處理:ensure 27、存取器 28、對象的初始化 29、雜項 RGSS入門教程 1、什么是RGSS 2、開始:最簡單的腳本 3、數(shù)據(jù)類型:數(shù)字 4、數(shù)據(jù)類型:常量與變量 5、數(shù)據(jù)類型:字符串 6、控制語句:條件分歧語句 7、控制語句:循環(huán) 8、函數(shù) 9、對象與類 10、顯示圖片 11、數(shù)組 12、哈希表(關(guān)聯(lián)數(shù)組) 13、類 14、數(shù)據(jù)庫 15、游戲?qū)ο?/a> 16、精靈的管理 17、窗口的管理 18、活動指令 19、場景類 Programming Ruby的翻譯 Programming Ruby: The Pragmatic Programmer's Guide 前言 Roadmap Ruby.new 類,對象和變量 容器Containers,塊Blocks和迭代Iterators 標(biāo)準(zhǔn)類型 深入方法 表達(dá)式Expressions 異常,捕捉和拋出(已經(jīng)開始,by jellen) 模塊 基本輸入輸出 線程和進(jìn)程 當(dāng)遭遇挫折 Ruby和它的世界 Ruby和Web開發(fā) Ruby Tk Ruby 和微軟的 Windows 擴(kuò)展Ruby Ruby語言 (by jellen) 類和對象 (by jellen) Ruby安全 反射Reflection 內(nèi)建類和方法 標(biāo)準(zhǔn)庫 OO設(shè)計 網(wǎng)絡(luò)和Web庫 Windows支持 內(nèi)嵌文檔 交互式Ruby Shell 支持 Ruby參考手冊 Ruby首頁 卷首語 Ruby的啟動 環(huán)境變量 對象 執(zhí)行 結(jié)束時的相關(guān)處理 線程 安全模型 正則表達(dá)式 字句構(gòu)造 程序 變量和常數(shù) 字面值 操作符表達(dá)式 控制結(jié)構(gòu) 方法調(diào)用 類/方法的定義 內(nèi)部函數(shù) 內(nèi)部變量 內(nèi)部常數(shù) 內(nèi)部類/模塊/異常類 附加庫 Ruby變更記錄 ruby 1.6 特性 ruby 1.7 特性 Ruby術(shù)語集 Ruby的運行平臺 pack模板字符串 sprintf格式 Marshal格式 Ruby FAQ Ruby的陷阱
文字

深入方法


一些其它語言有函數(shù),過程,方法等,而Ruby中只有方法:一段表達(dá)式代碼,返回一個值。

到目前為止,我們在這本書中只是基本的介紹了如何定義,使用方法,現(xiàn)在,我們會繼續(xù)深入的探討一些關(guān)于方法更深層的東西。

方法定義

如同在前面看到的一樣,定義一個方法用關(guān)鍵字def開頭,方法名應(yīng)該以小寫字母開頭[如果你用大寫字母開頭定義一個方法,你不會立即得到一個錯誤,但是當(dāng)你調(diào)用這個方法時,Ruby首先認(rèn)為你訪問的是一個常量,所以可能會解析錯誤],如果一個方法主要用來完成一些查詢操作(不專指數(shù)據(jù)庫查詢),通常以一個問號"?"結(jié)束,作為函數(shù)名的最后一個字母,比如instance_of?等。如果一個方法有一定危險,或者可能修改方法的接受者,通常以"!"結(jié)尾,比如String類提供了chop和chop!兩個方法,第一個方法返回一個修改過的字符串,而第二個方法直接就修改了接收者本身。"?"和"!"是唯一兩個能作為方法名后綴的特殊字符。

我們已經(jīng)指定了方法名,如果需要,我們可以定義一些參數(shù),這些參數(shù)用雙括號括起來,作用域范圍都是局部變量,一些例子如下:

def?myNewMethod(arg1,?arg2,?arg3)?????#?3?arguments
??#?Code?for?the?method?would?go?here
end

def?myOtherNewMethod??????????????????#?No?arguments    
??#?Code?for?the?method?would?go?here    
end
  

Ruby允許為方法的參數(shù)設(shè)置默認(rèn)值:如果調(diào)用者沒有顯示的為這些參數(shù)提供值,將使用這些默認(rèn)值。通過"=",就可以為這些參數(shù)設(shè)定默認(rèn)值。

def?coolDude(arg1="Miles",?arg2="Coltrane",?arg3="Roach")
??"#{arg1},?#{arg2},?#{arg3}."
end
coolDude ? "Miles,?Coltrane,?Roach."
coolDude("Bart") ? "Bart,?Coltrane,?Roach."
coolDude("Bart",?"Elwood") ? "Bart,?Elwood,?Roach."
coolDude("Bart",?"Elwood",?"Linus") ? "Bart,?Elwood,?Linus."

方法體中包含了一般的Ruby表達(dá)式,但是你不能在方法里面定義實例方法,類或者模塊。方法的返回值是方法體最后一行執(zhí)行后的結(jié)果,或者你顯示的用一個return語句。

可變長度的參數(shù)列表

如果我們想給方法傳入一個數(shù)目不定的參數(shù),或者把所有參數(shù)放到一個參數(shù)中進(jìn)行傳遞的話,該怎么辦呢?我們可以在普通的參數(shù)后面加入一個特殊的參數(shù),這個參數(shù)以"*"開頭,就可以達(dá)到這個目的了。

def?varargs(arg1,?*rest)
??"Got?#{arg1}?and?#{rest.join(',?')}"
end
varargs("one") ? "Got?one?and?"
varargs("one",?"two") ? "Got?one?and?two"
varargs?"one",?"two",?"three" ? "Got?one?and?two,?three"

在這個例子中,第一個參數(shù)很普通,直接作為第一個參數(shù)變量,而后面以"*"開頭的參數(shù),將會包括調(diào)用時候后面的所有參數(shù),是一個Array的結(jié)構(gòu),包括了從第二個開始的所有參數(shù)。

方法和塊

在討論塊和迭代的那章時,我們知道,當(dāng)一個方法被調(diào)用時候,可以接收一個block,而我們在方法中可以用yield來執(zhí)行這個block。

def?takeBlock(p1)
??if?block_given?
????yield(p1)
??else
????p1
??end
end

takeBlock("no?block") ? "no?block"
takeBlock("no?block")?{?|s|?s.sub(/no?/,?'')?} ? "block"

但是,當(dāng)方法接受參數(shù)中最后一個參數(shù)以"&"開始的時候,任何給定的block都會轉(zhuǎn)換為Proc對象,并且這個Proc對象將會賦值給這個參數(shù)(下例中block指向一個Proc對象)。

class?TaxCalculator
??def?initialize(name,?&block)
????@name,?@block?=?name,?block
??end
??def?getTax(amount)
????"#@name?on?#{amount}?=?#{?@block.call(amount)?}"
??end
end
tc?=?TaxCalculator.new("Sales?tax")?{?|amt|?amt?*?0.075?}
tc.getTax(100) ? "Sales?tax?on?100?=?7.5"
tc.getTax(250) ? "Sales?tax?on?250?=?18.75"

調(diào)用方法

通常,調(diào)用一個方法需要指定一個接收者,方法名,還有一些參數(shù)或者block。

connection.downloadMP3("jitterbug")?{?|p|?showProgress(p)?}

在這個例子里,connection是接收者,downloadMP3是方法名,"jitterbug"是一個參數(shù),{?|p|?showProgress(p)?}是傳遞給這個方法的塊。

對于類或者模塊方法來說,接收者是類或模塊名:

File.size("testfile")
Math.sin(Math::PI/4)

如果你省略了接收者,那么默認(rèn)為self是接收者,即當(dāng)前對象:

self.id ? 537794160
id ? 537794160
self.type ? Object
type ? Object

這種機(jī)制也是Ruby實現(xiàn)private方法的體現(xiàn),private方法不能用一個接收者來直接調(diào)用,只能在當(dāng)前對象中使用。

?方法名后面是可選的參數(shù),如果不會出現(xiàn)歧義的話,調(diào)用方法時參數(shù)可以不加括號括起來[Ruby文檔有時候也叫做這樣的方法是命令(commands)],然而,除非特別簡單的方法,否則還是加上括號的好,要不可能容易出錯,比如,你的方法嵌套在另一個方法調(diào)用之中。

a?=?obj.hash????#?Same?as
a?=?obj.hash()??#?this.



obj.someMethod?"Arg1",?arg2,?arg3???#?Same?thing?as     
obj.someMethod("Arg1",?arg2,?arg3)??#?with?parentheses.

在方法調(diào)用時使用數(shù)組

前面我們已經(jīng)說過了,在一個方法的參數(shù)前面可以加一個星號,這樣所有后面的參數(shù)都被放到了一個數(shù)組中,反過來,Ruby也支持調(diào)用的時候指定一個數(shù)組代替若干個參數(shù)。

在調(diào)用方法的時候,你可以使用一個數(shù)組作為一個參數(shù),它的每個元素都將作為一個單獨的參數(shù)使用。使用的時候,需要在這個作為參數(shù)的數(shù)組前面加一個星號。

def?five(a,?b,?c,?d,?e)
??"I?was?passed?#{a}?#?#{c}?#wjcelcm34c?#{e}"
end
five(1,?2,?3,?4,?5?) ? "I?was?passed?1?2?3?4?5"
five(1,?2,?3,?*['a',?'b']) ? "I?was?passed?1?2?3?a?b"
five(*(10..14).to_a) ? "I?was?passed?10?11?12?13?14"

更加動態(tài)的block

我們已經(jīng)看過了如何把一個方法和一個塊聯(lián)系起來。

listBones("aardvark")?do?|aBone|
??#?...
end

通常,這已經(jīng)足夠好了,我們可以給一個方法提供一個機(jī)構(gòu)良好的塊,而不必再方法中使用很多的if或者while等語句。

?但是有些時候,你需要更靈活一些,比如,下面的例子,如果選擇times,即輸入t,將會打印2,4,6,8等等:

print?"(t)imes?or?(p)lus:?"
times?=?gets
print?"number:?"
number?=?gets.to_i



if?times?=~?/^t/      
??puts((1..10).collect?{?|n|?n*number?}.join(",?"))      
else      
??puts((1..10).collect?{?|n|?n+number?}.join(",?"))      
end
結(jié)果:
(t)imes?or?(p)lus:?t
number:?2
2,?4,?6,?8,?10,?12,?14,?16,?18,?20

雖然這樣可以工作,但是不是很完美,我們可以把負(fù)責(zé)計算的部分抽出來組成一個block。

?

print?"(t)imes?or?(p)lus:?"
times?=?gets
print?"number:?"
number?=?gets.to_i


if?times?=~?/^t/      
??calc?=?proc?{?|n|?n*number?}      
else      
??calc?=?proc?{?|n|?n+number?}      
end      
puts((1..10).collect(&calc).join(",?"))
produces:
(t)imes?or?(p)lus:?t
number:?2
2,?4,?6,?8,?10,?12,?14,?16,?18,?20

如果最后一個方法的最后一個參數(shù)以"&"開頭,Ruby把它最為一個Proc來處理,傳到相應(yīng)的block。

這種技術(shù)也有另外的用處,比如我們使用迭代器處理一些數(shù)據(jù),把每個步驟地結(jié)果存儲到一個數(shù)組中,我們下面將用到前面的Fibonacci 例子來產(chǎn)生一組數(shù)據(jù):

a?=?[]
fibUpTo(20)?{?|val|?a?<<?val?} ? nil
a.inspect ? "[1,?1,?2,?3,?5,?8,?13]"

盡管這樣已經(jīng)可以工作了,但是這顯示出來的意圖不像我們想象的那么明晰,所以,我們?nèi)《氖橇硗舛x了一個方法into,它將返回一個完成填充array功能的block。(注意返回的block是一個閉包closure ,即使into返回了,它還指向參數(shù)anArray

def?into(anArray)
??return?proc?{?|val|?anArray?<<?val?}
end
fibUpTo?20,?&into(a?=?[])
a.inspect ? "[1,?1,?2,?3,?5,?8,?13]"

哈希結(jié)構(gòu)作為參數(shù)

一些語言支持基于鍵的參數(shù),即hash結(jié)構(gòu)的參數(shù)。不按照參數(shù)的個數(shù)和位置來調(diào)用一個方法,而是用一個hash結(jié)構(gòu)的鍵-值結(jié)構(gòu)來設(shè)定參數(shù),而不是按位置。Ruby1。6不支持這種特性,1。8支持。[本書寫的是基于1.6,而目前最新的Ruby是1.8]

同時,人們可以用hash結(jié)構(gòu)來實現(xiàn)這一功能,比如,我們要為我們的SongList實現(xiàn)一個按名字查找的功能。

 

class?SongList
??def?createSearch(name,?params)
????#?...
??end
end
aList.createSearch("short?jazz?songs",?{
???????????????????'genre'????????????=>?"jazz",
???????????????????'durationLessThan'?=>?270
???????????????????}?)

第一個參數(shù)是查找的名稱,第二個參數(shù)是一個hash結(jié)構(gòu),包含了各種查找的參數(shù)。使用hash結(jié)構(gòu),我們可以是有一些鍵-值特性:音樂流派是jazz,時長小于4.5分鐘。但是這段代碼不是太好,而且大括號中的內(nèi)容很容易被誤認(rèn)為塊。所以,Ruby提供了一個快捷方式,你可以在方法的參數(shù)中指定鍵=>值的結(jié)構(gòu),像普通的參數(shù)那樣。這樣的結(jié)構(gòu)都將作為一個hash結(jié)構(gòu)傳給方法,而不需要大擴(kuò)號了。

aList.createSearch("short?jazz?songs",
???????????????????'genre'????????????=>?"jazz",
???????????????????'durationLessThan'?=>?270
???????????????????)


Extracted from the book "Programming Ruby - The Pragmatic Programmer's Guide"
Copyright ? 2001 by Addison Wesley Longman, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/)).

Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.

Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.
上一篇: 下一篇: