代码之家  ›  专栏  ›  技术社区  ›  joe

为什么Perl抱怨“不能在标量赋值中修改常量项”?

  •  2
  • joe  · 技术社区  · 15 年前

    我有一个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 回复  |  直到 15 年前
        1
  •  10
  •   Space    15 年前

    我认为你的代码应该是;

    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
  •  11
  •   Axeman maxelost    15 年前

    由于您没有使用“胖逗号”(=>),因此左侧的下划线名称无法获取 auto-quoted 因此,没有信号( '$' , '@' '%' )它们只能是 子例程名称 . 由于您还没有声明这些sub,Perl将它们作为常量,并告诉您不能分配给常量(或子调用)。

    正确的方法是把你的作业改成双箭头

    _ldap => $ldap_obj, #...
    

    此外,Brad的文章提醒我,即使它们是自动引用的,也不能为文本字符串分配词汇,即使Perl将其解释为自动引用的字符串。

        3
  •  2
  •   Brad Gilbert    15 年前

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


    这就是你想写的:

    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;