亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2437 | 回復: 8
打印 上一主題 下一主題

$! 是只讀的嗎? [復制鏈接]

論壇徽章:
0
跳轉到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-09-18 15:58 |只看該作者 |倒序瀏覽
$! undef 總是沒有起作用, 感覺 $! 變成了只讀, 代碼如下:
undef( $! );
print "xxx" if defined( $! );

#  總是會打印

為何呢? 我看到不少代碼都有 undef $! 的用法啊...

論壇徽章:
0
2 [報告]
發(fā)表于 2009-09-18 22:23 |只看該作者
$!是perl自動會幫你設置的
就跟c庫里面的errno一樣,是個全局變量,你當然去可以設置errno了,但是你在調用庫函數的時候,庫函數也會去寫這個變量

$!也是同樣的道理,print函數調用的過程中也是會有錯誤發(fā)生,perl也是會幫你去設置$!變量的

論壇徽章:
0
3 [報告]
發(fā)表于 2009-09-19 09:17 |只看該作者
$! 的用法我一開始就在 perldoc perlvar 翻了一遍,解釋確實也是這樣子說的,但問題是:
print "xxx" if defined( $! );
這里,應該是 if 條件先判斷啊,上下代碼并未有任何函數的調用,為何會有print 或 其他函數設置 errno?

論壇徽章:
0
4 [報告]
發(fā)表于 2009-09-19 13:03 |只看該作者

回復 #3 dugu072 的帖子

一條c語言大多數情況對應了好幾條匯編
一條perl語言你看似是一條,生成的中間代碼有多少你知道不?

論壇徽章:
0
5 [報告]
發(fā)表于 2009-09-19 13:52 |只看該作者
確實,一條perl語句,會對應很多c的代碼,甚至會有不少c庫的調用,但并不是任何語句都會有c庫的調用吧?
而就上面的代碼而言:
undef( $! );
if( defined($!) ) {
   print "Hello\n";
}
除了第一句 undef $!之外,緊接著就是  取defined($!),除此之外就是 if 判斷,而 我的疑問是 undef($!) 到底起作用沒,如果它起作用了,那么唯一可能會修改 $! 的,就只有 defined() 函數,但不論從perl -f defined說明的,還是從該函數的實現來看,這里也不會有c庫的調用而改變了 $!  的可能的吧?

甚至我修改代碼,不要用 if 了:
undef $!;
print defined($!);
竟然還是打印的: 1,那這里的 undef( $!) ,到底起了作用沒?

退一步說,如果真的如你所說,如此簡單的邏輯里,都會立即改變 $! ,那么,$! 這個變量還有什么意義,它 總是在變啊,等你用的時候,早就是其他錯誤信息了……

所以,我還是懷疑 $! 是只讀的,只有 perl 解釋器在執(zhí)行code時,才會根據內部調用,自己修改 $!,而對于外部程序,$! 只能只讀?

[ 本帖最后由 dugu072 于 2009-9-19 13:55 編輯 ]

論壇徽章:
0
6 [報告]
發(fā)表于 2009-09-19 14:14 |只看該作者

回復 #5 dugu072 的帖子

絕對是可以改的
perlvar上也說的很清楚了
If used in a numeric context, yields the current value of errno, with all the usual caveats. (This means that you shouldn't depend on the value of $! to be anything in particular unless you've gotten a specific error return indicating a system error.) If used in a string context, yields the corresponding system error string. You can assign to $! to set errno if, for instance, you want "$!" to return the string for error n, or you want to set the exit value for the die() operator. (Mnemonic: What just went bang?)


注意其中的assign

  1. use strict;
  2. use warnings;
  3. foreach ( 1 .. 10 ) {
  4.     $! = $_;
  5.     print "###Error info for $_ is ####\n";
  6.     print $!, "\n";
  7.     print "#" x 30, " \n ";
  8. }
復制代碼

你用上面的代碼就可以把errno對應的錯誤提示都給打印一遍

loser@loserking:~$ ./a.pl
###Error info for 1 is ####
Operation not permitted
##############################
###Error info for 2 is ####
No such file or directory
##############################
###Error info for 3 is ####
No such process
##############################
###Error info for 4 is ####
Interrupted system call
##############################
###Error info for 5 is ####
Input/output error
##############################
###Error info for 6 is ####
No such device or address
##############################
###Error info for 7 is ####
Argument list too long
##############################
###Error info for 8 is ####
Exec format error
##############################
###Error info for 9 is ####
Bad file descriptor
##############################
###Error info for 10 is ####
No child processes
##############################

[ 本帖最后由 churchmice 于 2009-9-19 14:17 編輯 ]

論壇徽章:
0
7 [報告]
發(fā)表于 2009-09-19 14:19 |只看該作者
雖然可以改,但是這個變量是不能被undef的,你undef之后perl怎么告訴你錯誤呢?
然后我猜所有predefined的variable都是不能被undefine的
其實undef $!只是把以前的$!變量給清空了而已,就跟errno=0一個道理
如果你進行了一個關鍵性的操作,這個操作可能會引起錯誤,需要去檢查$!以進行下一步的操作,那你再操作之前就要把前面遺留下來的$!先清空掉,否則不是悲劇了?

[ 本帖最后由 churchmice 于 2009-9-19 14:58 編輯 ]

論壇徽章:
0
8 [報告]
發(fā)表于 2009-09-19 16:59 |只看該作者
原帖由 churchmice 于 2009-9-19 14:19 發(fā)表
雖然可以改,但是這個變量是不能被undef的,你undef之后perl怎么告訴你錯誤呢?
然后我猜所有predefined的variable都是不能被undefine的
其實undef $!只是把以前的$!變量給清空了而已,就跟errno=0一個道理
...


部分贊同, 而且經過你的的提示——“這個變量是不能被undef”,因為之前一開始就想 $! 只讀與否,而沒考慮undef是否對某些變量有效,于是仔細翻了下文檔,做了些試驗,算是搞清楚一些了:
1. $! 可以設置,但有限制,因為“You can assign a number to $! to set *errno* if ……”,這句不僅僅說明可以賦值給 $! ,而且只是說明了 可以賦值的是一個 Number
2. $! 在數字環(huán)境,表現為 error number的值;在字符串環(huán)境,表示錯誤string
如下代碼就可以看到 $! 在error number為 1~42 區(qū)間內,存在對應的error string,尤其要注意的是對于: error number == 0 時,error string== “”;error number > 42時, error string== “Unknown error”

  1. for(0..76) {
  2.    $! = $_;
  3.    my $num = $! + 0;
  4.    print "$num. After modify: ". $! . "\n";
  5. }
復制代碼

3. $! 將對其本身的賦值操作,都會轉化為 Number(字符串->數字,undef->0……)后,在賦值給自己
首先第 2 點可以看到,直接賦值 number,是可以成功的,但如果賦值字符串呢?

  1. $! = 'haha';
  2. print "After modify to string: ". $! . "\n";
復制代碼

  將看到 $! 為 空
修改代碼為:

  1. $! = '1haha';
  2. print "After modify to string: ". $! . "\n";
復制代碼

   將看到 $! 為: Operation not permitted,正式第 2 點中,$!=1時候,對應的 error string 的內容
   因此 undef( $! )的結果,實際上, 此時 $! 被賦值為 $! = 0,對應的是 "" 字符串,因此 defined( $! )是 true
4. “然后我猜所有predefined的variable都是不能被undefine的”——這句話,分析到這里,肯定就不對了,因為 undef $!; 的結果,只是 $! 本身的特性而已,對其他內部變量,沒有什么參考意義。當然我也簡單試驗了下:

  1. print "\$\" Before modify: ". defined($") . "\n";
  2. undef $";
  3. print "Undef successfully!\n" unless defined($");
復制代碼

輸出結果是:
$" Before modify: 1
Undef successfully!
可以看到,undef成功了

再次感謝 churchmice 的提示, 順便再幫我看看,分析的有什么問題沒?

論壇徽章:
0
9 [報告]
發(fā)表于 2009-09-19 17:46 |只看該作者

回復 #8 dugu072 的帖子

分析的很細致
第4點經你這么一說我也想起來了,在讀取整個文件(slurp模式)的時候就經常undef $/ 的
感謝你的指出,證明我的猜測還是不準確
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術有限公司. 版權所有 京ICP備16024965號-6 北京市公安局海淀分局網監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯網協會會員  聯系我們:huangweiwei@itpub.net
感謝所有關心和支持過ChinaUnix的朋友們 轉載本站內容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP