鷹翔宇空

          學(xué)習(xí)和生活

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks

          引自:

          原 名:Brian’s Guide to Solving Any Perl Problem
          中 文: Brian 的 Perl 問(wèn)題之萬(wàn)能指南
          作 者:brian d foy
          原 文:
          http://www.panix.com/~comdog/brian's_guide.html
          發(fā) 表:2004 七 月 20 日
          翻 譯:klaus
          審 校:qiang
          出 處:中國(guó) Perl協(xié)會(huì) FPC - PerlChina.org

          標(biāo)題 brian的Perl問(wèn)題之萬(wàn)能指南

          綱要 閱讀這份指南并保持明智的頭腦

          描述 我的調(diào)試哲學(xué)
          我相信三件事情:

          這不是個(gè)人問(wèn)題

          別老想著是你的代碼。你可能覺得自己是個(gè)藝術(shù)家,但實(shí)際上就算是經(jīng)驗(yàn)豐富的大師也會(huì)寫出很多垃圾。每個(gè)人的代碼都是垃圾,我的也是你的也是。要學(xué)著去喜歡它。當(dāng)你碰到問(wèn)題的時(shí)候,你應(yīng)該想:“噢,我寫的垃圾代碼出了點(diǎn)問(wèn)題?!边@說(shuō)明你不再去責(zé)怪 Perl。不應(yīng)該變成個(gè)人性的問(wèn)題。

          忘記你以前怎么做的。如果不是你做事的方法有點(diǎn)問(wèn)題,你也不會(huì)來(lái)讀這個(gè)。這并不是壞事,只是到了該有點(diǎn)長(zhǎng)進(jìn)的時(shí)間。我們都經(jīng)歷過(guò)的。

          個(gè)人責(zé)任感

          如果你的代碼出了問(wèn)題那僅僅是——你的問(wèn)題。你應(yīng)該盡最大的力量自己解決。記住,每個(gè)人都有自己的代碼,每個(gè)人都有自己的問(wèn)題。自己的作業(yè)自己做,在麻煩別人之前先盡自己最大的努力。如果你老老實(shí)實(shí)地按照這個(gè)指南做了所有能做的事之后,依然不能解決問(wèn)題,那么你已經(jīng)盡力了,應(yīng)該找別人來(lái)看看。

          改變你做事的方法

          改正之后不要再犯同樣的錯(cuò)誤。很可能是你寫代碼的方法錯(cuò)了,而不是你寫的代碼錯(cuò)了。改變你以前做事的方法,讓生活更容易些。不要指望Perl來(lái)習(xí)慣你,因?yàn)檫@是不可能的。你要習(xí)慣 Perl。它只是種語(yǔ)言,而不是種生活方式。

          我的方法: 你用strictures編譯代碼嗎?

          如果你不用 strictures,請(qǐng)把它打開。Perl 高手們之所以是高手,因?yàn)樗麄兪褂脟?yán)格模式,使得他們有更多的時(shí)間解決其他問(wèn)題,學(xué)新的東西,以及上載模塊倒 CPAN。

          你可以使用 strict pragma 在代碼中打開 strictures

          use strict;
          

          也可以用perl的 -M開關(guān)在命令行中打開它:
          perl -Mstrict script.pl
          

          你可能會(huì)被它搞怒,但是堅(jiān)持用上它幾個(gè)禮拜之后,你會(huì)寫出更好的代碼,花更少的時(shí)間來(lái)檢查低級(jí)錯(cuò)誤,而且可能就不再需要讀這個(gè)指南了。

          什么是warning?

          Perl 會(huì)對(duì)一些有問(wèn)題的結(jié)構(gòu)給你警告提示。把 warning 打開,讓 Perl 來(lái)幫你。
          你可以在第一行用 perl的 -w 開關(guān)打開它:

          #!/usr/bin/perl -w
          

          也可以在命令行打開warning:
          perl -w script.pl
          

          你也可以使用詞匯警告,它帶有許多有趣的特性。更多的信息參看warnings 的幫助文檔。
          use warnings;
          

          如果你不明白某個(gè)警告的意思,你可以使用 warning 的詳細(xì)模式,或者在你的代碼中使用診斷 pragma:
          use diagnostics;
          

          解決第一個(gè)問(wèn)題先!

          你從 Perl 中得到警告或者錯(cuò)誤信息之后,先解決第一個(gè),然后看Perl是否依舊報(bào)出其他錯(cuò)誤。因?yàn)楹罄m(xù)的錯(cuò)誤很可能是由于第一個(gè)錯(cuò)誤衍生而來(lái)的。

          檢查錯(cuò)誤信息行號(hào)之前的代碼!

          Perl 在錯(cuò)誤已經(jīng)發(fā)生的時(shí)候才報(bào)錯(cuò),而不是在此之前。因此當(dāng) Perl 報(bào)出行號(hào)時(shí)錯(cuò)誤已經(jīng)發(fā)生了,而出錯(cuò)的地方是在這之前??纯村e(cuò)誤行號(hào)之前的代碼和表達(dá)式是否有問(wèn)題。

          那個(gè)變量值是你想的那樣嗎?

          不要亂猜!在表達(dá)式中使用某個(gè)值的時(shí)候先檢查它是否正確。世界上最好的調(diào)試器就是 print。

          print STDERR "The value is [$value]\n";
          

          我用括號(hào)括住 $value 的原因是因?yàn)檫@樣我可以看見開頭和尾巴上是否有空格或者換行。

          如果這個(gè)值不是標(biāo)量,那么我使用 Data::Dumper 來(lái)打印這些數(shù)據(jù)結(jié)構(gòu)。

          require Data::Dumper;
          print STDERR "The hash is ", Data::Dumper::Dumper( %hash ), "\n";
          

          如果打印出來(lái)的結(jié)果不是你所期望的,那么移到前面幾句,再來(lái)!找到這個(gè)值最后正確的位置。也可以用 perl -d 開關(guān)打開內(nèi)建的 Perl 調(diào)試器。更多信息請(qǐng)參考perldebug。

          perl -d script.pl
          

          你也可以使用其他調(diào)試器或者開發(fā)環(huán)境,想 ptkdb(一個(gè)基于Tk的圖形調(diào)試器)或者是 Komodo( Active States 基于 Mozilla 的 Perl IDE

          你用的函數(shù)是正確的嗎?

          我寫 perl 程序的時(shí)間已經(jīng)不短了,可我還是幾乎每天都要查 perlfunc。有些東西我就是吃不準(zhǔn),而有時(shí)候我太缺乏睡眠了以至于沒(méi)了常識(shí),然后總搞不懂為什么 sprintf() 不打印到屏幕上。

          你可以用perldoc命令和它的-f開關(guān)來(lái)查詢某個(gè)特定的函數(shù)。

          perldoc -f function_name
          

          如果你在使用一個(gè)模塊,查詢它的文檔,看看你是不是在用正確的方式使用它。你可以用 perldoc 查詢它的文檔。

          perldoc Module::Name
          

          你用的特殊變量是正確的嗎?

          同樣,我經(jīng)常去查 perlvar。不過(guò),當(dāng)我發(fā)現(xiàn) Perl 快速參考這本書(The Perl Pocket Reference)更加方便之后,我就很少查perlvar了。

          你用模塊版本正確嗎?

          有些模塊在升級(jí)版本的時(shí)候會(huì)有不少改變。你知道你用的模塊是什么版本嗎?你可以用一個(gè)一行的 perl 語(yǔ)句檢查你的模塊版本:

          perl -MModule::Name -le 'print Module::Name->VERSION';

          如果你讀的文檔不是你機(jī)器上的本地文檔,而是像 http://www.perldoc.com或者http://search.cpan.org 上的,那你就比較有可能碰到文檔版本差異的問(wèn)題。

          你用小腳本測(cè)試過(guò)了嗎?

          如果你在嘗試新的東西,或者覺得某一小段代碼很奇怪,你可以寫一個(gè)最短的程序運(yùn)行一下這一個(gè)片斷。這個(gè)方法把所有其他的因素都排除在外。如果測(cè)試沒(méi)有問(wèn)題,那說(shuō)明問(wèn)題可能不在這段代碼里面。如果測(cè)試結(jié)果不對(duì),那你大概就找到了你的問(wèn)題所在。

          你檢查環(huán)境了嗎?

          有些東西是依賴環(huán)境變量的。你確定你的環(huán)境變量都是對(duì)的嗎?程序運(yùn)行的時(shí)候用到的環(huán)境變量是你現(xiàn)在看到的環(huán)境變量嗎?記住有些 CGI 程序或cron 可能用到的環(huán)境變量和 shell 里的不一樣,尤其是在不同的機(jī)器上的時(shí)候。

          Perl 講環(huán)境變量存儲(chǔ)在 %ENV 里 。如果你需要某個(gè)環(huán)境變量,就算是在測(cè)試的時(shí)候,也記住先提供一個(gè)默認(rèn)值,如果它原來(lái)不存在的話。

          如果還有問(wèn)題,查看你的環(huán)境。

          require Data::Dumper;
          print STDERR Data::Dumper::Dumper( \%ENV );
          

          你試過(guò)Google了嗎?

          其他人也許碰到過(guò)和你同樣的問(wèn)題。用 Google Groups(http://groups.google.com)搜索看看是不是有人在 comp.lang.perl.misc 上發(fā)過(guò)類似帖子, 沒(méi)準(zhǔn)還能發(fā)現(xiàn)其他人給出的解決方法。在新聞組里問(wèn)問(wèn)題的人和回答問(wèn)題的人的差別在于,他們使用Google Groups 的能力高底不同。

          你對(duì)程序做過(guò)性能測(cè)試嗎?

          如果你想知道是哪些部分讓你的程序變慢,試過(guò)性能測(cè)試嗎?可以讓Devel::Small Prof? 幫你做這件事。它可以計(jì)算 perl 執(zhí)行每一行代碼的次數(shù)和花費(fèi)的時(shí)間,然后打印一份漂亮的報(bào)告。

          到底是那個(gè)測(cè)試沒(méi)通過(guò)?

          如果你有一套測(cè)試,到底是哪個(gè)測(cè)試失敗了呢?你可以很容易的找到錯(cuò)誤所在,因?yàn)槊總€(gè)小測(cè)試只執(zhí)行一小段代碼。

          如果你沒(méi)有,為什么不寫一個(gè)呢?如果你的代碼很短很短,或者只是一個(gè)一次性的程序,那我不會(huì)建議你專門寫一套測(cè)試出來(lái)。但如果不是這樣的情況,那寫一些測(cè)試代碼是很有幫助的。Test::Harness讓這件事變得太容易了,以至于你都找不到理由不做。如果你說(shuō)你沒(méi)時(shí)間,那大概是因?yàn)槟悴挥脺y(cè)試而在腳本除錯(cuò)上浪費(fèi)了太多時(shí)間。

          你和小熊說(shuō)話了嗎?

          把你的問(wèn)題大聲說(shuō)出來(lái)。把它變成語(yǔ)言。有幾年我很愉快地和一個(gè)很優(yōu)秀的程序員一起工作,他幾乎能解決任何問(wèn)題。當(dāng)我被什么問(wèn)題堵住的時(shí)候,我總?cè)フ?qǐng)教他,跟他解釋我的問(wèn)題。幾乎每次都是這樣的情況:我說(shuō)不到第三句,就停下來(lái),說(shuō):“噢我明白了,沒(méi)問(wèn)題了?!彼看我捕际沁@樣。

          你可能需要做太多次這樣的事情,所以我推薦拿一個(gè)長(zhǎng)毛絨玩具做為你的Perl 臨床診斷家,這樣你就不會(huì)惹怒你的同事了。我的桌子旁邊就有一只小熊,我每次都把我的問(wèn)題解釋給他聽。每次當(dāng)我自言自語(yǔ)的時(shí)候,我女朋友跟本都不會(huì)注意,她習(xí)慣了。

          這問(wèn)題在紙上看起來(lái)有點(diǎn)不一樣了嗎?

          因?yàn)槟憷鲜强粗娔X屏幕,所以說(shuō)不定一種新的媒介可以讓你從新的角度看這個(gè)問(wèn)題。把程序打印到紙上試試看。

          你看 Jon Stewart 的節(jié)目嗎?

          說(shuō)真的。可能你不太喜歡 Jon Stewart,那換一個(gè)其他的。休息一下,停一會(huì),讓你的大腦放松放松。當(dāng)你回來(lái)的時(shí)候說(shuō)不定問(wèn)題忽然就很容易解決了。

          你認(rèn)真檢查自己了嗎?

          如果到了這一步你還沒(méi)有解決的話,這說(shuō)不定是個(gè)心理問(wèn)題??赡苣銓?duì)某段代碼有特別的感情,所以不想改掉它。說(shuō)不定你覺得只有你是對(duì)的,別人都錯(cuò)了。當(dāng)你有這種感覺的時(shí)候,你該考慮一下問(wèn)題的來(lái)源—你自己。不要過(guò)于自負(fù)而不愿認(rèn)清自己的錯(cuò)誤。

          作者
          brian d foy,

          COPYRIGHT
          Copyright 2002, Perl Documentation Project, All Rights Reserved

          posted on 2006-01-21 12:39 TrampEagle 閱讀(215) 評(píng)論(0)  編輯  收藏 所屬分類: 技術(shù)文摘
          主站蜘蛛池模板: 弥勒县| 景洪市| 晋城| 四会市| 蒙阴县| 隆化县| 驻马店市| 洞头县| 郧西县| 绿春县| 黄平县| 南投县| 无锡市| 奉新县| 黄冈市| 文昌市| 恩平市| 英德市| 蚌埠市| 金坛市| 祁连县| 大邑县| 聊城市| 棋牌| 渭南市| 滨州市| 泾川县| 清丰县| 延川县| 文登市| 阿克陶县| 梁平县| 本溪市| 竹山县| 城步| 滦平县| 锦州市| 遂昌县| 霍邱县| 枝江市| 任丘市|