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

目錄 搜尋
Ruby用戶指南 3、開始 4、簡單的例子 5、字符串 6、正則表達(dá)式 7、數(shù)組 8、回到那些簡單的例子 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、開始:最簡單的腳本 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、場景類 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的陷阱
文字

Ruby語言



這一章讓我們來對(duì)Ruby語言做一個(gè)從頭到腳地審視。和前面的章節(jié)不同,在這里我們集中精力闡述事實(shí),而不是揭示語言設(shè)計(jì)的細(xì)節(jié)問題。然后我們也盡量避免對(duì)內(nèi)建的類和模塊的介紹,這些內(nèi)容在第275頁開始有詳細(xì)地介紹。

如果這章的內(nèi)容看上去很眼熟,那是因?yàn)樗鼈儽緛砭蛻?yīng)該是我們熟悉的;我們?cè)谇懊娼榻B性的章節(jié)中對(duì)它們都有描述。應(yīng)該把這一章看成自包含的對(duì)核心Ruby語法描述的語言參考。

代碼編排(Source Layout)

Ruby程序是用7字節(jié)ACSII碼(7-bit ASCII)來表示的。[Ruby也有完整的語言擴(kuò)展來支持Kanji編碼,就是使用EUC, SJIS或UTF-8編碼系統(tǒng)。如果一段代碼使用了7字節(jié)ACSII碼以外的編碼格式,那么KCODE選項(xiàng)就應(yīng)該被適當(dāng)?shù)卦O(shè)置,如137頁所示。]

Ruby是一種面向行的(line-oriented)程序設(shè)計(jì)語言。Ruby的表達(dá)式和聲明語句都是在一行的最后結(jié)束,除非一個(gè)語句很明顯是沒有結(jié)束的---比如一行的最后一個(gè)字符是一個(gè)操作符或者逗號(hào)。一個(gè)分號(hào)可以用來分割一行中的多個(gè)語句。你也可以在一行最后加一個(gè)反斜杠來使這一行延續(xù)到下一行。注釋以'#'開始,到物理行結(jié)束為止。在編譯(執(zhí)行)的時(shí)候,注釋將被忽略。

a?=?1

b?=?2;?c?=?3

d?=?4?+?5?+??????#不需要'\' ????6?+?7

e?=?8?+?9???\ ????+?10?????????#需要'\'

在以=begin開始的一行和以=end結(jié)束的一行之間的語句會(huì)被編譯器忽略,不過它們可以作為內(nèi)嵌文檔來使用(請(qǐng)參見第511頁開始的附錄A)。

Ruby只讀一遍源程序,所以你可以向Ruby編譯器的stdin發(fā)送程序代碼。

echo?'print?"Hello\n"'?|?ruby

在任何地方,只要編譯器遇到一行僅包含“__END__”的代碼,沒有前行和后隨的空格,它就把這一行當(dāng)成程序的結(jié)束---后面的所有代碼都不會(huì)被編譯了。然而,后面的代碼可以用一個(gè)全局IO對(duì)象DATA讀入正在執(zhí)行的當(dāng)前程序,這在217頁有描述。

BEGIN和END模塊

每個(gè)Ruby源文件都可以聲明一些代碼模塊用來在文件被載入前(BEGIN模塊)或者在程序執(zhí)行結(jié)束后(END模塊)運(yùn)行。

BEGIN {
  begin code
}

END { end code }

一個(gè)程序可以有多個(gè)BEGINEND模塊。BEGIN模塊以它們出現(xiàn)的順序執(zhí)行,END模塊以相反的順序執(zhí)行。

常規(guī)定界輸入(General Delimited Input)

還有另外一種用來表示字符串常量,數(shù)組,正則表達(dá)式和shell命令的格式,就是用常規(guī)定界語法。所有這些常量都是以一個(gè)百分號(hào)開始,后面跟一個(gè)用來指定常量類型的字符。對(duì)這些字符的描述請(qǐng)參見200頁的表18.1;常用的幾個(gè)字符在這章的后面會(huì)有描述。

常規(guī)定界輸入
類型 涵義 參見
%q 單引號(hào)字符串 202
%Q, % 雙引號(hào)字符串 202
%w 常量數(shù)組 204
%r 正則表達(dá)式 205
%x Shell命令 218

在類型字符后面是一個(gè)分隔符,它可以是任何字符。如果分隔符是“(”,“[”,“{”,“<”中的一個(gè),那么常量由分隔符到相應(yīng)的后隨結(jié)束符(譯者注:比如左括號(hào)'('對(duì)右括號(hào)')')之間的字符組成,注意嵌套的分隔符。對(duì)于其他的分隔符,常量由兩個(gè)分隔符之間的字符組成。

%q/this?is?a?string/
%q-string-
%q(a?(nested)?string)

定界字符串可以跨越多行文本。

%q{def?fred(a)
?????a.each?{?|i|?puts?i?}
???end}

基本數(shù)據(jù)類型

Ruby的基本數(shù)據(jù)類型有數(shù)字,字符串,數(shù)組,哈希表(hashes),范圍(ranges),符號(hào)(symbols)和正則表達(dá)式。

整數(shù)和浮點(diǎn)數(shù)類型

Ruby的整數(shù)是類Fixnum或者Bignum的對(duì)象。Fixnum可以容納物理機(jī)器一個(gè)字長少一位大小的整數(shù)。當(dāng)一個(gè)Fixnum超過它的范圍時(shí),它會(huì)自動(dòng)轉(zhuǎn)換成Bignum類型,而Bignum類型的范圍只能被物理內(nèi)存所限制。如果一個(gè)Bignum上的操作使得它的最終值適合一個(gè)Fixnum保存,那么結(jié)果就會(huì)以一個(gè)Fixnum對(duì)象返回。

整數(shù)前面可以帶一個(gè)可選的符號(hào)標(biāo)記,一個(gè)可選的進(jìn)制指示符(0代表八進(jìn)制,0x代表十六進(jìn)制,0b代表二進(jìn)制),然后跟一串相應(yīng)進(jìn)制的數(shù)字串。在數(shù)字串中的下劃線將被忽略。

你可以在一個(gè)ASCII字符前面加一個(gè)問號(hào)來取得它相應(yīng)的整數(shù)值。Ctrl和Meta(譯者注:Meta就是Alt鍵)的鍵組合可以由?\C-x, ?\M-x, 和?\M-\C-x來產(chǎn)生。一個(gè)字符ch的Ctrl版本是(就是Ctrl + ch組合)ch&0x9f,然后它的Meta版本是ch?|?0x80。你可以用字符序列?\\來取得反斜杠的整數(shù)值。

123456????????????????????#?Fixnum
123_456???????????????????#?Fixnum?(下劃線被忽略)
-543??????????????????????#?Negative?Fixnum
123_456_789_123_345_789???#?Bignum
0xaabb????????????????????#?十六進(jìn)制
0377??????????????????????#?八進(jìn)制
-0b1010???????????????????#?二進(jìn)制?(負(fù)的)
0b001_001?????????????????#?二進(jìn)制
?a????????????????????????#?character?code
?A????????????????????????#?upper?case
?\C-a?????????????????????#?control?a?=?A?-?0x40
?\C-A?????????????????????#?case?ignored?for?control?chars
?\M-a?????????????????????#?meta?sets?bit?7
?\M-\C-a??????????????????#?meta?and?control?a

一個(gè)帶有小數(shù)點(diǎn)的數(shù)字串(也可以帶指數(shù))被認(rèn)為是Float對(duì)象,大小和物理機(jī)器上double類型一樣。你必須在小數(shù)點(diǎn)后面跟一個(gè)數(shù)字,因?yàn)橄?code>1.e3意味著去調(diào)用類Fixnum的方法e3。

12.34 12.34
-.1234e2 -12.34
1234e-2 12.34

字符串

Ruby提供了好幾種方法來產(chǎn)生字符串常量。每中方法都產(chǎn)生String對(duì)象。每種方法在字符串是如何定界和要產(chǎn)生多少替換上是不一樣的。

單引號(hào)字符串('stuff'和%q/stuff/)進(jìn)行最少限度的替換。兩種格式的表示方法都把“\\”轉(zhuǎn)換成一個(gè)反斜杠,然后把“\'”轉(zhuǎn)換成一個(gè)單引號(hào)。

'hello' hello
'a?backslash?\'\\\'' a?backslash?'\'
%q/simple?string/ simple?string
%q(nesting?(really)?works) nesting?(really)?works
%q?no_blanks_here?; no_blanks_here

雙引號(hào)字符串("stuff",%Q/stuff/,和%/stuff/)還會(huì)進(jìn)行額外的替換,詳見203頁表18.2。

雙引號(hào)字符串中的替換

\a Bell/alert (0x07) \nnn Octal nnn
\b Backspace (0x08) \xnn Hex nn
\e Escape (0x1b) \cx Control-x
\f Formfeed (0x0c) \C-x Control-x
\n Newline (0x0a) \M-x Meta-x
\r Return (0x0d) \M-\C-x Meta-control-x
\s Space (0x20) \x x
\t Tab (0x09) #{expr} Value of expr
\v Vertical tab (0x0b)

a??=?123
"\123mile" Smile
"Say?\"Hello\"" Say?"Hello"
%Q!"I?said?'nuts',"?I?said! "I?said?'nuts',"?I?said
%Q{Try?#{a?+?1},?not?#{a?-?1}} Try?124,?not?122
%<Try?#{a?+?1},?not?#{a?-?1}> Try?124,?not?122
"Try?#{a?+?1},?not?#{a?-?1}" Try?124,?not?122

字符串可以跨越多個(gè)文本行,在這種情況下它們可以包含換行符。我們也可以使用here documents來表達(dá)很長的字符串常量。每當(dāng)Ruby遇到字符序列<<標(biāo)識(shí)符 或者 <<括號(hào)字符串的時(shí)候,它就把后隨的所有輸入行變成一個(gè)字符串常量。它一直接收字符到字符串中,直到它遇到一行以前面的標(biāo)識(shí)符或者括號(hào)字符串開始的程序行。你可以在<< 后面跟一個(gè)負(fù)號(hào),使得結(jié)束符可以向右邊縮進(jìn)。如果一個(gè)括號(hào)字符串被用來作為結(jié)束符,那么引號(hào)規(guī)則就會(huì)應(yīng)用到here document中;另外,雙引號(hào)規(guī)則也起作用。

a?=?123
print?<<HERE
Double?quoted?\
here?document.
Sum?=?#{a?+?1}
HERE

print?<<-'THERE' ????This?is?single?quoted. ????The?above?used?#{a?+?1} ????THERE
產(chǎn)生結(jié)果:
Double?quoted?here?document.
Sum?=?124
????This?is?single?quoted.
????The?above?used?#{a?+?1}

相鄰的單引號(hào)和雙引號(hào)字符串會(huì)連接在一起成為一個(gè) String 對(duì)象。

'Con'?"cat"?'en'?"ate" "Concatenate"

字符串保存在8比特字節(jié)長的序列中[為了在日本使用,jcode庫支持一系列對(duì)EUC,SJIS,或者UTF-8編碼字符串的操作。不過底層的字符串還是以字節(jié)形式被訪問。],然后每個(gè)字節(jié)都保存一個(gè)256以內(nèi)的8比特值,包括空值null和換行。203頁表18.2所示的替換規(guī)則允許不可打印字符可以便利并且可移植地嵌入到普通字符串中。

每一次一個(gè)字符串被用在一個(gè)賦值或者用做一個(gè)參數(shù)的時(shí)候,一個(gè)新的String對(duì)象會(huì)被創(chuàng)建。

for?i?in?1..3
??print?'hello'.id,?"?"
end
產(chǎn)生結(jié)果:
537767360?537767070?537767040

String類的詳細(xì)資料請(qǐng)參見第363頁開始的文檔。

范圍(Ranges)

在一個(gè)條件表達(dá)式外面,表達(dá)式expr..exprexpr...expr會(huì)創(chuàng)建范圍對(duì)象(Range)。中間兩點(diǎn)的格式不包括兩邊的邊界值;中間有三點(diǎn)的格式還包括最后那個(gè)邊界值。要看Range類的詳細(xì)信息,請(qǐng)參見第359頁。第222頁有在條件語句中使用范圍的其他方法。

數(shù)組

Array的對(duì)象由一系列在方括號(hào)中由逗號(hào)分隔的對(duì)象引用組成。最后一個(gè)逗號(hào)會(huì)被忽略。

arr?=?[?fred,?10,?3.14,?"This?is?a?string",?barney("pebbles"),?]

字符串?dāng)?shù)組可以由一個(gè)簡捷符號(hào)組成,%w,它可以把由逗號(hào)分隔的一個(gè)連續(xù)字符串中的子字符提取出來組成一個(gè)字符串?dāng)?shù)組??崭窨梢杂煞葱备苻D(zhuǎn)義。這是一種定界輸入的格式,請(qǐng)參見200--201頁。

arr?=?%w(?fred?wilma?barney?betty?great\?gazoo?)
arr ["fred",?"wilma",?"barney",?"betty",?"great?gazoo"]

哈希值(Hashes)

一個(gè)Ruby的Hash對(duì)象是由一系列在花括號(hào)里面的鍵/值匹配對(duì)組成的。由逗號(hào)分隔鍵/值對(duì),鍵和值之間由=>連接。最后一個(gè)逗號(hào)會(huì)被忽略。

colors?=?{?"red"???=>?0xf00,
???????????"green"?=>?0x0f0,
???????????"blue"??=>?0x00f
?????????}

在一個(gè)特定的哈希表中的鍵和值的類型不一定要一致。

哈希鍵值的要求

作為一個(gè)哈希鍵值的唯一要求是它必須響應(yīng)消息hash,然后返回一個(gè)哈希值,這個(gè)哈希值不能改變。這意味著一些類(比如ArrayHash,像這種類型的)不能很好的適合哈希鍵值的要求,因?yàn)樗鼈兊闹禃?huì)隨著它們的內(nèi)容而變化。

如果你保持了一個(gè)對(duì)象的外部引用,然后這個(gè)對(duì)象又被用來做為一個(gè)哈希鍵。那么你通過這個(gè)引用來改變這個(gè)對(duì)象然后改變哈希值,這個(gè)哈希鍵對(duì)應(yīng)的哈希值將不會(huì)起作用。

因?yàn)樽址?jīng)常被用來當(dāng)作鍵值,然后字符串值又會(huì)經(jīng)常改變,Ruby對(duì)字符串鍵值做了特殊處理。當(dāng)你把一個(gè)String對(duì)象當(dāng)做哈希鍵時(shí),哈希表會(huì)復(fù)制一個(gè)字符串,然后把這個(gè)字符串當(dāng)作鍵值。后隨的所有對(duì)原來字符串的改變不會(huì)影響哈希表。

如果你寫了自己的類然后把它們的實(shí)例當(dāng)作哈希鍵值,你必須確保哈希表的鍵值在創(chuàng)建以后不再改變或者在鍵值改變的時(shí)候記得調(diào)用Hash#rehash方法來重新索引哈希表。

符號(hào)對(duì)象(Symbols)

一個(gè)Ruby的符號(hào)對(duì)象是一個(gè)對(duì)象名的內(nèi)部表示。你可以在對(duì)象名前面加一個(gè)冒號(hào)來產(chǎn)生相應(yīng)的符號(hào)對(duì)象。一個(gè)特定的對(duì)象名總是產(chǎn)生相同的符號(hào)對(duì)象,不論對(duì)象名在程序中是如何被使用的。

:Object
:myVariable

其他編程語言稱這個(gè)替換過程為“interning”,然后把符號(hào)對(duì)象叫做“atoms”。

正則表達(dá)式

正則表達(dá)式是類型Regexp的對(duì)象。它們可以通過顯式地調(diào)用 Regexp.new來創(chuàng)建,或者使用文字常量方式,/pattern/和%r{ pattern}。%r創(chuàng)建方法是一種普通定界輸入(詳見200--201頁)。

/pattern/
/pattern/選項(xiàng)
%r{pattern}
%r{pattern}選項(xiàng)
Regexp.new( 'pattern' [, 選項(xiàng)
            ] )

正則式的選項(xiàng)

一個(gè)正則表達(dá)式可以包含一個(gè)或多個(gè)選項(xiàng)來修改默認(rèn)的匹配規(guī)則。如果你使用文字常量來創(chuàng)建正則式,那么一個(gè)或多哥選項(xiàng)就緊跟在結(jié)束符后面。如果你使用Regexp.new方法,那么選項(xiàng)就是構(gòu)造函數(shù)的第二個(gè)參數(shù)。

i 忽略大小寫. 這個(gè)匹配將會(huì)忽略模式和字符串中的字符的大小寫。如果全局變量$=被設(shè)置,那么匹配也會(huì)大小寫不敏感。
o 替換一次。任何在正則式中的#{...}替換都僅進(jìn)行一次,就是第一次遇到它的時(shí)候。其他情況中,替換會(huì)在每次一個(gè)Regexp對(duì)象產(chǎn)生的時(shí)候進(jìn)行。
m 多行模式。通常的,'.'匹配除了換行以外的任何字符。有了/m 選項(xiàng)以后,'.'匹配任何字符了。
x 擴(kuò)展模式。復(fù)雜的正則表達(dá)式會(huì)很難閱讀。'x'選項(xiàng)允許我們可以在模式中加入空格,換行和注釋來使它更容易被閱讀。

正則式的模式

規(guī)則字符
除了.,|, (, ), [, \, ^, {, +, $, *,和?,任何字符都匹配它自己。如果要匹配上面的字符,那么應(yīng)該在它們前面加一個(gè)反斜杠。

^
匹配一行的開始

$
匹配一行的末尾

\A
匹配字符串的開始

\z
匹配字符串的末尾

\Z
匹配字符串的末尾,如果字符串以"\n"結(jié)束,那么它從"\n"前面開始匹配。

\b, \B
相應(yīng)匹配單詞邊界和非單詞的邊界

[ 字符 ]
一個(gè)字符串類型匹配任何出現(xiàn)在方括號(hào)里面的單個(gè)字符。 字符|, (, ), [, ^, $, *,?,在其他地方有特殊含義,但是在方括號(hào)里面就失去了它們的特殊含義。序列 \ nnn, \x nn, \c x, \C- x, \M- x, and \M-\C- x有如203頁表18.2所示的特殊含義。序列\d, \D, \s, \S, \w,和\W是一組字符串的縮寫,如59頁表5.1所示。序列c1-c2表示在c1和c2之間的所有字符(包括c1,c2)。字符]-必須僅跟在左括號(hào)后面。一個(gè)(^)緊跟在左括號(hào)后使匹配反義---模式匹配任何不在方括號(hào)中出現(xiàn)的字符。

\d, \s, \w
分別匹配數(shù)字,空格和單詞字符(word character)。\D, \S, 和\W匹配不是數(shù)字,空格和單詞字符的字符。這些縮寫在59頁表5.1有詳細(xì)描述。

. (句點(diǎn))
出現(xiàn)在方括號(hào)外面,它代表除了換行以外的任何字符(如果/m選項(xiàng)被設(shè)置了,那么它也匹配換行符)。

re *

匹配零次或者多次re的出現(xiàn)。

re +
匹配一次或者多次re的出現(xiàn)。

re {m,n}
匹配最少"m"次然后最多"n"次re的出現(xiàn)。

re ?
匹配零次或一次re的出現(xiàn)。 *, +, 和{m,n}都是最大匹配的,加上一個(gè)問號(hào)使得它們進(jìn)行最小匹配。

re1 | re2
匹配re1或者re2,|的優(yōu)先級(jí)很低。

(...)
圓括號(hào)用來集合正則表達(dá)式。比如,模式 /abc+/匹配一個(gè)含有一個(gè)'a', 一個(gè)'b'然后一個(gè)或多個(gè)'c'的字符串。/(abc)+/就匹配一次或多次"abc"的出現(xiàn)。圓括號(hào)還用來收集模式匹配的結(jié)果。Ruby為每一個(gè)左圓括號(hào)保存括號(hào)中的部分匹配結(jié)果,直到相應(yīng)的右括號(hào)為止。在同一個(gè)匹配中,\1代表第一組匹配的結(jié)果,\2代表第二組結(jié)果,依次類推。在匹配外面,特殊變量$1, $2等起到相同的作用。

替換作用

#{...}
表示一個(gè)字符串中的表達(dá)式的替換。默認(rèn)情況,替換會(huì)在每次匹配成功時(shí)發(fā)生。當(dāng)/o選項(xiàng)被設(shè)置時(shí),它僅僅匹配一次。

\0, \1, \2, ... \9, \&, \`, \', \+
替換第n組匹配,或者整個(gè),前面或后面,或者最高匹配的那一組。

語法擴(kuò)展

和Perl和Python類試,Ruby的正則表達(dá)式提供了一些對(duì)傳統(tǒng)Unix正則表達(dá)式的擴(kuò)展。這些擴(kuò)展都寫在(?/code>?and?)里面。這些圓括號(hào)括著的擴(kuò)展是組,但是它們不會(huì)產(chǎn)生后引用(backreferences):它們不會(huì)設(shè)置\1$1等變量的值。

(?# 注釋)
在模式串中插入注釋。注釋在模式匹配的時(shí)候被忽略。

(?:re)
re加入組,然而不產(chǎn)生后引用。這在當(dāng)你希望創(chuàng)建一個(gè)組但是又不想讓它設(shè)置$1等值的時(shí)候特別有用。在下面的例子中,兩個(gè)模式都保存了一個(gè)包括月份,日子和年份的數(shù)據(jù),用冒號(hào)或空格分隔。第一種格式的在$2$4中保存了數(shù)據(jù),但是第二種格式?jīng)]有保存內(nèi)部數(shù)據(jù)。

date?=?"12/25/01"
date?=~?%r{(\d+)(/|:)(\d+)(/|:)(\d+)}
[$1,$2,$3,$4,$5] ["12",?"/",?"25",?"/",?"01"]
date?=~?%r{(\d+)(?:/|:)(\d+)(?:/|:)(\d+)}
[$1,$2,$3] ["12",?"25",?"01"]

(?=re)
在此處匹配re,但是不要銷毀它(也可以愜意地叫做零距離回顧(``zero-width positive lookahead''))。它可以讓我們方便地引用前面的內(nèi)容而不會(huì)影響$&。在這個(gè)例子中,scan方法匹配后面跟一個(gè)句點(diǎn)的單詞,但是句點(diǎn)不包括在匹配結(jié)果里面。

str?=?"red,?white,?and?blue"
str.scan(/[a-z]+(?=,)/) ?/td> ["red",?"white"]

(?!re)
看看在此處是否不匹配re。不要銷毀這個(gè)匹配(否定的零距離回顧)。比如,/hot(?!dog)(\w+)/匹配任何包含“hot”然后后面不跟“dog”的單詞,返回$1中的最后一個(gè)單詞。

(?>re)
把一個(gè)獨(dú)立的正則式嵌入到第一個(gè)正則式中。這個(gè)表達(dá)式在當(dāng)前匹配點(diǎn)被確定。如果它銷毀了一些字符,這些字符就不會(huì)被上級(jí)的正則式訪問到。因此這個(gè)結(jié)構(gòu)是有后回溯機(jī)制的(backtracking),這可以是一個(gè)執(zhí)行效果的增強(qiáng)。比如,模式/a.*b.*a/的基本意思是匹配一個(gè)含有一個(gè)'a',后面跟數(shù)個(gè)'b',然后沒有后隨'a'的字符串。然而,這可以用嵌套的正則式/a(?>.*b).*a/來避免。在這種格式中,內(nèi)嵌的正則式消耗掉了所有字符串,直到有字符'b'的出現(xiàn)。當(dāng)一個(gè)對(duì)后隨'a'的查找失敗以后,就沒有回溯的必要了,這個(gè)模式匹配迅速結(jié)束。

require?"benchmark"
include?Benchmark
str?=?"a"?+?("b"?*?5000)
bm(8)?do?|test|
??test.report("Normal:")?{?str?=~?/a.*b.*a/?}
??test.report("Nested:")?{?str?=~?/a(?>.*b).*a/?}
end
產(chǎn)生結(jié)果:
??????????????user?????system??????total????????real
Normal:???0.420000???0.000000???0.420000?(??0.414843)
Nested:???0.000000???0.000000???0.000000?(??0.001205)

(?imx)
打開"i","m"或"x"選項(xiàng)。如果用在一個(gè)組里面,那么效果就限制在組里面。

(?-imx)
關(guān)閉"i","m"或"x"選項(xiàng)。

(?imx:re)
打開re的"i","m"或"x"選項(xiàng)。

(?-imx:re)
關(guān)閉re的"i","m"或"x"選項(xiàng)。

標(biāo)識(shí)名

Ruby的標(biāo)識(shí)名用來指向常量,變量,方法,類和模塊。標(biāo)識(shí)名的首字符用來幫助我們確定標(biāo)識(shí)所指向內(nèi)容的類型。一些標(biāo)識(shí)名,就是210頁表18.3所示的都是保留字,不能用來當(dāng)作變量,方法,類或模塊的名字。

保留字

__FILE__ and def end in or self unless
__LINE__ begin defined? ensure module redo super until
BEGIN break do false next rescue then when
END case else for nil retry true while
alias class elsif if not return undef yield

在下面的描述中,小寫字母表示'a'到'z'的字母和'_',下劃線。大寫字母表示'A'到'Z'的字母,還有數(shù)字表示'0'到'9'的數(shù)字字符。標(biāo)識(shí)符字符表示大小寫字母和數(shù)字的組合。

一個(gè)局部變量由一個(gè)小寫字母后面跟標(biāo)識(shí)符組成。

fred??anObject??_x??three_two_one

類的實(shí)例變量由一個(gè)‘@’開始,后面跟一個(gè)大寫或小寫字母,然后后面還可以有一些標(biāo)識(shí)符字符。

@name??@_??@Size

一個(gè)類變量由兩個(gè)‘@@’開始,后面跟一個(gè)大寫或小寫字母,然后后面還可以有一些標(biāo)識(shí)符字符。

@@name??@@_??@@Size

一個(gè)常量名由一個(gè)大寫字母開始,后面跟標(biāo)識(shí)符字符。類名和模塊名是常量,所以也遵循常量的命名規(guī)則。常量名一般是由大寫字母組成,然后可以帶下劃線。

module?Math
??PI?=?3.1415926
end
class?BigBlob

全局變量,以及一些特殊的系統(tǒng)變量,由一個(gè)美圓符號(hào)'$'開始,然后后面跟標(biāo)識(shí)符字符。另外,還有一些有兩個(gè)字符組成的變量名,它們第二個(gè)字符是標(biāo)點(diǎn)符號(hào)。這些預(yù)設(shè)的變量名在213頁有描述。最后,全局變量名也可以用"$-"開頭,后面跟任意一個(gè)字符。

$params??$PROGRAM??$!??$_??$-a??$-.

關(guān)于方法的命名規(guī)則,在從第225頁的開始的章節(jié)有描述。

變量/方法的疑惑

每當(dāng)Ruby在一個(gè)表達(dá)式中遇到一個(gè)比如像'a'這樣的字符,他必須確定這個(gè)'a'到底是一個(gè)局部變量的引用還是一個(gè)無參數(shù)的函數(shù)方法調(diào)用。為了確定這個(gè),ruby用了一種啟發(fā)式(heuristic)的方法。當(dāng)Ruby在讀取源代碼的時(shí)候,它記下了那些被賦值的標(biāo)識(shí)符。它假定這些標(biāo)識(shí)符是變量名。然后如果它在隨后遇到一個(gè)標(biāo)識(shí)符可能是變量,也可能是方法名的時(shí)候,它就查看這個(gè)標(biāo)識(shí)服是否在以前被賦過值。如果被賦過值,它就把標(biāo)識(shí)符當(dāng)成變量名;否則它就把標(biāo)識(shí)符當(dāng)成一個(gè)方法調(diào)用。作為一個(gè)比較詭異的例子,請(qǐng)參見以下的代碼片段,由Clemens Hintze遞交。

def?a
??print?"Function?'a'?called\n"
??99
end

for?i?in?1..2 ??if?i?==?2 ????print?"a=",?a,?"\n" ??else ????a?=?1 ????print?"a=",?a,?"\n" ??end end
produces:
a=1
Function?'a'?called
a=99

在語法解析的時(shí)候,Ruby遇到第一個(gè)'a',因?yàn)榇藭r(shí)'a'沒有被賦值,就認(rèn)為它是一個(gè)方法調(diào)用。然后到第二個(gè)打印語句的時(shí)候,Ruby已經(jīng)遇到了一個(gè)賦值,所以此時(shí)它把'a'當(dāng)成一個(gè)變量。

注意賦值語句不一定要被執(zhí)行---Ruby只要見到它就可以了。這個(gè)程序不會(huì)出現(xiàn)錯(cuò)誤。

a?=?1?if?false;?a

變量和常量

Ruby變量和常量都是指向?qū)ο蟮囊?。變量自身并沒有內(nèi)在的類型。一個(gè)變量的類型僅僅由它指向的對(duì)象的信息決定。 [我們說一個(gè)變量沒有類型,我們的意思就是任何給定的變量可以在不同時(shí)間指向許多不同的類型。]

一個(gè)Ruby的常量也是對(duì)一個(gè)對(duì)象的引用。常量在Ruby首次對(duì)它賦值時(shí)被創(chuàng)建(一般在一個(gè)類或模塊的定義中)。和一些通融性差的語言不同,允許我們修改變量的值,盡管這樣會(huì)得到一個(gè)警告信息。

MY_CONST?=?1
MY_CONST?=?2???#?generates?a?warning
產(chǎn)生結(jié)果:
prog.rb:2:?warning:?already?initialized?constant?MY_CONST

注意雖然常量不應(yīng)該被修改,但是我們可以修改它指向的對(duì)象的內(nèi)部狀態(tài)。

MY_CONST?=?"Tim"
MY_CONST[0]?=?"J"???#修改常量的內(nèi)部狀態(tài)
MY_CONST "Jim"

賦值潛在地給一個(gè)對(duì)象別名,給同一個(gè)對(duì)象不同的名字。

常量和變量的作用域

在一個(gè)類或模塊中定義的常量可以方便地在類或模塊任何地方訪問。在模塊或類外面,它們可以使用域作用符“::”來訪問,在一個(gè)表達(dá)式前加一個(gè)“::”可以返回類或模塊相應(yīng)的對(duì)象。在任何類外面定義的常量,可以通過在它前面加"::"訪問到。我們不能在方法中定義常量。

OUTER_CONST?=?99
class?Const
??def?getConst
????CONST
??end
??CONST?=?OUTER_CONST?+?1
end
Const.new.getConst 100
Const::CONST 100
::OUTER_CONST 99

全局變量在整個(gè)程序中都可以使用。每個(gè)指向特定全局對(duì)象名的引用都返回相同的對(duì)象。引用一個(gè)未初始化的全局變量返回一個(gè)

類變量在整個(gè)類或模塊體中都可以被使用。類變量在使用之前必須被初始化。一個(gè)類變量被這個(gè)類的所有對(duì)象所共有,然后只在類內(nèi)部使用。

class?Song
??@@count?=?0
??def?initialize
????@@count?+=?1
??end
??def?Song.getCount
????@@count
??end
end

類變量屬于最內(nèi)層嵌套類或模塊。最頂層的類變量是定義在Object中的,然后就像全局變量一樣。如果接收者是一個(gè)類或者模塊,那么定義在單例類里面的類變量屬于接收者;否則,它們屬于接收者的類。

class?Holder
??@@var?=?99
??def?Holder.var=(val)
????@@var?=?val
??end
end

a?=?Holder.new def?a.var ??@@var end


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.
上一篇: 下一篇: