歡迎來到Perl。我希望你有一個很好的學習和使用它的時間。
就業務,從哪裏開始?我在這裏有很多要說的。
首先,這是不必要的冒險通過評估文件加載數據。如果您只想要序列化數據,請嘗試使用JSON::XS或YAML,或者甚至使用Storable。如果你想要一個配置文件,CPAN上有許多模塊可以幫助完成這項任務。檢查出Config::Any。
如果你想創建數據結構來通過eval加載(這不是一個好主意),Data::Dumper會生成創建任何數據結構所需的perl代碼。我提到它的主要原因是它比串行器更有用作爲調試輔助工具。
現在該是照顧的,如果要加載一個文件,並評估它(同樣,沒有最好在幾乎所有情況下的想法),你應該看do或require。
my $stuff = do 'address.pl';
但是不這樣做。字符串eval
是一種通常最好未使用的工具。 99%的時間,如果您打算使用字符串評估,請停下來思考解決問題的另一種方法。 Do是一個隱含的eval,所以它也是很重要的。
的Perl爲您提供了大量的工具做有風險的,強大的魔法。成爲高級Perl編程的很大一部分在於理解哪些事情是有風險的,爲什麼以及何時使用它們是有意義的。不要指望Perl用圍牆和大門來保護你,以保證你的安全。認真考慮拿起Effective Perl Programming或Perl Best Practices的副本。作爲一個新手,第一次閱讀時會有很多事情要做,但是隨着你的成長和學習,任何一本書都可以成爲一個很好的參考。
下一個話題,你試圖用所有那些逃脫的引號實現世界上的什麼?看着那些東西讓我頭痛! Perl有some very, very nice quoting operators,您可以使用它來避免在文字字符串中亂用引號。
=>
或胖逗號會自動引用左手邊(LHS),就像它只是字母數字一樣。但是,把所有的引號和逃脫都讓事情變得非常狡猾。
當您說\'address\' => {}
時,Perl將此視爲\
,即將「get reference」運算符應用於字符串文字。在這種情況下,一個未終止的字符串文字,因爲你從未提供第一個之後未轉義的'
。
如果你的目標是利用'address'
,報價和全部作爲哈希鍵,你可以這樣做:
my %foo = ("'address'" => 'blah');
如果你不想引號,這似乎是一個更爲通常使用的情況下,簡單地做:
my %foo = (address => 'blah');
對您收到的錯誤消息!一旦你瞭解了它們的含義,Perl就會有一些相當不錯的錯誤消息。在此之前,理解它們的意義可能有點困難。幸運的是,Perl帶有一個名爲splain
的腳本:一個方便的花花公子工具,可以更詳細地解釋錯誤消息。您也可以使用diagnostics模塊自動獲取相同的擴展錯誤消息。現在
,如果我寫這個,我會做一些事情沿着這些路線:
gen_schema_files.pl - 寫JSON模式文件的文件。如果你願意,你可以手工編輯你的模式。如果您想提高可讀性,您可能還希望將輸出配置爲更漂亮。
#!/usr/bin/perl
use JSON::XS;
use File::Spec;
use constant BASEDIR => '.';
# Key is the file name, value is the data to put into the file.
my %schemata = (
'address.json' => {
address => {
street => { __type => 'String' },
unit => {
__type => 'String',
__validation_function => { is_a_number => '' },
__schema_constraints => { is_not_null => '' }
},
suburb => { __type => 'String' },
__type => 'ARRAY'
},
},
'person_contact.json' => {
firstname => { __type => 'String' },
lastname => { __type => 'String' },
# Use a special key to indicate that additional files should be
# loaded into this hash.
INCLUDE => [qw(address.json)],
},
# And so forth
);
for my $schema (keys %schemata) {
my $path = File::Spec->catfile(BASEDIR, $schema);
open my $fh, '>', $path
or die "Error opening '$path' for writing - $!\n";
print $fh encode_json $schemata{$schema};
}
load_schemas.pl - 這是加載模式和做的東西的代碼。我的只能被加載。我不知道你正在處理數據的方式...
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use JSON::XS;
use File::Spec;
use constant BASEDIR => '.';
my $schema = load_schema('person_contact.json');
print Dumper $schema;
sub load_schema {
my $file = shift;
my $path = File::Spec->catfile(BASEDIR, $file);
open my $fh, '<', $path
or die "Error opening file '$path' - $!\n";
my $json = join '', <$fh>; # reads a list of lines and cats them into one string.
# One way to slurp out of many.
my $schema = decode_json($json);
# Handle the inclusion stuff:
if(exists $schema->{INCLUDE}) {
# Copy the files to load into an array.
my @loadme = @{$schema->{INCLUDE}};
# delete the magic special include key.
delete $schema->{INCLUDE};
# Load each file and copy it into the schema hash.
for my $load (@loadme) {
my $loaded = load_schema($load);
# This is a bit of weird syntax.
# We are using a hash slice assignment to copy the loaded data into the existing hash.
# keys and values are guaranteed to come out in the same (random) order as each other.
# the @{$foo}{blahbhal} is how you dereference a hash reference as a slice.
@{$schema}{keys %$loaded} = values %$loaded;
}
}
return $schema;
}
我已經掩蓋了一些東西,但我試過有足夠的條件(詞彙,甚至行話要發表評論,如果你喜歡)讓你做有利可圖的搜索。
上面的代碼有幾個缺陷。它不會檢查循環包含(它會運行很長時間,最終會填滿內存和崩潰 - 不太好)。魔術鑰匙的選擇可能不太好。還有更多我還沒有想到。
Perldoc是一個了不起的資源,但有這麼多,需要一段時間才能學會找東西。看看Perl Data Structures Cookbook和Arrays of Arrays tutorial。作爲初學者,我發現Perl Functions by Category section of perlfunc非常有幫助。
我想我會停下來,現在我已經寫了足夠多的文字來讓一般人失明。我希望你覺得這篇論文有用。再次歡迎,晚上好(請在適應當地時間的情況下調整,以便找到答案)。
無需逐行閱讀。通過在讀取文件之前加入`local $ /;`來使用「slurp模式」,並將`while(my $ line ...)`改爲`my $ line = <$fh>;``。 – Mikel 2011-01-24 04:35:21