无法在“ $ year;”附近的。\ metro.pl第31行的列表分配中修改键/值哈希切片。

Пав*_*кий 4 perl

我是Perl的新手。我不明白为什么我不能为字符串中的哈希字段分配年份

   %currentBook{year}=$year; 
完整代码在这里。

use warnings;
use strict;
use Scalar::Util qw(looks_like_number);
use Time::localtime; 

my $maxYear = Time::localtime->year+1;
my $year = $maxYear;
my %currentBook = (name=>"firstCurrentBook",
    author=>"NO",
    place=>"NO",
    year=>0);
my %maxBook = %currentBook;
my %minBook = %currentBook;
print "Choose action\n1 - Input book\n2 - Print min max year\n3 = exit\n->";
my $cond = <STDIN>;
while ($cond  != 3)
{
    if ($cond == 1){
        print "\nInput book name: ";
        $currentBook{name} = <STDIN>;
        print "\nInput author surname and initials: ";
        $currentBook{author} = <STDIN>;
        print "\nInput place: ";
        $currentBook{place} = <STDIN>;    
        do{
            print "\nInput year of book: ";
            $year = <STDIN>;
            chomp $year;
        } while  (!looks_like_number($year) || $year < 0 || $year > Time::localtime->year);
        %currentBook{year}=$year;
        if (%currentBook{year} > %maxBook{year}){
            %maxBook=%currentBook;
        }
        if (%currentBook{year} < %minBook{year}){
            %minBook=%currentBook;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

sim*_*que 6

您已经在toolic的评论中得到了答案,但是我将详细说明为什么会这样。

my %books = ( year => 2017 );
%books{year} = 2018;
Run Code Online (Sandbox Code Playgroud)

此代码将引发您看到的错误。

无法在“ 2018;”附近的/home/simbabque/code/scratch.pl行6313处的列表分配中修改键/值哈希切片。
由于编译错误,中止了/home/simbabque/code/scratch.pl的执行。

为了使您的程序按预期运行,您需要使用$ sigil而不是% sigil,因为其中的值$books{year}是标量。

但是为什么会出现错误消息?

实际上,%books{year}是一个完全有效的Perl表达式。

use Data::Dumper;

my %books = ( year => 2017 );
print Dumper %books{year};
Run Code Online (Sandbox Code Playgroud)

这将打印

$VAR1 = 'year';
$VAR2 = 2017;
Run Code Online (Sandbox Code Playgroud)

该构造%book{year}是所谓的哈希切片,它返回键/值对的列表。您还可以放入键列表,并获取键及其值的列表。这对于快速构造子哈希很有用。

my %timestamp = ( year => 2017, month => 12, day => 31, hour => 23, minute => 59 );
my %date = %timestamp{ 'year', 'month', 'day' };

print Dumper \%date;
Run Code Online (Sandbox Code Playgroud)

的输出是

$VAR1 = {
          'day' => 31,
          'month' => 12,
          'year' => 2017
        };
Run Code Online (Sandbox Code Playgroud)

但是,这种行为不允许您分配给%books{year}。它根本没有意义,因为它返回键/值对的列表。这就是为什么这种构造在Perl中不是我们所谓的左值的原因,因此它不能在赋值的左侧