IPC :: Shareable变量,“不能使用字符串...作为标量引用."和内存地址 [英] IPC::Shareable variables, "Can't use string ... as a SCALAR ref.." and memory address

查看:151
本文介绍了IPC :: Shareable变量,“不能使用字符串...作为标量引用."和内存地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意以下最小工作示例:

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 = "b";"时尝试取消注释"$sharevar1 = "AOE" . \$sharevar2;"行;那么我得到的输出几乎是一样的,除了最后:

...
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带有括号"正则匹配的正则表达式):无法将字符串("AOESCALAR(0x836bf88)")用作标量引用" ...

 

我的问题是-关于Perl和IPC :: Shareable如何正确解释地址(否则存储为字符串")的原因(否,请参见下面的编辑;是的,请参见帖子);不管它是什么,如何将地址存储到IPC :: Shareable中?

在此先感谢您的回答,
干杯!

嗯,显然,通常所有方法都可以通过打印包含字符串地址的字符串变量来正常工作-所以这个问题是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

解决方案

如果您升级到IPC::Shareable的最新版本(0.60),可以为您提供更好的帮助.我目前无法使用Unix系统进行此操作,但是当前版本的741行没有任何重要意义.

您应该意识到,当您处理绑定变量时,您只是在与看起来像Perl变量的标准API交互.因此,在编写$sharevar1 = "AOE" . \$sharevar2时,您实际上是在调用IPC::Shareable::STORE($sharevar1, "AOE" . \$sharevar2),它可以完成所需的工作.

我在模块中看到的是代码,该代码检查要分配(绑定到标量)的值是否是参考值,如果尚未绑定,则将其绑定到IPC::Shareable.通过对照/SCALAR/等检查字符串化引用来建立用于解引用值的类型,尽管我看不到它如何应用于您所看到的行为(我希望将字符串'AOESCALAR(0x836bf88)'识别为而不是参考,因此无需进行正则表达式检查)我确信这是有帮助的.也许这是我的版本中已修复的问题?

此方法有很多错误的余地,尤其是与其他类关联的变量将把整个事情完全抛弃.我建议您升级并查看最新版本是否支持您要执行的操作.

请记住,这与内核Perl无关,而与模块无关的所有事情都无法完全模拟Perl标量的接口.

Please note the following minimal working example:

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);

When I run this, I get an output like below - which is as expected:

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)

 

However, if now I try to uncomment the "$sharevar1 = "AOE" . \$sharevar2;" line, while commenting out the "$sharevar1 = "b";" above it; then the output I get is mostly the same, except at the end:

...
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: $ 

Now, the thing is that this "Can't use string ..." actually causes a crash... Apparently if a tied variable ever gets assigned a reference via \, it gets a value like SCALAR(0x836bf88) as a string, which apparently gets interpreted by Perl afterwards to mean an address... ?!

And I thought that Perl would in that case match the starting part (SCALAR(...) of the string - and so I tried to cheat by prepending string "AOE" - but the strange thing is, Perl still noticed (as if it is looking for some regex for "0x withing parenthesis" kinda match): "Can't use string ("AOESCALAR(0x836bf88)") as a SCALAR ref" ...

 

My question is - is my reasoning about how Perl and IPC::Shareable interpret an address (which is otherwise stored as a "string") correct (no, see edit below; yes, see post); and regardless if it is, how would I go about storing an address into an IPC::Shareable?

Many thanks in advance for any answers,
Cheers!

EDIT: Well, apparently, normally all works OK with printing string variables that contain string adresses - so this problem is IPC::Shareable specific, I guess:

  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

解决方案

I could help you better if you would upgrade to the latest version (0.60) of IPC::Shareable. I have no access to a Unix box to try this at present, but there is nothing significant at line 741 of the current version.

You should be aware that, when you are dealing with tied variables, you are just interfacing with a standard API that looks like a Perl variable. So in writing $sharevar1 = "AOE" . \$sharevar2 you are actually calling IPC::Shareable::STORE($sharevar1, "AOE" . \$sharevar2) which can do pretty much what it wants.

What I do see in the module is code that checks whether the value to be assigned (to a tied scalar) is a reference value, and if so ties it to IPC::Shareable if it isn't already tied. The type to use in dereferencing the value is established by checking the stringified reference against /SCALAR/ etc. and although I don't see how it applies to the behaviour you are seeing (I would expect the string 'AOESCALAR(0x836bf88)' to be recognized as not being a reference and so not subject to regex checking) I am sure it is contributory. Maybe it is something that has been fixed in my version?

There is a lot of room for error in this methodology, not least that variables tied to other classes will throw the whole thing out completely. I suggest you upgrade and see if the latest version supports what you want to do.

Remember though that this has nothing to do with core Perl, and everything to do with the module incompletely emulating the interface to Perl scalars.

这篇关于IPC :: Shareable变量,“不能使用字符串...作为标量引用."和内存地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆