国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

directory search
Ruby用戶指南 3、開始 4、簡(jiǎn)單的例子 5、字符串 6、正則表達(dá)式 7、數(shù)組 8、回到那些簡(jiǎn)單的例子 9、流程控制 10、迭代器 11、面向?qū)ο笏季S 12、方法 13、類 14、繼承 15、重載方法 16、訪問控制 17、單態(tài)方法 18、模塊 19、過程對(duì)象 20、變量 21、全局變量 22、實(shí)變量 23、局部變量 24、類常量 25、異常處理:rescue 26、異常處理:ensure 27、存取器 28、對(duì)象的初始化 29、雜項(xiàng) RGSS入門教程 1、什么是RGSS 2、開始:最簡(jiǎn)單的腳本 3、數(shù)據(jù)類型:數(shù)字 4、數(shù)據(jù)類型:常量與變量 5、數(shù)據(jù)類型:字符串 6、控制語句:條件分歧語句 7、控制語句:循環(huán) 8、函數(shù) 9、對(duì)象與類 10、顯示圖片 11、數(shù)組 12、哈希表(關(guān)聯(lián)數(shù)組) 13、類 14、數(shù)據(jù)庫 15、游戲?qū)ο?/a> 16、精靈的管理 17、窗口的管理 18、活動(dòng)指令 19、場(chǎng)景類 Programming Ruby的翻譯 Programming Ruby: The Pragmatic Programmer's Guide 前言 Roadmap Ruby.new 類,對(duì)象和變量 容器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) 類和對(duì)象 (by jellen) Ruby安全 反射Reflection 內(nèi)建類和方法 標(biāo)準(zhǔn)庫 OO設(shè)計(jì) 網(wǎng)絡(luò)和Web庫 Windows支持 內(nèi)嵌文檔 交互式Ruby Shell 支持 Ruby參考手冊(cè) Ruby首頁 卷首語 Ruby的啟動(dòng) 環(huán)境變量 對(duì)象 執(zhí)行 結(jié)束時(shí)的相關(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的運(yùn)行平臺(tái) pack模板字符串 sprintf格式 Marshal格式 Ruby FAQ Ruby的陷阱
characters

深入方法


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

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

方法定義

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

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

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á)式,但是你不能在方法里面定義實(shí)例方法,類或者模塊。方法的返回值是方法體最后一行執(zhí)行后的結(jié)果,或者你顯示的用一個(gè)return語句。

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

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

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"

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

方法和塊

在討論塊和迭代的那章時(shí),我們知道,當(dāng)一個(gè)方法被調(diào)用時(shí)候,可以接收一個(gè)block,而我們?cè)诜椒ㄖ锌梢杂脃ield來執(zhí)行這個(gè)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ù)中最后一個(gè)參數(shù)以"&"開始的時(shí)候,任何給定的block都會(huì)轉(zhuǎn)換為Proc對(duì)象,并且這個(gè)Proc對(duì)象將會(huì)賦值給這個(gè)參數(shù)(下例中block指向一個(gè)Proc對(duì)象)。

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)用一個(gè)方法需要指定一個(gè)接收者,方法名,還有一些參數(shù)或者block。

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

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

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

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

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

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

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

?方法名后面是可選的參數(shù),如果不會(huì)出現(xiàn)歧義的話,調(diào)用方法時(shí)參數(shù)可以不加括號(hào)括起來[Ruby文檔有時(shí)候也叫做這樣的方法是命令(commands)],然而,除非特別簡(jiǎn)單的方法,否則還是加上括號(hào)的好,要不可能容易出錯(cuò),比如,你的方法嵌套在另一個(gè)方法調(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í)使用數(shù)組

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

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

def?five(a,?b,?c,?d,?e)
??"I?was?passed?#{a}?#?#{c}?#377j5v51b?#{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"

更加動(dòng)態(tài)的block

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

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

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

?但是有些時(shí)候,你需要更靈活一些,比如,下面的例子,如果選擇times,即輸入t,將會(huì)打印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é)計(jì)算的部分抽出來組成一個(gè)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

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

這種技術(shù)也有另外的用處,比如我們使用迭代器處理一些數(shù)據(jù),把每個(gè)步驟地結(jié)果存儲(chǔ)到一個(gè)數(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了一個(gè)方法into,它將返回一個(gè)完成填充array功能的block。(注意返回的block是一個(gè)閉包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ù)的個(gè)數(shù)和位置來調(diào)用一個(gè)方法,而是用一個(gè)hash結(jié)構(gòu)的鍵-值結(jié)構(gòu)來設(shè)定參數(shù),而不是按位置。Ruby1。6不支持這種特性,1。8支持。[本書寫的是基于1.6,而目前最新的Ruby是1.8]

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

 

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

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

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.
Previous article: Next article: