對于一些 Perl 診斷測驗,我正在使用 JSON::MaybeXS 記錄格式為 JSON 的各種資訊。
當我想記錄從特殊變數 $^V 獲得的當前 Perl 版本時出現錯誤。
正如最小的演示腳本所示,除非我將 $^V 參考為“$^V”,否則會發生錯誤。
json_perl_version_test.pl
#!/usr/bin/env perl
use strict;
use warnings;
use v5.18;
use JSON::MaybeXS;
say "Running Perl version $^V";
my $item = 'Wut?';
my %hash1 = (
something => $item,
v_unquoted => $^V
);
eval { say say 'Hash1: ', encode_json \%hash1 };
say "Oops - JSON encode error: $@" if $@;
my %hash2 = (
something => $item,
v_quoted => "$^V"
);
say 'Hash2: ', encode_json \%hash2;
# Running Perl version v5.34.0
# Oops - JSON encode error: encountered object 'v5.34.0',
# but neither allow_blessed, convert_blessed nor allow_tags
# settings are enabled (or TO_JSON/FREEZE method missing) at
# /Users/bw/Documents/Dev/tests/json_perl_version_test.pl line 17.
# Hash2: {"something":"Wut?","v_quoted":"v5.34.0"}
請注意,沒有必要參考 $item。
錯誤訊息指的是處理其他情況的一些方法,但似乎不包括規范的 Perl 版本點分十進制字串。我查看了主要的 Perl JSON 模塊(JSON::MaybeXS、JSON 和 Cpanel::JSON::XS 的最新版本),但找不到任何涉及 $^V 或點分十進制字串的內容。也找不到關于 SO 的相關問題 :(。
也許我錯過了什么?還是我堅持需要參考 $^V?
原因?
謝謝,
uj5u.com熱心網友回復:
$^V變數實際上是一個物件
Perl 解釋器的修訂、版本和顛覆,表示為版本物件。
一個物件不能就這樣存盤在 JSON 中。參考它會使它串起來。
可以使JSON::XS(及其Cpanel::)獲得祝福的參考,但它涉及更多的作業。請參閱物件序列化。最干凈的完整解決方案是使用convert_blessed,當該encode方法將查找一個TO_JSON方法(在要添加到 JSON 的物件的類中)時,該方法將回傳一個 JSON 就緒的字串。
version唉,對于(我嘗試過的其他一些課程也沒有,比如)沒有這樣的事情DateTime。可以將該方法添加到類中?,但只要考慮一下它就會使引號看起來不錯。
另一種方法是明確地使version物件字串化
my $json = JSON::XS->new->encode( { ver => $^V->stringify } )
這更加復雜,但至少現在很清楚問題是什么,沒有魔術引號。
或者只是參考它并添加評論。
? 例如,通過“猴子修補”它
添加具有完全限定名稱的子
perl -Mstrict -wE'use JSON::XS; say $^V; sub version::TO_JSON { return $_[0]->stringify }; my $json = JSON::XS->new->convert_blessed->encode( { ver => $^V } ); say $json'也可以在運行時通過字串添加子
eval,但這似乎不需要。在運行時撰寫對類符號表的代碼參考
perl -wE'use JSON::XS; say $^V; *{"version"."::"."TO_JSON"} = sub { return $_[0]->stringify }; $json = JSON::XS->new->convert_blessed->encode( { ver => $^V } ); say $json'好吧,或者實際上
strict我們需要允許符號參考perl -Mstrict -wE'use JSON::XS; say $^V; NO_STRICT_REFS: { no strict "refs"; my ($class, $method) = qw(version TO_JSON); *{$class."::".$method} = sub { return $_[0]->stringify } }; my $json = JSON::XS->new->convert_blessed->encode( { ver => $^V } ); say $json'我還為類名和方法添加了變數,這不是必需的,但更好。
或者,當然是通過撰寫一個包裝類或類似的東西,但那是另外一回事。
uj5u.com熱心網友回復:
Blessed Perl 物件不能在沒有額外步驟的情況下存盤在 JSON 中(錯誤中提到)。
print ref $^V; # version
一種可能的解決方法:
my $j = Cpanel::JSON::XS->new->convert_blessed; # Allow stringification.
say 'Hash1: ', $j->encode(\%hash1);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425570.html
