?
このドキュメントでは、 php中國語ネットマニュアル リリース
例:
foo.bar() foo.bar bar() print "hello world\n" print Class::new
語法:
[表達(dá)式 `.'] 標(biāo)識(shí)符 [`(' 表達(dá)式 ... [`*' [表達(dá)式]],[`&' 表達(dá)式] `)'] [表達(dá)式 `::'] 標(biāo)識(shí)符 [`(' 表達(dá)式 ... [`*' [表達(dá)式]],[`&' 表達(dá)式] `)']
方法調(diào)用表達(dá)式表示調(diào)用被調(diào)(receiver,"."左側(cè)表達(dá)式的值)的方法。若未指定被調(diào),則調(diào)用self的方法。
"."與"::"的意義大體相同。但表示常數(shù)時(shí),必須使用"::"(例:Math::PI,Errno::ERANGE)。若寫成
Klass::Foo
的話,通常會(huì)被認(rèn)為是常數(shù)。請(qǐng)注意,通常是將"::"用作類方法的調(diào)用。若方法名是以大寫字母開始的時(shí)候,要寫成
Klass.Foo
或者寫成
Klass::Foo()
但要用括號(hào)顯式地表明這是方法調(diào)用。
方法名中除了通常的標(biāo)識(shí)符以外,還可以添加"?"或"!"等后綴。通常在布爾型(返回真或偽的方法)方法名后添加"?",在比同名(無"!")方法更具破壞性的方法名(例:tr和tr!)后添加"!"。
若最后一個(gè)參數(shù)帶"*"的話,將會(huì)先展開該參數(shù)的值,然后才傳遞。也就是:
foo(1,*[2,3,4]) foo(1,*[])
和下例
foo(1,2,3,4) foo(1)
等效。
若最后一個(gè)參數(shù)帶"&",則該參數(shù)指定的過程對(duì)象(Proc)以及方法對(duì)象(Method)等會(huì)被當(dāng)作一個(gè)塊傳遞給方法。詳情請(qǐng)參考迭代器。
方法調(diào)用時(shí),private方法只能用函數(shù)形式(省略被調(diào)的形式)來調(diào)用。而protected方法只能在擁有該方法的對(duì)象的方法定義表達(dá)式內(nèi)進(jìn)行調(diào)用。(請(qǐng)參考方法調(diào)用的限制)
例:
super super(1,2,3)
語法:
super super(表達(dá)式, ... )
super將調(diào)用被當(dāng)前方法覆蓋的父類中的同名方法。若省略括號(hào)和參數(shù)時(shí),將會(huì)把當(dāng)前方法的參數(shù)原封不動(dòng)地傳遞給父類中的同名方法。若調(diào)用時(shí)不想使用參數(shù)的話,請(qǐng)使用括號(hào)顯式地標(biāo)出,像super()這樣。
例:
class Foo def foo(arg=nil) p arg end end class Bar < Foo def foo(arg) super(5) # 以5作為參數(shù)進(jìn)行調(diào)用 super(arg) # 以5作為參數(shù)進(jìn)行調(diào)用 super # 以5作為參數(shù)進(jìn)行調(diào)用,super(arg)的簡寫 arg = 1 super # 以1作為參數(shù)進(jìn)行調(diào)用,super(arg)的簡寫 super() # 無參數(shù)的調(diào)用 end end Bar.new.foo 5
例:
[1,2,3].each do |i| print i*2, "\n" end [1,2,3].each {|i| print i*2, "\n" }
語法:
method(arg1, arg2, ...) do [`|' 表達(dá)式 ... `|'] 表達(dá)式 ... end method(arg1, arg2, ...) `{' [`|' 表達(dá)式 ... `|'] 表達(dá)式 ... `}' method(arg1, arg2, ..., `&' proc_object)
所謂帶塊的方法是指,為了對(duì)控制結(jié)構(gòu)進(jìn)行抽象化而設(shè)計(jì)的方法。最初常用于對(duì)循環(huán)進(jìn)行抽象化,所以有時(shí)也叫迭代器。將do...end或{...}中的代碼片段(也就是塊)添加在方法后面,然后再調(diào)用該方法時(shí),就能從該方法內(nèi)部對(duì)快進(jìn)行計(jì)算。在帶塊的方法內(nèi)進(jìn)行塊調(diào)用時(shí)使用 yield 表達(dá)式。傳給yield的值會(huì)被賦值給夾在"||"中的變量。
{...}比do...end塊的結(jié)合能力強(qiáng)。例如:
foobar a, b do .. end # foobar 是帶塊的方法 foobar a, b { .. } # b 成了帶塊的方法
塊中首次被賦值(聲明)的局部變量的作用域僅限于該塊。例如:
foobar { i = 20 # 聲明了局部變量i ... } print defined? i # 此處的i尚未定義,false foobar a, b do i = 11 # 聲明了一個(gè)新變量i ... end
如下所示,在塊外仍然有效。
i = 10 [1,2,3].each do |m| p i * m # 馬上就能使用i end
還可以把過程對(duì)象( Proc )當(dāng)作塊傳遞給帶塊的方法。這時(shí)要在過程對(duì)象名前面添加"&",并把該過程對(duì)象傳遞給帶塊的方法的最后一個(gè)參數(shù)。除了過程對(duì)象以外,還可以傳遞方法對(duì)象( Method )。這時(shí)將生成一個(gè)調(diào)用該方法的過程對(duì)象,然后把這個(gè)過程對(duì)象傳給帶塊的方法。
pobj = proc {|v| p v } [1,2,3].each(&pobj) => 1 2 3
ruby 1.7 特性: 在version 1.7中,若該對(duì)象自帶to_proc方法的話,就可以把它當(dāng)作帶"&"的參數(shù)傳給帶塊方法(默認(rèn)狀態(tài)下,Proc、Method對(duì)象都有to_proc方法)。方法調(diào)用時(shí)會(huì)執(zhí)行to_proc,它將返回Proc對(duì)象。
class Foo def to_proc Proc.new {|v| p v} end end [1,2,3].each(&Foo.new) => 1 2 3
帶塊方法的返回值與通常的方法是一樣的。若塊中的 break 引起中斷時(shí),將返回nil。 ruby 1.7 特性 :若break帶參數(shù)的話,該參數(shù)的值就是帶塊方法的返回值。
例:
yield data
語法:
yield `(' [表達(dá)式 [`,' 表達(dá)式 ... ]] `)' yield [表達(dá)式 [`,' 表達(dá)式 ... ]]
把參數(shù)傳給塊之后,對(duì)塊進(jìn)行計(jì)算。因?yàn)閥ield定義迭代器,所以是在方法定義內(nèi)使用。
def foo yield(1,2) end foo {|a,b| p [a,b]}
對(duì)塊參數(shù)進(jìn)行賦值時(shí)遵從多重賦值規(guī)律。若執(zhí)行yield時(shí),方法并沒有帶塊(不是迭代器)的話,就會(huì)引發(fā) LocalJumpError 異常。
yield將會(huì)返回塊內(nèi)最后被計(jì)算的表達(dá)式的值。若因 next 引起塊的運(yùn)行中斷的話,返回nil。
ruby 1.7 特性 :若next帶參數(shù)的話,該參數(shù)的值就是yield的返回值。
ruby 1.8 特性 :關(guān)于塊參數(shù)的交付問題,以后可能會(huì)對(duì)下述內(nèi)容進(jìn)行變更(會(huì)發(fā)出警告)。
def foo yield 1,2,3 end foo {|v| p v} # => -:5: warning: multiple values for a block parameter (3 for 1) [1, 2, 3]
應(yīng)該寫成
yield [1,2,3]
或者
foo {|*v| p v}
這樣才對(duì)。雖然現(xiàn)在使用
v = 1,2,3
這樣的多重賦值還不會(huì)有警告,但最好不要使用。