欢迎来到 Perl。我希望你有一个愉快的学习和使用它。
谈生意,从哪里开始?我在这里有很多话要说。
首先,通过评估文件来加载数据是不必要的风险。如果您只想序列化数据,请尝试JSON::XS或YAML,甚至Storable。如果你想要一个配置文件,CPAN 上有很多很多模块可以帮助完成这项任务。查看Config::Any。
如果您想创建通过 eval 加载的数据结构(这不是一个好主意),Data::Dumper会生成创建您提供给它的任何数据结构所需的 perl 代码。我提到它的主要原因是它作为调试辅助工具比序列化程序更有用。
既然已经处理好了,如果你想加载一个文件并评估它(再次强调,在几乎所有情况下都不是最好的主意),你应该看看do或require。
my $stuff = do 'address.pl';
但不要那样做。Stringeval
是一个最好不要使用的工具。99% 的情况下,如果您打算使用字符串 eval,请停下来考虑另一种解决问题的方法。Do 是一个隐式评估,所以它也很重要。
Perl 为您提供了许多工具来执行冒险而强大的魔法。成为熟练的 Perl 编程的很大一部分在于了解哪些事情是有风险的,为什么以及何时使用它们是有意义的。不要指望 Perl 会用栅栏和大门来保护你的安全。认真考虑拿起一本Effective Perl Programming或Perl Best Practices。作为一个新手,当你第一次阅读时,很多东西会让你头疼,但是随着你的成长和学习,这两本书都可以成为很好的参考。
下一个话题,你到底想用所有这些转义的引号来实现什么?看着那些东西我就头疼!Perl 有一些非常非常好的引用运算符,您可以使用它们来避免在文字字符串中处理转义引号。
or 粗逗号自动引用其=>
左侧 (LHS),就好像它只是字母数字一样。但是把所有的引号和转义符放在一起会让事情变得非常狡猾。
当您说 时\'address\' => {}
,Perl 将其视为\
应用于字符串文字的“获取引用”运算符。在这种情况下,一个未终止的字符串文字,因为您永远不会'
在第一个之后提供未转义的字符串。
如果您的目标是使用'address'
, quotes 和 all 作为您的哈希键,您可以这样做:
my %foo = ( "'address'" => 'blah' );
如果您不想要引号,这似乎是一个更常见的用例,只需执行以下操作:
my %foo = ( address => 'blah' );
关于您收到的错误消息!一旦你了解了它们的含义,Perl 就会有一些非常好的错误消息。在那之前,要理解它们的重要性可能有点困难。幸运的是,Perl 附带了一个名为splain
: 的脚本,这是一个方便的花花公子工具,可以更详细地解释错误消息。您还可以使用诊断模块自动获取相同的扩展错误消息。
现在,如果我正在写这篇文章,我会按照以下方式做一些事情:
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 教程。作为初学者,我发现perlfunc 的 Perl Functions by Category 部分非常有用。
我想我会停下来,因为我已经写了足够多的文字来让普通人失明。我希望你觉得这篇论文有帮助。再次欢迎您,晚上好(当您找到此回复时,请调整您的当地时间)。