Perl явные ошибки имени пакета в цикле while и требуют проблем - PullRequest
1 голос
/ 16 октября 2011

Запуск этого кода

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

частоты.пл

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

Я получаюэти ошибки

Глобальный символ "% частоты" требует явного имени пакета в строке ./parsensendnotes2.pl 30.

Глобальный символ "% частот" требует явного имени пакета в строке ./parsensendnotes2.pl44.

Глобальному символу "@tone" требуется явное имя пакета в строке ./parsensendnotes2.pl 44.

Глобальному символу "@tone" требуется явное имя пакета в строке ./parsensendnotes2.pl45.

Глобальному символу "$ tempo" требуется явное имя пакета в строке ./parsensendnotes2.pl 45.

Глобальному символу "@tone" требуется явное имя пакета в строке ./parsensendnotes2.pl46. ​​

Глобальному символу "@tone" требуется явное имя пакета в строке ./parsensendnotes2.pl 46.

Выполнение ./parsensendnotes2.pl прервано из-за ошибок компиляции.

Что я делаю не так?

Ответы [ 2 ]

4 голосов
/ 16 октября 2011

имя% частот локализовано в файле frequencies.pl: my длится до конца блока или до конца файла.

Лучшим способом было бы удалить 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 & co, опять же, my область действия переменной ограничена блоком {},Вы должны сделать что-то вроде

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

, чтобы сделать $x доступным вне if.

1 голос
/ 16 октября 2011

my %frequencies из частот.пл не объявлено внутри parsesendnotes.pl .

Вам нужно our %frequencies в вашем основном скрипте.И, конечно, то же самое для других переменных.

Некоторая документация:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...