为什么Perl会抱怨“无法修改标量赋值中的常量项”?

时间:2010-05-18 08:26:09

标签: perl ldap

我有这个导致问题的Perl子例程:

sub new
{
    my $class = shift;

    my $ldap_obj = Net::LDAP->new( 'test.company.com' ) or die "$@";

    my $self = {
                _ldap = $ldap_obj,
                _dn ='dc=users,dc=ldap,dc=company,dc=com',
                _dn_login = 'dc=login,dc=ldap,dc=company,dc=com',
                _description ='company',
                };

    # Print all the values just for clarification.
    bless $self, $class;

    return $self;
}

这段代码出了什么问题:

我收到此错误无法在Core.pm第12行修改标量赋值中的常量项,靠近“$ ldap_obj”

3 个答案:

答案 0 :(得分:11)

由于您没有使用“胖逗号”(=>),因此左侧的下划线名称未获得auto-quoted,因此没有符号('$',{{1 }}或'@'),它们只能是子例程名称。由于你还没有声明这些subs,perl将它们作为常量,并告诉你不能分配给常量(或子调用)。

正确的解决方法是将作业更改为双箭头

'%'

此外,Brad的帖子提醒我,即使它们是自动引用的,你也无法将词汇分配给文字字符串,即使perl将其解释为自动引用的字符串。

答案 1 :(得分:10)

我认为你的代码应该是;

my $self = {
                _ldap => $ldap_obj,
                _dn =>'dc=users,dc=ldap,dc=company,dc=com',
                _dn_login => 'dc=login,dc=ldap,dc=company,dc=com',
                _description =>'company',
};

更改它并尝试使用$perl -c module.pm

答案 2 :(得分:2)

哈希只是键值对的列表。有一种语法结构可以帮助区分键和值。它被称为“胖箭”=>。此构造将左手参数强制转换为字符串,然后转换为简单的逗号。


这就是你的意思:

perl -MO=Deparse -e'$s = { a => 1 }'
$s = {'a', 1};
-e syntax OK

这是你实际写的:

perl -MO=Deparse -e'$s = { a = 1 }'
Can't modify constant item in scalar assignment at -e line 1, near "1 }"
-e had compilation errors.
$s = {'a' = 1};

这就是为什么我建议您始终启动一个启用了警告的Perl程序。

perl -w -MO=Deparse -e'$s = { a = 1 }'
Unquoted string "a" may clash with future reserved word at -e line 1.
Can't modify constant item in scalar assignment at -e line 1, near "1 }"
-e had compilation errors.
BEGIN { $^W = 1; }
$s = {'a' = 1};
perl -w -MO=Deparse -e'$s = { a => 1 }'
Name "main::s" used only once: possible typo at -e line 1.
BEGIN { $^W = 1; }
my $s = {'a', 1};
-e syntax OK

最后一个示例说明了您还应use strict

的原因
perl -w -Mstrict -MO=Deparse -e'$s = { a => 1 }'
Global symbol "$s" requires explicit package name at -e line 1.
-e had compilation errors.
BEGIN { $^W = 1; }
use strict 'refs';
${'s'} = {'a', 1};

在尝试使用之前我应该​​声明$s

perl -w -Mstrict -MO=Deparse -e'my $s = { a => 1 }'
BEGIN { $^W = 1; }
use strict 'refs';
my $s = {'a', 1};
-e syntax OK

这就是为什么我总是用以下内容开始我的Perl程序的原因:

use strict;
use warnings;