正如我們?cè)谏弦黄恼轮锌吹降哪菢硬柘h(huán)和迭代允許我們一遍遍地重復(fù)做相同的事情占卧。但在現(xiàn)實(shí)中有時(shí)我們想在程序中其他地方重復(fù)做同樣的事情。比如說(shuō)我們?cè)趯?xiě)一個(gè)面向心理專(zhuān)業(yè)學(xué)生所做的調(diào)查問(wèn)卷,而我這里已經(jīng)有一份他們提供給我的調(diào)查問(wèn)卷纹蝴,類(lèi)似下面這樣:
puts 'Hello, and thank you for taking the time to'
puts 'help me with this experiment. My experiment'
puts 'has to do with the way people feel about'
puts 'Mexican food. Just think about Mexican food'
puts 'and try to answer every question honestly,'
puts 'with either a "yes" or a "no". My experiment'
puts 'has nothing to do with bed-wetting.'
puts
# We ask these questions, but we ignore their answers.
goodAnswer = false
while (not goodAnswer)
puts 'Do you like eating tacos?'
answer = gets.chomp.downcase
if (answer == 'yes' or answer == 'no')
goodAnswer = true
else
puts 'Please answer "yes" or "no".'
end
end
goodAnswer = false
while (not goodAnswer)
puts 'Do you like eating burritos?'
answer = gets.chomp.downcase
if (answer == 'yes' or answer == 'no')
goodAnswer = true
else
puts 'Please answer "yes" or "no".'
end
end
# We pay attention to *this* answer, though.
goodAnswer = false
while (not goodAnswer)
puts 'Do you wet the bed?'
answer = gets.chomp.downcase
if (answer == 'yes' or answer == 'no')
goodAnswer = true
if answer == 'yes'
wetsBed = true
else
wetsBed = false
end
else
puts 'Please answer "yes" or "no".'
end
end
goodAnswer = false
while (not goodAnswer)
puts 'Do you like eating chimichangas?'
answer = gets.chomp.downcase
if (answer == 'yes' or answer == 'no')
goodAnswer = true
else
puts 'Please answer "yes" or "no".'
end
end
puts 'Just a few more questions...'
goodAnswer = false
while (not goodAnswer)
puts 'Do you like eating sopapillas?'
answer = gets.chomp.downcase
if (answer == 'yes' or answer == 'no')
goodAnswer = true
else
puts 'Please answer "yes" or "no".'
end
end
# Ask lots of other questions about Mexican food.
puts
puts 'DEBRIEFING:'
puts 'Thank you for taking the time to help with'
puts 'this experiment. In fact, this experiment'
puts 'has nothing to do with Mexican food. It is'
puts 'an experiment about bed-wetting. The Mexican'
puts 'food was just there to catch you off guard'
puts 'in the hopes that you would answer more'
puts 'honestly. Thanks again.'
puts
puts wetsBed
上面的程序有些太長(zhǎng),許多代碼都是重復(fù)的(圍繞著食物問(wèn)題的代碼是一樣的踪少,只有在尿床的部分有些許不同)塘安。代碼重復(fù)總是件不好的事,但我們又沒(méi)法將它們寫(xiě)成一個(gè)大的循環(huán)或迭代中去援奢,因?yàn)槲覀兺ǔ?huì)在問(wèn)題中間做點(diǎn)其他事情兼犯。鑒于這種情況我們就很有必要寫(xiě)一個(gè)方法,比如下面這種:
def sayMoo
puts 'mooooooo...'
end
但運(yùn)行后程序沒(méi)有輸出sayMoo
。這是為什么免都?因?yàn)槲覀冞€沒(méi)有告訴它去輸出(我們只是告訴程序如何做锉罐,但還沒(méi)指示程序去做)。讓我們?cè)賮?lái)試驗(yàn)一下:
mooooooo...
mooooooo...
coin-coin
mooooooo...
mooooooo...
嗯绕娘,成功運(yùn)行脓规。(考慮到你們可能不太了解法語(yǔ),在程序中有一個(gè)法國(guó)的鴨子险领,因?yàn)樵诜▏?guó)鴨子的叫聲就是coin-coin
)
在上面的程序中我們就成功定義(define
)了sayMoo
的方法(方法的名字類(lèi)似變量命名方式侨舆,以小寫(xiě)字母開(kāi)頭,但也有少數(shù)以+或==開(kāi)頭的例外)绢陌。但是難道方法不是通常要與對(duì)象一起用的嗎挨下?好吧,的確需要這樣用脐湾,但上面的例子有些類(lèi)似pus
和gets
臭笆,方法是以整個(gè)程序?yàn)閷?duì)象的,在下個(gè)章節(jié)中我們將會(huì)看到如何將方法與其他對(duì)象一起用上秤掌,但是我們要首先學(xué)習(xí)…
方法中參數(shù)的使用
你可能已經(jīng)注意到類(lèi)似gets``to_s``reverse
等方法可以直接向?qū)ο筮M(jìn)行調(diào)用愁铺,但類(lèi)似+``-``puts
等需要參數(shù)才能告訴對(duì)象如何使用這種方法。比如你不能僅僅用5+
,是吧闻鉴?你只是在告訴對(duì)象5
去執(zhí)行加法茵乱,但沒(méi)告訴它增加多少……
為了給sayMoo
增加參數(shù)(比如叫聲的數(shù)量),可以這樣做:
def sayMoo numberOfMoos
puts 'mooooooo...'*numberOfMoos
end
sayMoo 3
puts 'oink-oink'
sayMoo # This should give an error because the parameter is missing.
運(yùn)行結(jié)果是:
mooooooo...mooooooo...mooooooo...
oink-oink
#<ArgumentError: wrong number of arguments (0 for 1)>
numberOfMoos
是一個(gè)指向參數(shù)的變量:如果我鍵入的是sayMoo 3
孟岛,那么參數(shù)是3瓶竭,變量numberOfMoos
是指向3的。
正如你所看到的:上面的程序中參數(shù)就是必須要提供的渠羞,別忘了如果你不提供參數(shù)斤贰,sayMoo
要用什么去乘以'mooooooo...' ?你笨笨的電腦是有點(diǎn)懵逼的。
如果我們把Ruby中的對(duì)象比作英語(yǔ)中的名詞堵未,把Ruby中的方法比作動(dòng)詞腋舌,那么你可以把參數(shù)對(duì)應(yīng)于英語(yǔ)中的副詞(好比sayMoo,參數(shù)是教我們?nèi)绾蝧ayMoo)或某些情況下類(lèi)似直接賓語(yǔ)(好比puts中的參數(shù)就是應(yīng)該輸出的相應(yīng)內(nèi)容)渗蟹。
局部變量
在下面的代碼中有兩個(gè)變量:
輸出結(jié)果是:
44 doubled is 88
兩個(gè)變量分別是
num
和numTime2
块饺,它們都在我們定義的方法doubleThis
中。類(lèi)似之前你看到的所有變量都稱作局部變量雌芽,因?yàn)檫@些變量只能在方法內(nèi)部使用授艰,在外部使用的話就會(huì)提示錯(cuò)誤:
def doubleThis num
numTimes2 = num*2
puts num.to_s+' doubled is '+numTimes2.to_s
end
doubleThis 44
puts numTimes2.to_s
輸出就會(huì)提示有錯(cuò)誤:
44 doubled is 88
def_double.rb:7:in `<main>': undefined local variable or method `numTimes2' for main:Object (NameError)
提示中的undefined local variable…事實(shí)上我們的確定義了numTime2
變量,但它沒(méi)有位于我們想使用的地方世落,而只位于我們定義的方法中淮腾。
輸出為:
HAHA! I ruined your variable!
You can't even touch my variable!
在上面程序中有兩個(gè)名字均為var
的變量:一個(gè)在方法littlePest
中,另一個(gè)則在方法外面圆凰。當(dāng)我們用命令littlePest var
時(shí)候杈帐,僅僅是字符串的傳遞,都指向同一個(gè)字符串专钉。littlePest
方法中將局部變量var
指向nil
挑童,但對(duì)方法外部的另一個(gè)同樣的變量var
無(wú)任何影響。