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

Verzeichnis suchen
Ruby用戶指南 3、開始 4、簡單的例子 5、字符串 6、正則表達式 7、數(shù)組 8、回到那些簡單的例子 9、流程控制 10、迭代器 11、面向對象思維 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ù)據類型:數(shù)字 4、數(shù)據類型:常量與變量 5、數(shù)據類型:字符串 6、控制語句:條件分歧語句 7、控制語句:循環(huán) 8、函數(shù) 9、對象與類 10、顯示圖片 11、數(shù)組 12、哈希表(關聯(lián)數(shù)組) 13、類 14、數(shù)據庫 15、游戲對象 16、精靈的管理 17、窗口的管理 18、活動指令 19、場景類 Programming Ruby的翻譯 Programming Ruby: The Pragmatic Programmer's Guide 前言 Roadmap Ruby.new 類,對象和變量 容器Containers,塊Blocks和迭代Iterators 標準類型 深入方法 表達式Expressions 異常,捕捉和拋出(已經開始,by jellen) 模塊 基本輸入輸出 線程和進程 當遭遇挫折 Ruby和它的世界 Ruby和Web開發(fā) Ruby Tk Ruby 和微軟的 Windows 擴展Ruby Ruby語言 (by jellen) 類和對象 (by jellen) Ruby安全 反射Reflection 內建類和方法 標準庫 OO設計 網絡和Web庫 Windows支持 內嵌文檔 交互式Ruby Shell 支持 Ruby參考手冊 Ruby首頁 卷首語 Ruby的啟動 環(huán)境變量 對象 執(zhí)行 結束時的相關處理 線程 安全模型 正則表達式 字句構造 程序 變量和常數(shù) 字面值 操作符表達式 控制結構 方法調用 類/方法的定義 內部函數(shù) 內部變量 內部常數(shù) 內部類/模塊/異常類 附加庫 Ruby變更記錄 ruby 1.6 特性 ruby 1.7 特性 Ruby術語集 Ruby的運行平臺 pack模板字符串 sprintf格式 Marshal格式 Ruby FAQ Ruby的陷阱
Figuren

深入方法


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

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

方法定義

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

我們已經指定了方法名,如果需要,我們可以定義一些參數(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ù)提供值,將使用這些默認值。通過"=",就可以為這些參數(shù)設定默認值。

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

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

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

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ù),將會包括調用時候后面的所有參數(shù),是一個Array的結構,包括了從第二個開始的所有參數(shù)。

方法和塊

在討論塊和迭代的那章時,我們知道,當一個方法被調用時候,可以接收一個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"

但是,當方法接受參數(shù)中最后一個參數(shù)以"&"開始的時候,任何給定的block都會轉換為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"

調用方法

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

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

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

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

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

如果你省略了接收者,那么默認為self是接收者,即當前對象:

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

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

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

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



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

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

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

在調用方法的時候,你可以使用一個數(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

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

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

通常,這已經足夠好了,我們可以給一個方法提供一個機構良好的塊,而不必再方法中使用很多的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
結果:
(t)imes?or?(p)lus:?t
number:?2
2,?4,?6,?8,?10,?12,?14,?16,?18,?20

雖然這樣可以工作,但是不是很完美,我們可以把負責計算的部分抽出來組成一個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來處理,傳到相應的block。

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

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

盡管這樣已經可以工作了,但是這顯示出來的意圖不像我們想象的那么明晰,所以,我們取而代之的是另外定義了一個方法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]"

哈希結構作為參數(shù)

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

同時,人們可以用hash結構來實現(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結構,包含了各種查找的參數(shù)。使用hash結構,我們可以是有一些鍵-值特性:音樂流派是jazz,時長小于4.5分鐘。但是這段代碼不是太好,而且大括號中的內容很容易被誤認為塊。所以,Ruby提供了一個快捷方式,你可以在方法的參數(shù)中指定鍵=>值的結構,像普通的參數(shù)那樣。這樣的結構都將作為一個hash結構傳給方法,而不需要大擴號了。

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.
Vorheriger Artikel: N?chster Artikel: