我不明白錯誤資訊
每個 on 參考的引數型別必須是 test.pl 第 17 行的 unblessed hashref 或 arrayref。
對于這個測驗用例(從一個更大的模塊中提取):
BEGIN { our $RE_timestamp = qr/whatever/; }
# check Regular expressions for TIMESTAMP
use constant _TEST_TIMESTAMPS => ( # from "6.2.3.1. Examples"
'1985-04-12T23:20:50.52Z' => 1,
'1985-04-12T19:20:50.52-04:00' => 1,
'2003-10-11T22:14:15.003Z' => 1,
'2003-08-24T05:14:15.000003-07:00' => 1,
'2003-08-24T05:14:15.000000003-07:00' => 0, # invalid!
'-' => 1 # NILVALUE
);
UNITCHECK
{
# from "6.2.3.1. Examples"
while (my ($str, $valid) = each _TEST_TIMESTAMPS) {
if ($valid) {
die "timestamp ($str) is not valid\n"
if ($str !~ /^${RE_timestamp}$/o);
} else {
die "timestamp ($str) is valid\n"
if ($str =~ /^${RE_timestamp}$/o);
}
}
}
最重要的是,我在 Perl 5.18.2 中遇到了錯誤,但是當我在另一臺使用 Perl 5.26.1 的機器上檢查時,根本沒有錯誤訊息!
那么我也可以讓代碼與舊的 Perl 5.18 一起作業嗎?
丑陋的解決方法
實驗我發現each (my %h = _TEST_TIMESTAMPS)沒有幫助,但是當使用my %h = _TEST_TIMESTAMPS;and then時each %h,錯誤就消失了。
仍然我不明白發生了什么(在使用常量之前,我在my內部使用了本地哈希UNITCHECK。顯然我想改用包級常量。
uj5u.com熱心網友回復:
這在問題中_TEST_TIMESTAMPS作為“串列常量”給出,并且僅表現為平面串列,而不是散列。有關非常詳細的討論,請參見這篇文章。each此外,由于錯誤訊息通知我們,因此它被拒絕。
可以改用哈希參考
use constant _TEST_TIMESTAMPS => { ... };
這被each. 對于問題的片段,它似乎可以正常作業,但我會小心使用更多涉及的內容。使用參考有constant其自身的問題。
另外,請記住,來自constant pragma的物件實際上是子例程(“在當前實作中”,如檔案所說);見Technical Note和Bugs。這會影響人們對他們在各種情況下的行為的期望。
另一方面,換成const,Const::Fast使它在所有情況下都可以使用正常的詞法變數干凈地作業
use warnings;
use strict;
use feature 'say';
use Const::Fast;
our $RE_timestamp;
BEGIN { our $RE_timestamp = qr/whatever/; }
# check Regular expressions for TIMESTAMP
our %_TEST_TIMESTAMPS;
BEGIN {
const our %_TEST_TIMESTAMPS => ( # from "6.2.3.1. Examples"
'1985-04-12T23:20:50.52Z' => 1,
'1985-04-12T19:20:50.52-04:00' => 1,
'2003-10-11T22:14:15.003Z' => 1,
'2003-08-24T05:14:15.000003-07:00' => 1,
'2003-08-24T05:14:15.000000003-07:00' => 0, # invalid!
'-' => 1 # NILVALUE
);
}
UNITCHECK
{
# from "6.2.3.1. Examples"
while (my ($str, $valid) = each %_TEST_TIMESTAMPS) {
if ($valid) {
die "timestamp ($str) is not valid\n"
if ($str !~ /^${RE_timestamp}$/o);
} else {
die "timestamp ($str) is valid\n"
if ($str =~ /^${RE_timestamp}$/o);
}
}
}
with 引入的詞法Const::Fast必須在宣告時賦值(當然以后不能重新賦值),所以這里它必須是一個our變數,因為它需要在塊內賦值,但在BEGIN塊外宣告,所以要設定和可見UNITCHECK。?
我只使用Const::Fast作為我的偏好;另一個可行的庫是Readonly。
請注意,$RE_timestamp如果要使用,必須首先在任何塊之外進行詞法宣告strict(為什么不使用它?)。我糾正了這一點。這不需要our任何原因,但我離開了,因為可能還有其他原因。
至于為什么這在后來的 Perls 中不是問題,我想它是 hashref 或 arrayref 的要求在某個時候被放棄了。(我現在無法檢查。)
?我們可以在多個地方正式宣告一個變數是全域變數our的詞法別名的一個屬性。
uj5u.com熱心網友回復:
問題似乎是each堅持使用哈希變數(不是常量),所以我這樣解決了(不是真正的,但它有效):
UNITCHECK
{
my $hr = { _TEST_TIMESTAMPS };
while (my ($str, $valid) = each %$hr) {
#...
}
}
但是,將創建一個新的臨時哈希{ _TEST_TIMESTAMPS },因此最好將哈希參考分配給常量。然后你仍然需要一個變數,但不會創建臨時哈希物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464668.html
上一篇:如何傳遞定義為常量的陣列的參考?
