Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 确定一个程序并用不同的程序替换_Perl - Fatal编程技术网

Perl 确定一个程序并用不同的程序替换

Perl 确定一个程序并用不同的程序替换,perl,Perl,我想要达到的目标: ###############CODE######## old_procedure(arg1, arg2); #############CODE_END###### 我有一个巨大的代码,其中有一个旧的过程。我希望对旧_过程的调用转到对具有相同参数的新过程(新_过程(arg1,arg2))的调用。 现在我知道了,这个问题看起来很愚蠢,但诀窍是不允许我更改代码或坏函数。所以我唯一能做的就是在外部创建一个过程,读取代码流或其他东西,然后每当它发现坏的函数时,就用新的函数替换它。它

我想要达到的目标:

###############CODE########
old_procedure(arg1, arg2);
#############CODE_END######
我有一个巨大的代码,其中有一个旧的过程。我希望对旧_过程的调用转到对具有相同参数的新过程(新_过程(arg1,arg2))的调用。 现在我知道了,这个问题看起来很愚蠢,但诀窍是不允许我更改代码或坏函数。所以我唯一能做的就是在外部创建一个过程,读取代码流或其他东西,然后每当它发现坏的函数时,就用新的函数替换它。它们有一个void类型,因此不必担心返回值。 我正在使用perl。如果有人知道如何至少从这个方向开始…请评论或回答。如果新代码可以用perl或C编写就好了,但其他已知语言也不错。C++,java,< /P> 编辑:代码是用shell脚本和perl编写的。我不能编辑代码,我没有旧函数的位置,我的意思是我可以找到它…但它真的很难。所以我可以使用前面提到的包,但是如果有办法的话……这样我就可以用那个函数解析线程并替换函数调用。请不要删除标签,因为我需要从java,C++专家的建议。 编辑:@mirod 所以我试过了,你的答案生成了一个新的子程序,现在没有办法访问旧的子程序。我已经创建了一个变量,该变量检查值以决定采用哪种方式(旧的_sub或新的_sub)…是否有办法在新代码中添加该变量…如果未设置,它会将控件发送回旧的_函数。。。 比如:


这些被称为自动重构工具,在其他语言中很常见。对于Perl来说,这可能是一种非常糟糕的方式,因为解析Perl以查找所有引用几乎是不可能的。

这些被称为自动重构工具,在其他语言中很常见。但是对于Perl,您可能会遇到非常糟糕的情况,因为解析Perl以查找所有引用几乎是不可能的。

sed-i's/old\u procedure/new\u procedure/g codefile


这就是你的意思吗?

sed-i的/old\u过程/new\u过程/g代码文件


这就是你的意思吗?

旧程序是在哪里定义的

如果它是在包中定义的,您可以切换到包,在它被
使用
d后,重新定义子包:

use BadPackage; # sub is defined there
BEGIN
{ package BapPackage;
  no warnings; # to avoid the "Subroutine bad_sub redefined" message
  sub bad_sub
    { # good code
    }
}
如果代码在同一个包中,但在不同的文件中(通过
require
加载),则无需切换包即可执行相同的操作


如果所有代码都在同一个文件中,则更改它

旧程序在哪里定义

如果它是在包中定义的,您可以切换到包,在它被
使用
d后,重新定义子包:

use BadPackage; # sub is defined there
BEGIN
{ package BapPackage;
  no warnings; # to avoid the "Subroutine bad_sub redefined" message
  sub bad_sub
    { # good code
    }
}
如果代码在同一个包中,但在不同的文件中(通过
require
加载),则无需切换包即可执行相同的操作


如果所有代码都在同一个文件中,则更改它

这在Perl中比在许多其他语言中更容易做到,但这并不意味着这很容易,我不知道这是否是您想要听到的。以下是概念证明:

让我们看一些坏代码:

# file name: Some/Package.pm
package Some::Package;
use base 'Exporter';
our @EXPORT = qw(forty_two nineteen);
sub forty_two { 19 }
sub nineteen { 19 }
1;

# file name: main.pl
use Some::Package;
print "forty-two plus nineteen is ", forty_two() + nineteen();
运行程序
perl main.pl
生成输出:

forty-two plus nineteen is 38
假定文件
Some/Package.pm
main.pl
已损坏且不可更改。我们如何纠正他们的行为

perl
命令插入任意代码的一种方法是使用
-M
命令行开关。让我们制作一个修复模块:

# file: MyRepairs.pm
CHECK {
    no warnings 'redefine';  
    *forty_two = *Some::Package::forty_two = sub { 42 };
};
1;
现在运行程序perl-MMyRepairs main.pl
生成:

forty-two plus nineteen is 61
我们的修复模块使用
CHECK
块在编译时和运行时阶段之间执行代码。我们希望我们的代码是编译时运行的最后一个代码,这样它将覆盖一些已经加载的函数。
-M
命令行开关将首先运行我们的代码,因此
CHECK
块将延迟修复的执行,直到运行所有其他编译时代码。有关更多详细信息,请参阅

这个解决方案是脆弱的。对于在运行时加载的模块(使用
require…
eval“use…”
(这些是常见的)或在其他
CHECK
块中定义的子例程(这些是罕见的),它无能为力

如果我们假设运行
main.pl
的shell脚本也是不可变的(即,我们不允许将
perl main.pl
更改为
perl-MMyRepairs main.pl
),那么我们将向上移动一级,并在
PERL5OPT
环境变量中传递
-MMyRepairs

PERL5OPT="-I/path/to/MyRepairs -MMyRepairs" bash the_immutable_script_that_calls_main_pl.sh

这在Perl中比在许多其他语言中更容易实现,但这并不意味着这很容易,而且我不知道这是否是您想要听到的。下面是一个概念证明:

让我们看一些坏代码:

# file name: Some/Package.pm
package Some::Package;
use base 'Exporter';
our @EXPORT = qw(forty_two nineteen);
sub forty_two { 19 }
sub nineteen { 19 }
1;

# file name: main.pl
use Some::Package;
print "forty-two plus nineteen is ", forty_two() + nineteen();
运行程序
perl main.pl
生成输出:

forty-two plus nineteen is 38
假定文件
Some/Package.pm
main.pl
已损坏且不可更改。我们如何修复它们的行为

我们可以向
perl
命令插入任意代码的一种方法是使用
-M
命令行开关

# file: MyRepairs.pm
CHECK {
    no warnings 'redefine';  
    *forty_two = *Some::Package::forty_two = sub { 42 };
};
1;
现在运行程序perl-MMyRepairs main.pl
生成:

forty-two plus nineteen is 61
我们的修复模块使用
CHECK
块在编译时和运行时阶段之间执行代码。我们希望我们的代码是在编译时运行的最后一个代码,这样它将覆盖一些已经加载的函数。
-M
命令行开关将首先运行我们的代码,因此
CHECK
块延迟执行在所有其他编译时代码运行之前,我们将执行修复。有关更多详细信息,请参阅

此解决方案是脆弱的。对于在运行时加载的模块(使用
require…
eval“use…”
(这些是常见的)或在其他
检查中定义的子例程,它无能为力