在while循环中Perl显式包名称错误并且需要麻烦

时间:2011-10-16 14:56:59

标签: perl

运行此代码

parsesendnotes.pl

#!/usr/bin/perl
use strict;
use warnings;
use Device::SerialPort;
use Time::HiRes qw(usleep); # For sleep in ms

if ($#ARGV + 1 != 2) {
    print "Usage: $0 port filename\n";
    print "Example: $0 /dev/ttyASM0 money.txt\n";
    exit 1;
}

my $file = $ARGV[0];
my $dev  = $ARGV[1];

if (!-e $file || !-e $dev) {
    print "File or brain not found.\n";
    exit 1;
}

my $arduino = DeviceSerialPort->new($dev);
$arduino->baudrate(9600);
$arduino->databits(8);
$arduino->parity("none");
$arduino->stopbits(1);

require "frequencies.pl";
open NOTES, "$file";

print $frequencies{"LA3"};

while (<NOTES>) {
    chomp;      # No newline
    s/#.*//;    # No comments
    s/^\s+//;   # No leading white
    s/\s+$//;   # No trailing white
    next unless length;
    if ($_ =~ m/^TEMPO/) {
        my $tempo = split(/\s+/, $_, -1);
        print "Tempo is $tempo.";
    } else {
        my @tone = split(/\s+/, $_);
    }
    my $note = $frequencies{$tone[0]};
    my $duration = $tone[1]*$tempo;
    print "Playing $tone[0] (\@$note Hz) for $tone[1] units ($duration ms).";
    while ($note > 255) {
        $arduino->write(chr(255));
        $note -= 255;
    }
    $arduino->write(chr($note));
    $arduino->write(";");
    usleep($duration);
}

frequencies.pl

my %frequencies = (
    "PAUSE" => 0,
    "B0" => 31,
    "DO1" => 33,
    "DOD1" => 35,
    ...
);

我获得了这些错误

全局符号“%频率”需要在./parsensendnotes2.pl第30行显式包名。

全局符号“%频率”需要在./parsensendnotes2.pl第44行显式包名。

全局符号“@tone”需要在./parsensendnotes2.pl第44行显式包名。

全局符号“@tone”需要在./parsensendnotes2.pl第45行显式包名。

全局符号“$ tempo”需要在./parsensendnotes2.pl第45行显式包名。

全局符号“@tone”需要在./parsensendnotes2.pl第46行显式包名。

全局符号“@tone”需要在./parsensendnotes2.pl第46行显式包名。

由于编译错误,./parsensendnotes2.pl的执行中止。

我做错了什么?

2 个答案:

答案 0 :(得分:4)

名称%频率已本地化在文件frequencies.pl中:我会持续到块结束或文件结束。

更好的方法是删除my并执行以下操作:

my %frequencies;
eval { %frequencies = do "frequencies.pl"; }
# must check $! and $@ here -- see perldoc -f do`

然而,更好的方法是使用YAML:

freq.yml

---
    "PAUSE": 0 
    "B0": 31
    "DO1": 33
    "DOD1": 35

然后

use YAML qw(LoadFile);
# ...
my $data = LoadFile("freq.yml");
%frequencies = %$data;

至于@tone,$ tempo&amp;另外,my变量范围仅限于{}块。你应该做点什么

my $x;
if (...) { $x = ... };

使$x可以在if之外访问。

答案 1 :(得分:1)

来自 frequencies.pl

my %frequencies未在 parsesendnotes.pl 中声明。

您的主脚本中需要our %frequencies。当然其他变量也一样。

一些文档: