下面是.pm文件中的Perl代码,它应该用一些值替换指定的字符串(在"引号"中)。但它没有发生。谁能解释一下这段代码中发生了什么?
package SomePackage;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(send_request, create_mmd_and_transfer, update_mmd_file);
sub send_request {
my ( $service, $action, $torole ) = @_;
my ( $seller_request_mmd );
my $replace_contents = ();
$replace_contents{"REPLACE_Service"} = $service;
$replace_contents{"REPLACE_RequestAction"} = $action;
$replace_contents{"REPLACE_TradingPartner"} = $torole;
$replace_contents{"REPLACE_Requestxml"} = "Request.xml";
create_mmd_and_transfer( \%replace_contents, $seller_request_mmd, "/MMD.xml" );
}
sub create_mmd_and_transfer {
my $local_replace_contents = shift;
my $input_mmd = shift;
my $local_output_mmd = shift;
my $output_mmd = shift;
update_mmd_file( "$input_mmd", "temp_mmd_file.xml", $local_replace_contents );
}
sub update_mmd_file {
my $input_file = shift;
my $output_file = shift;
my $contents = shift;
open( MMD_FILE, "<$input_file" )
or main::error_exit(" Cannot open MMD file template $input_file \n $input_file not found int the Templates folder \n Please place the same and then run the script ");
open( TEMP_MMD_FILE, ">$output_file" );
while ( <MMD_FILE> ) {
s/^M//g; # Getrid of the ^Ms
foreach my $content ( keys( %$contents ) ) {
my $exact_value = ${%$contents}{$content};
if ( $main::test_scenario =~ /^Invalid Request Action \a\n\d Service/
and ( $content =~ /REPLACE_Service|REPLACE_RequestAction/i ) ) {
}
else {
if ( $exact_value ne "" ) {
s/$content/$exact_value/g;
}
}
}
print TEMP_MMD_FILE;
}
close MMD_FILE;
close TEMP_MMD_FILE;
}
答案 0 :(得分:0)
以下内容不会使您的脚本有效,只需为以后的某些问题创建更好的基础。
在您考虑在此处发布perl
问题之前:
1。)添加到脚本的顶部:
use strict;
use warnings;
在没有这两行的情况下在这里发布代码,没有人会打扰甚至尝试阅读代码。
2.)使用perl -c SomePackage.pm
进行检查。如果它会告诉您:SomePackage.pm syntax OK
- 您可以开始考虑在此处发布问题。 ;)
脚本的一些基本问题:
package SomePackage;
use strict; # see the above
use warnings;
require Exporter;
# these variables are defined outside of this package, so, tell perl this fact. use the `our`
our @ISA = qw(Exporter);
#the use warnings will warn you about the following line
# @EXPORT = qw(send_request, create_mmd_and_transfer, update_mmd_file);
#the correct one is without commas
our @EXPORT = qw(send_request create_mmd_and_transfer update_mmd_file); #not saying anything about the @EXPORT rudeness. :)
#my $replace_contents = ();
#the $replace_contents is a scalar. Bellow you using a hash. So,
my %replace_contents;
#or use the scalar but the lines bellow should use the hashref notation, e.g.
# $replace_contents->{"REPLACE_Service"} = $service;
# you decide. :)
# the seller_request_mmd contains undef here.
create_mmd_and_transfer( \%replace_contents, $seller_request_mmd, "/MMD.xml");
# also bellow, in the subroutine definition it wants 4 arguments.
# indicates a problem...
# using 2-arg open is not the best practice.
# Also, you should to use lexical filehandles
# open (MMD_FILE, "<$input_file")
# better
open (my $mmd_file, '<', $input_file)
# of course, you need change every MMD_FILE to $mmd_file
# check the result of the open and die if not successful
# or you can use the
use autodie;
# instead of $exact_value = ${%$contents}{$content};
# you probably want
my $exact_value = $contents->{$content};
缩进你的代码!
以上所有内容都是关于语法问题而不解决有关代码“逻辑”的任何问题。
Ps:我还是初学者,所以,其他人肯定会发现上述代码存在更多问题。
答案 1 :(得分:0)
确定。以下是我为测试这一点所做的工作。
首先,您没有提供输入文件或用于调用模块的代码。所以我发明了它们。我做了最简单的输入文件:
REPLACE_Service
REPLACE_RequestAction
REPLACE_TradingPartner
REPLACE_Requestxml
这个驱动程序:
#!/usr/bin/perl
use strict;
use warnings;
use SomePackage;
send_request('foo', 'bar', 'baz');
sub error_exit {
die @_;
}
第一次,我跑了,我收到了这个错误:
在测试线8处调用未定义的子程序&amp; main :: send_request。
那是因为你的@EXPORT
行错了。你有:
@EXPORT = qw(send_request, create_mmd_and_transfer, update_mmd_file);
但qw(...)
的要点是你不需要逗号。所以我纠正了:
@EXPORT = qw(send_request create_mmd_and_transfer update_mmd_file);
然后我重新运行程序并得到了这个错误:
无法打开MMD文件模板
找不到Templates文件夹 请放置相同的内容,然后在测试第11行运行脚本。
看起来有些东西不见了。我更改了错误消息,添加了变量插值应该发生的位置的指示符:
open( MMD_FILE, "<$input_file" )
or main::error_exit(" Cannot open MMD file template <$input_file> \n <$input_file> not found int the Templates folder \n Please place the same and then run the script ");
然后错误消息如下所示:
无法打开MMD文件模板&lt;&gt; &LT;&GT;找不到Templates文件夹 请放置相同的内容,然后在测试第11行运行脚本。
所以很明显$input_file
子程序中没有设置update_mmd_file()
变量。追溯该变量后,我们发现此值最初是$seller_request_mmd
中的send_request()
变量。但是在send_request()
中,您声明$seller_request_mmd
,但您从未给它赋值。让我们这样做:
my ( $seller_request_mmd ) = 'test_input.txt';
现在,当我运行你的程序时,它运行完成没有任何错误。我发现生成了一个新的temp_mmd_file.xml
。但它与输入文件完全相同。因此需要进行更多调查。
深入研究update_mmd_file()
子程序,我们发现了这条有趣的路线:
my $exact_value = ${%$contents}{$content};
我认为您正在尝试从$contents
中提取值,这是一个哈希引用。但是你的语法错了。你可能的目标是:
my $exact_value = ${$contents}{$content};
但大多数Perl程序员更喜欢使用箭头符号来处理参考查找。
my $exact_value = $contents->{$content};
进行更改并重新运行程序,我得到一个包含以下内容的输出文件:
foo
bar
baz
Request.xml
这正是我的预期。所以该计划现在有效。
但仍有许多工作要做。正如你多次被告知的那样,你应该总是添加:
use strict;
use warnings;
代码。这会在您的代码中发现许多潜在的问题 - 您应该修复它们。
说实话,这对我来说就像你在行走前试图跑步一样。我建议花一些时间在a good Perl introductory book之前完成我的更多Perl工作。
您的问题中缺少许多有用的信息。如果您向我们展示了您的驱动程序和输入数据,那么找到解决方案的时间不会太长。