2012-05-19 26 views
1

請注意以下幾個最基本的工作例如:IPC ::共享的變量,「不能用string ......作爲標REF ..」和內存地址

use warnings; 
use strict; 
use IPC::Shareable; 
use Data::Printer; 

IPC::Shareable->clean_up; 


my $sharevar1 = "a"; 
my $sharevar2; 


print "A: $sharevar1 $sharevar2\n"; 
p($sharevar1); 
p($sharevar2); 


my $glue1 = 'glu1'; 
my $glue2 = 'glu2'; 

my %options = (
    create => 1, #'yes', 
    exclusive => 0, 
    mode  => 0644, #0644, 
    destroy => 1, # 'yes', 
); 

my $sharevar_handle1 = tie $sharevar1, 'IPC::Shareable', $glue1 , \%options ; # 

print "B1: $sharevar1 $sharevar2 - $sharevar_handle1\n"; 

my $sharevar_handle2 = tie $sharevar2, 'IPC::Shareable', $glue2 , \%options ; # 

print "B2: $sharevar1 $sharevar2 - $sharevar_handle2\n"; 

p($sharevar1); 
p($sharevar2); 


$sharevar1 = "b"; 
#~ $sharevar1 = "AOE" . \$sharevar2; 
$sharevar2 = 20; 

print "C: "; 
print "- $sharevar1 $sharevar2\n"; 
p($sharevar1); 
p($sharevar2); 

當我跑,我得到像下面的輸出 - 這是預期:

Use of uninitialized value $sharevar2 in concatenation (.) or string at tt.pl line 13. 
A: a 
"a" 
undef 
Use of uninitialized value $sharevar1 in concatenation (.) or string at tt.pl line 30. 
Use of uninitialized value $sharevar2 in concatenation (.) or string at tt.pl line 30. 
B1: - IPC::Shareable=HASH(0xa1dc1b8) 
Use of uninitialized value $sharevar1 in concatenation (.) or string at tt.pl line 34. 
Use of uninitialized value $sharevar2 in concatenation (.) or string at tt.pl line 34. 
B2: - IPC::Shareable=HASH(0xa215b10) 
undef (tied to IPC::Shareable) 
undef (tied to IPC::Shareable) 
C: - b 20 
"b" (tied to IPC::Shareable) 
20 (tied to IPC::Shareable) 

 

但是,如果現在我試圖取消對「$sharevar1 = "AOE" . \$sharevar2;」行,而註釋掉「$sharevar1 = "b";「之上;那麼輸出我得到的是幾乎相同,只是在最後:

... 
B2: - IPC::Shareable=HASH(0x852fb20) 
undef (tied to IPC::Shareable) 
undef (tied to IPC::Shareable) 
Can't use string ("AOESCALAR(0x836bf88)") as a SCALAR ref while "strict refs" in use at /usr/local/share/perl/5.10.1/IPC/Shareable.pm line 741. 
C: $ 

現在,事情是,這個「不能用string ......」實際上會導致系統崩潰......顯然,如果tie d變量曾經通過\獲得了一個引用,它獲得了一個值,如SCALAR(0x836bf88)作爲字符串,這顯然被Perl解釋爲意味着一個地址...?!

而且我還以爲是Perl會在這種情況下匹配字符串的開始部分(SCALAR(...) - 所以我想在前面加上字符串「AOE」騙 - 但奇怪的是,Perl的仍然注意到(彷彿它是尋找一些正則表達式「0X withing括號」還挺符合):「不能用字符串(」 AOESCALAR(0x836bf88)「)作爲標參考」 ......

 

我的問題是 - 我推理Perl和IPC :: Shareable如何解釋地址(否則存儲爲「字符串」)正確(否,請參閱下面的編輯;是的,參見post);並且不管是否如此,我將如何將地址存儲到IPC :: Shareable中?

非常感謝任何答案,
乾杯!

編輯:嗯,很明顯,通常都與作品中包含字符串不會忽略打印字符串變量確定 - 所以這個問題是IPC ::共享的具體,我想:

DB<1> $ttt = "aa" 
    DB<2> p $ttt 
aa 
    DB<3> $eee = \$ttt 
    DB<4> p $eee 
SCALAR(0xa382668) 
    DB<5> $eee = "erw".\$ttt 
    DB<6> p $eee 
erwSCALAR(0xa382668) 
    DB<7> q 

回答

0

好了,原來我錯了關於出錯:)

原來,這個問題畢竟與字符串解析有關;即檢查大寫的關鍵字SCALAR;這裏是OP代碼的相應改變部分:

p($sharevar1); 
p($sharevar2); 


#~ $sharevar1 = "b"; 
#~ $sharevar1 = substr "AOE" . \$sharevar2, 2, 7; # Can't use string ("ESCALAR") as a SCALAR ref 
#~ $sharevar1 = substr "AOE" . \$sharevar2, 5, 10; # "ALAR(0x878", passes OK 
$sharevar1 = lc \$sharevar2; # lowercase works too 
$sharevar2 = 20; 

print "C: "; 
print "- $sharevar1 $sharevar2\n"; 
p($sharevar1); 
p($sharevar2); 

請注意,只要你有SCALAR,即使你沒有號碼的地址(如「ESCALAR」),嚴格的使用引發錯誤。

但是,如果關鍵字SCALAR不是完整的 - 即使它是小寫 - 那麼錯誤消失;這是終端日誌末尾現在:

... 
B2: - IPC::Shareable=HASH(0x9ca2e58) 
undef (tied to IPC::Shareable) 
undef (tied to IPC::Shareable) 
C: - scalar(0x9adef88) 20 
"scalar(0x9adef88)" (tied to IPC::Shareable) 
20 (tied to IPC::Shareable) 

好,希望這是它 - 但我真的不明白這個機制還沒有,沒有更好的澄清是受歡迎的,
乾杯!


編輯:剛發現另一件事;有時候你可能會這樣做:

my $sharevar2; 
my $sharevar_handle2 = tie $sharevar2, 'IPC::Shareable', $glue2 , \%options ; # 
print($sharevar2); 

我剛剛注意到有時(但並非總是,也不能真正說什麼時候); tie而不是'undef',會將$sharevar2變量設置爲像「SCALAR()」或「ARRAY()」 - 在這種情況下,print($sharevar2);語句將失敗。

不能調試這個其他方式,而是利用Data::Printer「上不$sharevar2小號p()(原因試圖無論如何打印會失敗) - 而是對$sharevar_handle2

my $sharevar2; 
my $sharevar_handle2 = tie $sharevar2, 'IPC::Shareable', $glue2 , \%options ; # 
print "2 "; p($sharevar_handle2); 

...然後輸出可能是這樣的:

... 
2 IPC::Shareable { 
    Parents  Exporter 
    Linear @ISA IPC::Shareable, Exporter 
    public methods (31) : .... 
    private methods (11) : .... 
    internals: { 
     _data \ "ARRAY(0xa21e788)", 
     _iterating "", 
... 

在這種情況下,你一定$sharevar2被設置爲「陣列(0xa21e788)」,因此,總會引起的故障時,一個試圖print吧。請注意,類似這樣的事情可以通過在代碼中稍後更多地將$sharevar2分配給參考(即,= \$somevar;;而這種因果關係可能並不總是顯而易見的。

對於一個臨時的解決辦法,只需將「行爲不端」變量undeftie之後 - 這應該允許的,其中分配給一個參考發生更容易追蹤:

my $sharevar2; 
my $sharevar_handle2 = tie $sharevar2, 'IPC::Shareable', $glue2 , \%options ; 
# if here $sharevar2 somehow becomes "ARRAY(0x88417c8)" instead of undef; reset 
print "1 "; p($sharevar_handle2); # would show "ARRAY(0x88417c8)" 
$sharevar2 = undef; 
print "2 "; p($refvarstr_handle); # should show undef 
p($sharevar2); # should not crash, cause it's now ARRAY anymore, but undef 

而且相關:can't use string as a SCALAR ref while strict refs - perlmonks.org

1

如果您要升級到IPC::Shareable的最新版本(0.60),我可以幫助您更好。我目前無法訪問Unix框來嘗試此操作,但在當前版本的第741行中沒有任何意義。

你應該知道,當你在處理綁定變量時,你只是接口看起來像一個Perl變量的標準API。因此,在寫作$sharevar1 = "AOE" . \$sharevar2時,實際上你打電話給IPC::Shareable::STORE($sharevar1, "AOE" . \$sharevar2),它可以做到它想要的東西。

我在模塊中也看到的是代碼,檢查是否被分配值(以綁定標)是一個參考值,如果因此它的聯繫,IPC::Shareable,如果它是不是已經追平。通過在/SCALAR/等中檢查字符串化的引用來確定用於取消引用值的類型,儘管我不明白它如何應用於您所看到的行爲(我期望字符串'AOESCALAR(0x836bf88)'被識別爲不是引用所以不受正則表達式檢查)我相信它是有貢獻的。也許這是我的版本已經修復的東西?

有錯誤很多的房間裏這種方法,並非最不重要的變量綁定到其他類將引發整個事情了完全。我建議你升級,看看最新版本是否支持你想要做的。

但請記住,這已經無關Perl核心,一切都做的不完全模塊的模擬接口,Perl的標量。

+0

@Borodin您好,感謝您的回答!我嘗試過更新,'perl'說:'IPC ::共享的是最新的(0.6).'我已經更新[我的文章](http://stackoverflow.com/a/10668741/277826);我可以證實,只要資本「'SCALAR'」不存在,就可以打印變量(即使是小寫的「scalar」)。我也希望「_recognized as not an reference_」,但顯然不是這樣,至少在我的Ubuntu盒子上。非常感謝 - 歡呼! – sdaau