【发布时间】:2021-10-10 21:16:34
【问题描述】:
我有一个子例程csay,它在 Perl 类(包)中定义。它有几个子类经常和自始至终运行该子例程。它的行为取决于一些变量(其中大部分必须作为参数给出),其中一个在任何词法范围内都是常量($debug_level)。我试图尽可能避免重复代码,包括每次都必须将“常量”变量作为参数传递或在每次使用前加上 $self->。
我不反对使用编译时替换(如果 Perl 中存在这种情况),但我想尽可能避免使用实例(blessing 哈希等)。请参阅下面的示例,了解我正在尝试做的事情。有什么想法吗?
package SystemManager::Action::Generic;
sub csay($self, $cur_debug_level, $min_debug_level, $message) {
if ($cur_debug_level >= $min_debug_level) { print("$message\n"); }
}
sub prepare_system($self)...
package SystemManager::Action::Backup;
use parent "SystemManager::Action::Generic";
sub backup_system($self,$debug_level,@files) {
$self->csay($debug_level, 1, "Starting backup");
$self->prepare_system();
$self->csay($debug_level, 1, "Iterating through files");
for my $file in (@files) {
$self->csay($debug_level, 2, "Processing $file");
...
}
...
}
csay 不需要 属于同一类;最重要的部分是不必每次都指定 $debug_level 作为参数。
【问题讨论】:
-
你为什么不想在每个用法前加上
$self->?这对我来说似乎是正确的模式:如果csay依赖于调用它的对象的上下文,那么它实际上是一个方法,而不是一个子例程。没有? -
了解每种语言都有共同的习语很重要,如果你遵循这些习语,那么你必然会“复制”它们。这不是人们谈论消除代码重复时的意思。你不想在一堆地方复制实际的 logic,但是在你想调用
csay的任何地方写$self->csay(...)是一种常见的模式,实际上并不是在感觉你应该避免。 -
@ruakh 这主要是一种偏好,但这样做不会破坏交易。我没有意识到包/“类”子例程也称为方法,但我认为您是对的,但是
csay不需要任何无法作为参数提供的信息。我正在使用类和子类来获得更大的灵活性。 -
Re "我正在使用类和子类以获得更大的灵活性。",您的问题特别要求不要使用对象,这实际上是一个非常合理的解决方案到问题。你还说你不想使用调用者,它排除了类和对象。
-
请提供一个最小示例来澄清您的问题。请参阅minimal reproducible example 了解更多信息
标签: function class perl subclass code-duplication