perl local my our 的前世今生

2021-08-22 15:52:47 字數 2392 閱讀 9134

perl中的變數作用範圍 local, my, our與全域性變數

很古老很古老以前......嗯,不用老到白堊紀,那時候的perl是自由射擊的。沒有什麼定義變數的說法,所有的變數都是全域性變數,也不需要任何 定義就可以使用。後來就出現了local, 再後來出現了use strict 'vars'和my, 再後來又有了our......所以今天的perl大陸就有了崇山巨嶺,一些變數就被限制在盆地裡,老死於桃花源中也。

因為要使用乙個跨模組全域性變數,研究了一下perl的變數作用範圍,寫一點筆記吧。

1. 首先說our, 這個最晚出現但其實質卻最早出現的變數修飾符。眾所周知,在perl不使用use strict 'vars'的時候,你可以任意使用變數而不需要實現定義:

$szstatemachinestatus = undef;

這行**在使用了use strict 'vars'以後是編譯不能通過的。如果這個變數是乙個全域性變數,那麼可以定義

our $szstatemachinestatus = undef;

這個效果和在不使用use strict 'vars'時一樣。"一樣"意味著什麼呢?

our $szstatemachinestatus = 'init';

print $szstatemachinestatus;

列印的結果是兩個'inited'。順便說,用our定義過的變數,可以在任何地方被再次用our定義,仍然和第乙個our定義的變數是同乙個。

2. my

慢慢地有人覺得perl的"自由射擊式"變數定義法則不行,最突出的就是一些常會打錯字(typo)的人。假如你定義了乙個變數叫$ szstatemachinestatus,可是在某個地方寫成了$szstatmachinestatus,少了乙個e。因為不use strict啊,所以沒有任何警告,可以這樣用。結果就是出了錯你就慢慢debug去吧,很浪費時間,不符合perl的懶惰文化。

然後就有了use strict 'vars'和my。有了use strict 'vars'以後,所有的變數在使用前必須先被定義。my的法則很簡單,只在當前作用域起作用。比如說定義了

my $szstatemachinestatus;

那麼如果是在檔案頭定義的,作用範圍就到檔案尾,在子函式裡也能用。如果是在子函式裡定義的,那麼作用範圍就只到函式結束。試看以下**

foreach my $szname (@arrname)

在這個迴圈裡perl每次都建立乙個新的$szname變數。換句話說,"my"是屬於"見到my就新建"的變數。

3. local

其實這個定義都可以取消了。它是在my還沒出現之前的乙個權宜方案。比如說乙個變數$i被定義成了全域性變數,可是你又想暫時使用乙個也叫$i的臨時變數。

no strict 'vars';

$i = 9999;

print "$i\n";

結果是7777, 9999。在出了local的作用域以後$i又回到了原來的值。在出現了my以後,沒有任何理由需要使用local了,請忘記掉它吧。

4. 最後乙個話題,全域性變數

當你只有乙個pl檔案時,很簡單,把你的全域性變數在檔案頭部定義成our就行。可能你會看到有些書上說要使用use vars qw( $szversion $sztoolname); 這樣的方式來把 $szversion和$sztoolname定義成全域性變數。注意了,use vars的用法是在my出現後,our出現之前的乙個歷史的盲腸。our的語法更自然,更易於理解,為什麼不用our呢? --另外,在檔案頭把變數定義成my, 也是全域性可用的,但是冒了風險,假如在某個函式裡用my再定義一次,原來的值可就消失了。用our就不存在多次定義會導致丟值的狀況。

當你在寫乙個有乙個pl檔案,n個pm檔案的系統時該如何呢?事實上perl裡的變數和函式名都有乙個系統級的名字。比如說你在某pm檔案的頭上定義了包名和全域性變數

package bagua;

our $east = 'wood';

那麼在任何地方,任何pm和pl檔案裡都可以使用$bagua::east來訪問這個變數。$bagua::east就被稱為系統級名字。這也能回答乙個問題,為什麼不同的perl包裡面定義的同名全域性變數間不會衝突,因為它們都被限制在包的名字空間下面了。

如果你是在pl裡定義全域性變數,而且該檔案沒有定義package名字怎麼辦?perl會生成乙個預設的package,名字叫"main"。所以如果你的pl檔案是這樣

our $szversion = '1.0.1";

那麼在其它檔案裡就可以用$main::szversion來訪問,並不需要你定義package main.

最後,說乙個邪門招式。你可以試一下定義任意乙個含有::的變數

our $gcolor::blue = '0x0000ff';

這個變數就在任何地方可用,哪怕你從來沒有定義過gcolor這個package。這個是perl的靈活性的體現,它看到這個就自動生成了gcolor這個名字空間。當然,我不鼓勵這種無厘頭的用法。

container of 的的的原理

另外一篇,同樣精彩,揭開linux核心中container of的神秘面紗 華清遠見嵌入式學院講師。在linux 核心中有乙個大名鼎鼎的巨集container of 這個巨集是用來幹嘛的呢?我們先來看看它在核心中是怎樣定義的。呵呵,乍一看不知道是什麼東東。我們先來分析一下container of p...

存在的就是合理的,發生的即是必然的。

筆者有時候會想,什麼是對,什麼是錯?對於追求某一件事情之前首先會考慮,為什麼我要做這件事情。所以經過自我分析和生活周邊環境的總結。我認為,對於乙個人來,這是在站在個體的角度上說。什麼是對的?就是你自己覺得是對的,它就是對的。不過這個只是你自己的想法。主觀上的正確,不代表客觀上也受到了別人的認可。就拿...

Apache的rewrite的重寫相關的引數

apache mod rewrite規則重寫的標誌一覽 使用mod rewrite時常用的伺服器變數 rewriterule規則表示式的說明 匹配任何單字元 chars 匹配字串 chars chars 不匹配字串 chars text1 text2 可選擇的字串 text1或text2 匹配0到1...