请注意以下最小的工作示例:
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: $
现在,问题是“无法使用字符串......”实际上会导致崩溃...显然,如果tie
d变量通过\
分配了引用,那么得到一个像SCALAR(0x836bf88)
这样的值作为字符串,显然后来被Perl解释为一个地址......?!
我认为在这种情况下Perl会匹配字符串的起始部分(SCALAR(...
) - 所以我试图通过前面的字符串“AOE”作弊 - 但奇怪的是,Perl仍然注意到( 好像它正在寻找一些正则表达式“0x withing括号”有点匹配):“不能使用字符串(”AOESCALAR(0x836bf88)“)作为SCALAR ref”...
我的问题是 - 我的理由是关于Perl和IPC :: Shareable如何解释一个地址(否则存储为“字符串”)是正确的(不,请参阅下面的编辑;是的,请参阅post);无论如何,我如何将地址存储到IPC :: Shareable中?
非常感谢任何答案,
干杯!
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 :(得分: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标量的接口。
答案 1 :(得分: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
上使用p()
的{{1}}(因为无论如何都会尝试打印它) - 而是在{{1 }}:
$sharevar2
...然后输出可能是这样的:
$sharevar_handle2
在这种情况下,您确定my $sharevar2;
my $sharevar_handle2 = tie $sharevar2, 'IPC::Shareable', $glue2 , \%options ; #
print "2 "; p($sharevar_handle2);
设置为“ARRAY(0xa21e788)”,因此当尝试...
2 IPC::Shareable {
Parents Exporter
Linear @ISA IPC::Shareable, Exporter
public methods (31) : ....
private methods (11) : ....
internals: {
_data \ "ARRAY(0xa21e788)",
_iterating "",
...
时它将始终导致失败。请注意,这样的事情可能是由于在代码中稍后将$sharevar2
分配给引用(即print
)的命令引起的;这种因果关系可能并不总是显而易见的。
对于临时修复,只需在$sharevar2
之后将“行为不当”变量设置为= \$somevar;
,这样就可以更轻松地跟踪参考分配的位置:
undef
还相关:can't use string as a SCALAR ref while strict refs - perlmonks.org