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

directory search
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ù)據(jù)類型:數(shù)字 4、數(shù)據(jù)類型:常量與變量 5、數(shù)據(jù)類型:字符串 6、控制語句:條件分歧語句 7、控制語句:循環(huán) 8、函數(shù) 9、對象與類 10、顯示圖片 11、數(shù)組 12、哈希表(關聯(lián)數(shù)組) 13、類 14、數(shù)據(jù)庫 15、游戲對象 16、精靈的管理 17、窗口的管理 18、活動指令 19、場景類 Programming Ruby的翻譯 Programming Ruby: The Pragmatic Programmer's Guide 前言 Roadmap Ruby.new 類,對象和變量 容器Containers,塊Blocks和迭代Iterators 標準類型 深入方法 表達式Expressions 異常,捕捉和拋出(已經(jīng)開始,by jellen) 模塊 基本輸入輸出 線程和進程 當遭遇挫折 Ruby和它的世界 Ruby和Web開發(fā) Ruby Tk Ruby 和微軟的 Windows 擴展Ruby Ruby語言 (by jellen) 類和對象 (by jellen) Ruby安全 反射Reflection 內建類和方法 標準庫 OO設計 網(wǎng)絡和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的陷阱
characters

控制結構

  • 條件分支
    • if
    • if 修飾句
    • unless
    • unless 修飾句
    • case
  • 循環(huán)
    • while
    • while 修飾句
    • until
    • until修飾句
    • for
    • break
    • next
    • redo
    • retry
  • 異常處理
    • raise
    • begin
    • rescue修飾句
  • 其他
    • return
    • BEGIN
    • END

(與C等語言不同的是)Ruby的控制結構是表達式,其中的一部分還會返回值(也有不返回值的,若把這些不返回值的表達式放在賦值表達式右邊的話,就會引發(fā) parse error)。

Ruby中包括從C和Perl那里繼承來的控制結構,還包括一種可以將控制結構抽象化的功能,即 帶塊的方法調用。帶塊的方法調用使類的設計者可以自己定義一些包括循環(huán)在內的控制結構。

條件分支

if

例:

if age >= 12 then
  print "adult fee\n"
else
  print "child fee\n"
end
gender = if foo.gender == "male" then "male" else "female" end

語法:

if 表達式 [then]
  表達式 ...
[elsif 表達式 [then]
  表達式 ... ]
...
[else
  表達式 ... ]
end

若條件表達式的計算結果為真時,將計算then以下的表達式。若if的條件表達式為偽時,將計算elsif的條件部分??梢源嬖谌舾蓚€elsif部分,若所有的if以及elsif的條件表達式都為偽的話,如果有else部分,就計算它的表達式。

if 表達式的結果取決于條件成立部分(或else部分)中最后被計算的表達式的結果。若沒有else部分,且所有條件均不成立的話,就返回nil。

Ruby中只有falsenil代表偽,其他都是真,甚至0或空字符串也是如此。

請注意,在Ruby中,和if對應的是elsif,而并非else if(C的語句)或者elif(sh的語句)。

另外,當if 條件表達式中出現(xiàn)正則表達式字面值時,將作如下處理

$_ =~ 字面值

if 修飾句

例:

print "debug\n" if $DEBUG

語法:

表達式 if 表達式

當右邊的條件成立時,計算左邊的表達式,并返回其結果。若條件不成立則返回nil。

unless

例:

unless baby?
  feed_meat
else
  feed_milk
end

語法:

unless 表達式 [then]
  表達式 ...
[else
  表達式 ... ]
end

unlessif相反,當條件表達式結果為偽時,才計算then后面的表達式。unless表達式中不能安插elsif語句。

unless 修飾句

例:

print "stop\n" unless valid(passwd)

語法:

表達式 unless 表達式

當右邊的條件不成立時,計算左邊的表達式,并返回其結果。若條件不成立時返回nil。

case

例:

case $age
when 0 .. 2
  "baby"
when 3 .. 6
  "little child"
when 7 .. 12
  "child"
when 13 .. 18
  "youth"
else
  "adult"
end

語法:

case [表達式]
[when 表達式 [, 表達式] ...[, `*' 表達式] [then]
  表達式..]..
[when `*' 表達式 [then]
  表達式..]..
[else
  表達式..]
end

case先對一個表達式進行匹配判斷,然后根據(jù)匹配結果進行分支選擇。它使用"==="操作符比較when的指定值和最初那個表達式的計算值,若一致的話就計算when部分的內容。

也就是說

case 表達式0
when 表達式1, 表達式2
  stmt1
when 表達式3, 表達式4
  stmt2
else
  stmt3
end

基本上等同于下面的if表達式。

_tmp = 表達式0
if 表達式1 === _tmp or 表達式2 === _tmp
  stmt1
elsif 表達式3 === _tmp or 表達式4 === _tmp
  stmt2
else
  stmt3
end

when 部分的計算順序同上面這個if句的計算順序是相同的。即從上到下(從左到右)地計算"==="。另外,“表達式0”只計算一次。

若when 部分中的最后一個表達式前帶"*"的話,該表達式將被當作數(shù)組展開。

ary = [1,2,3]

case v
when *ary
 ..
end

等同于

case v
when 1, 2, 3
 ..
end

請參考描述各個類中"==="方法技術細節(jié)的文檔,來了解"==="在何種條件下為真。

case的“表達式”部分被省略時,將計算第一個when條件部分為真的表達式。

foo = false
bar = true
quu = false

case
when foo then puts 'foo is true'
when bar then puts 'bar is true'
when quu then puts 'quu is true'
end
# 顯示 "bar is true"

case將返回條件成立的when部分(或else部分)中最后被計算的表達式的結果。若所有條件都不成立的話,則返回nil。

循環(huán)

while

例:

ary = [0,2,4,8,16,32,64,128,256,512,1024]
i = 0
while i < ary.length
  print ary[i]
  i += 1
end

語法:

while 表達式 [do]
   ...
end

只要表達式的計算值為真,就循環(huán)執(zhí)行while語句中的內容。while不返回值。

ruby 1.7 特性: while返回nil。另外,可以使用帶參數(shù)的break,將while表達式的返回值設為那個參數(shù)的值。

while 修飾句

例:

sleep(60) while io_not_ready?

語法:

表達式 while 表達式

只要右邊表達式的計算值為真,就循環(huán)執(zhí)行左邊部分。

若左邊表達式是begin,且即不含rescue,又不含ensure的話,則只在開始時計算一次然后就執(zhí)行循環(huán)。

ruby 1.7 特性: 在version 1.7中,即使出現(xiàn)rescue/ensure部分也會作相同處理。

例:

send_request(data)
begin
  res = get_response()
end while res == 'Continue'

while 修飾的表達式?jīng)]有返回值。

ruby 1.7 特性: while修飾的表達式返回nil。另外,可以使用帶參數(shù)的break,將while修飾的表達式的返回值設為那個參數(shù)的值。

until

例:

until f.eof?
  print f.gets
end

語法:

until 表達式 [do]
   ...
end

在表達式的計算值變?yōu)檎嬷?,一直循環(huán)執(zhí)行until中的內容。until不返回值。

ruby 1.7 特性: until 返回 nil。另外,可以使用帶參數(shù)的break,將until表達式的返回值設定為那個參數(shù)的值。

until修飾句

例:

print(f.gets) until f.eof?

語法:

表達式 until 表達式

在右邊表達式的計算值變?yōu)檎嬷埃恢毖h(huán)執(zhí)行左邊部分。

若左邊表達式是begin,且即不含rescue,又不含ensure的話,則只在開始時計算一次然后就執(zhí)行循環(huán)。

ruby 1.7 特性: 在version 1.7中,即使出現(xiàn)rescue/ensure部分也會作相同處理

例:

send_request(data)
begin
  res = get_response()
end until res == 'OK'

until修飾的表達式?jīng)]有返回值。

ruby 1.7 特性: until修飾的表達式返回nil。另外,可以使用帶參數(shù)的break,將until修飾的表達式的返回值設為那個參數(shù)的值。

for

例:

for i in [1, 2, 3]
  print i*2, "\n"
end

語法:

for lhs ...  in 表達式 [do]
  表達式..
end

先計算表達式得到一個對象,然后分別針對該對象中的每個要素,循環(huán)執(zhí)行for的內容。這基本等價于

(表達式).each `{' `|' lhs..`|' 表達式.. `}'

之所以說“基本”是因為,do...end以及由{}構成的塊中導入了新的局部變量的有效范圍,而for語句對于局部變量的有效范圍沒有任何影響。

for將返回in所指對象的each方法的返回值。

若想使用多個循環(huán)變量的話,可以這樣

for i,j in [[1,2], [3,4], [5,6]]
  p [i,j]
end
=> [1, 2]
   [3, 4]
   [5, 6]

使用for或each時,每次只能取一個數(shù)組元素進行循環(huán),而不能一次取多個。

for i,j in [1, 2, 3]
  p [i,j]
end

=> [1, nil]
   [2, nil]
   [3, nil]

# 可能您希望這樣[1,2] [3,nil],但實際上這是行不通的

您必須自己定義這樣的方法(迭代器)。請參考 each。

class Array
  def each2
    i = 0
    while i < self.size
      yield self[i], self[i+1]
      i += 2
    end
  end
end

break

例:

i = 0
while i < 3
  print i, "\n"
  break
end

語法:

break

break val             ruby 1.7 特性

break將退出最內層的循環(huán)。所謂循環(huán)是指,下列之一

  • while
  • until
  • for
  • 迭代

與C語言不同,break只能從循環(huán)中退出,而不能從case中退出。

若使用break退出for或迭代循環(huán)后,該循環(huán)將返回nil。ruby 1.7 特性:但如果使用了參數(shù)的話,循環(huán)將返回那個參數(shù)的值。

next

例:

# 忽略空行的cat
ARGF.each_line do |line|
  next if line.strip.empty?
  print line
end

語法:

next

next val              ruby 1.7 特性

next將跳轉到最內側循環(huán)的頭部。在迭代器中,它將跳離yield調用。

使用next跳離yield后,yield表達式將返回nil。ruby 1.7 特性:但如果使用了參數(shù)的話,yield表達式的返回值就是該參數(shù)的值。

redo

例:

redo

語法:

redo

不檢查循環(huán)條件,重新開始當前循環(huán)。

retry

例:

retry

語法:

retry

在迭代、塊或for語句中使用retry,意味著重啟迭代器。同時迭代器的參數(shù)也將被重新計算。

for i in 1..5
  retry if some_condition # 從 i == 1 開始重新執(zhí)行
end

# 用戶定義的 "until循環(huán)"
def UNTIL(cond)
  return if cond
  yield
  retry
end

除了循環(huán)以外,還可以在rescue部分(后述)中使用retry。這時將從begin表達式開始重新執(zhí)行。使用retry可以在某處理過程成功之前,一直循環(huán)該處理過程。

begin
  do_something # exception raised
rescue
  # handles error
  retry  # restart from beginning
end

若在rescue部分、迭代器塊或for語句之外使用retry的話會引發(fā)LocalJumpError異常。

歸納一下,在迭代調用中使用break, next, redo, retry的作用如下。

def iter
 (a)
  :
 (b)
 yield
 (c)
  :
 (d)
end
iter { retry }   -> 跳到 (a)
iter { redo  }   -> 跳到 (b)
iter { next  }   -> 跳到 (c)
iter { break }   -> 跳到 (d)

嚴格地講(a)是從計算參數(shù)開始的。(b)指的是即將開始執(zhí)行塊的時候(yield的參數(shù)不會被再次計算)。(d)指的是方法的終結。

def iter(var = p("(a)"))
  p " : "
  yield
  p "(c)"
  p " : "
ensure
  p "(d)"
end

iter { p "(b)"; retry }     # => (a) .. (b)(d)(a) .. (b)(d)(a) ...
iter { p "(b)"; redo  }     # => (a) .. (b)(b)(b)(b) ...
iter { p "(b)"; next  }     # => (a) .. (b)(c) .. (d)
iter { p "(b)"; break }     # => (a)..(b)(d)

異常處理

raise

例:

raise "you lose"  # 引發(fā)RuntimeError異常
# 下面兩個將引發(fā)SyntaxError異常
raise SyntaxError, "invalid syntax"
raise SyntaxError.new("invalid syntax")
raise             # 再次引發(fā)上一個異常

語法:

raise
raise message或exception
raise error_type, message
raise error_type, message, traceback

引發(fā)異常。第一句將再次引發(fā)上一個異常。第二句中,若參數(shù)是字符串的話,就把它當作錯誤信息(message)再引發(fā)RuntimeError異常。若參數(shù)為異常對象則引發(fā)該異常。第三句中,將引發(fā)第一個參數(shù)所指的異常,并以第二個參數(shù)的內容作為錯誤信息。第四句中,第三參數(shù)裝載的是源自于$@caller的堆棧信息,它指明發(fā)生異常的地點。

可以使用begin表達式的rescue部分來捕捉異常。這時使用rescue error_type => var就可以得到異常對象。您還可以從內部變量$!中獲得這個對象。另外,變量$@中裝載的是發(fā)生異常的源代碼位置。

raise并不是Ruby的保留字,它是Kernel模塊中定義的函數(shù)式的方法。

begin

例:

begin
  do_something
rescue
  recover
ensure
  must_to_do
end

語法:

begin
  表達式..
[rescue [error_type,..] [=> evar] [then]
  表達式..]..
[else
  表達式..]
[ensure
  表達式..]
end

若給出了rescue部分(可以有若干個)的話,就可以在發(fā)生異常時捕捉到它。若存在與異常類型一致的rescue部分的話,就執(zhí)行rescue的內容??梢允褂?font color="blue">$!來查看異常的情況。另外,若事先設定了變量evar的話,它也可以像$!一樣存儲那些異常的信息。

begin
  raise "error message"
rescue => evar
  p $!
  p evar
end
# => #<RuntimeError: error message>
     #<RuntimeError: error message>

rescue部分使用Object#kind of?來判斷剛才的異常的類是否就是自己期待的異常類,或者這二者是否處于父類/子類的關系。

error_type被省略,則將捕捉StandardError的子類中的所有異常。Ruby的內部異常(除了SystemExitInterrupt這些退出命令以外)是StandardError的子類。

請參考異常類來了解異常類的層次關系。

rescue部分中,error_type與普通的參數(shù)一樣接受計算,若符合的話就執(zhí)行相應部分的內容。若error_type的計算值既非類又非模塊的話,則引發(fā)TypeError異常。

若運行過程中沒發(fā)生異常,則開始計算可選的else部分。

若存在ensure部分的話,則在begin表達式結束之前一定會計算它。

begin表達式整體的計算值取決于,begin的內容部分/rescue部分/else部分中最后被計算的句子的值。若各部分中均無語句時,其值為nil。不管怎樣,ensure部分的值始終會被忽略。

rescue修飾句

例:

open("nonexistent file") rescue STDERR.puts "Warning: #$!"

語法:

表達式1 rescue 表達式2

若表達式1中發(fā)生異常時就計算表達式2。這等同于下例。不能指定想捕捉的異常類。(也就是說,只能捕捉StandardError異常類的子類了)

begin
  表達式1
rescue
  表達式2
end

在包括rescue修飾句的表達式中,若沒發(fā)生異常則返回表達式1的值,若發(fā)生異常則返回表達式2的值。但在大多數(shù)場合中,因為考慮到優(yōu)先度的問題,所以需要使用括號將整個表達式括起來。

var = open("nonexistent file") rescue false
p var
=> nil      # 因為只定義了一個空變量var

var = (open("nonexistent file") rescue false)
p var
=> false

特別是傳遞給某方法的參數(shù)時,有必要使用雙重括號。

p(open("nonexistent file") rescue false)
=> parse error

p((open("nonexistent file") rescue false))
=> false

ruby 1.7 特性: 在1.7中,rescue的優(yōu)先度發(fā)生了變化,因此免去了這些煩惱。

var = open("nonexistent file") rescue false
p var
=> false

p(open("nonexistent file") rescue false)
=> false

其他

return

例:

return
return 12
return 1,2,3

語法:

return [表達式[`,' 表達式 ... ]]

結束方法的運行,且把表達式的值設定為方法的返回值。若給出了2個以上的表達式,則將把這些表達式化為一個數(shù)組,然后把該數(shù)組設定為方法的返回值。若省略表達式,將返回值設為nil。

BEGIN

例:

BEGIN {
   ...
}

語法:

BEGIN '{' 語句.. '}'

注冊初始化例程(routine)。BEGIN塊所指定的語句的執(zhí)行順序將先于該文件中任何語句。若有多個BEGIN塊的話,將按照出現(xiàn)順序依次執(zhí)行。

BEGIN塊在編譯時被注冊。也就是說,同一條語句只會被注冊一次。

if false
  BEGIN { p "begin" }
end

# => "begin"

BEGIN塊引入了獨立的局部變量作用域,因此不能和外部共享局部變量。為了與塊外交換信息,必須借助于常數(shù)或全局變量。

BEGIN { $foo, foo = true, true }
p $foo  # => true
p foo   # undefined local variable or method `foo' for main:Object (NameError)

BEGIN不能出現(xiàn)在方法定義表達式中,否則會引發(fā) parse error。

def foo
  BEGIN { p "begin" }
end
# => -:2: BEGIN in method

END

例:

END {
   ... 
}

語法:

END '{' 語句.. '}'

注冊“善后”例程。END塊中指定的語句會在解釋器結束前得到執(zhí)行。關于Ruby退出程序時的相關處理問題,請參考結束時的相關處理。

若注冊了若干END塊的話,則以與注冊時相反的順序依次執(zhí)行這些塊。

END { p 1 }
END { p 2 }
END { p 3 }

# => 3
     2
     1

END塊中同一條語句只會執(zhí)行一次。如下例,即使把END塊置入循環(huán)中,也只會注冊一次。若想實現(xiàn)復用,請使用 at_exit。

5.times do |i|
  END { p i }
end
# => 0

若把END塊置入方法定義表達式中會引起警告。若有意如此,請使用at_exit。

def foo
  END { p "end" }
end
p foo

# => -:2: warning: END in method; use at_exit
     nil
     "end"

END與BEGIN不同的是,它在運行時進行注冊。因此,下例中的END塊將不會運行。

if false
  END { p "end" }
end

END和at_exit中注冊的善后處理無法取消。

END塊與BEGIN塊不同的是,它同周圍部分共享作用域。也就是說,它的作用域同迭代器一樣。

若END塊中發(fā)生了異常,將中斷該塊。但解釋器并不結束,只是發(fā)出信息,并且試圖處理完所有的善后例程。

例:

END { p "FOO" }
END { raise "bar"; p "BAR" }
END { raise "baz"; p "BAZ" }

=> baz (RuntimeError)
   bar (RuntimeError)
   "FOO"

Previous article: Next article: