子例程是否应该始终显式返回?

2024-02-14

If perlcritic http://www.perlcritic.org/说“子项中没有返回值是错误的”,如果确实不需要它们,还有什么选择?

我养成了两个明显的坏习惯:

  • 我显式地将变量分配给“$main::”命名空间。
  • 然后我在 subs 中使用这些变量。

例如,我可能会做..

#!/usr/bin/perl
use strict;
use warnings;

@main::array = (1,4,2,6,1,8,5,5,2);

&sort_array;
&push_array;
&pop_array;

sub sort_array{
    @main::array = sort @main::array;
    for (@main::array){
        print "$_\n";
    }
}

sub push_array{
    for ( 1 .. 9 ){
        push @main::array, $_;
    }
}

sub pop_array {
    for ( 1 .. 3 ){
        pop @main::array;
    }
}

我并不总是这样做。但在上面,这是有道理的,因为我可以隔离操作,不必担心来回传递值,而且对我来说通常看起来很整洁。

但正如我所说,perl 批评者说这是错误的 - 因为没有回报。

那么,有谁能够解释我正在尝试做的事情,并提出一种更好的方法来处理这种 Perl 编码风格?例如。我是在做 OOP 吗?


简而言之,是的,您基本上是在进行面向对象,但在某种程度上这会让每个人感到困惑。

像这样做替补的危险在于你是在远处行动。必须完全从其他地方寻找可能破坏代码的内容,这是一种糟糕的编码风格。

这通常就是尽可能避免使用“全局变量”的原因。

对于一个简短的脚本来说,这并不重要too much.

关于返回值 - Perl 默认返回最后一个表达式的结果。 (看:return http://perldoc.perl.org/functions/return.html)

(在没有显式返回的情况下,子例程、eval 或 do FILE 自动返回最后计算的表达式的值。)

原因Perl 评论家 http://search.cpan.org/%7Ethaljef/Perl-Critic-1.123/lib/Perl/Critic/Policy/Subroutines/RequireFinalReturn.pm标志它是:

要求所有子例程使用以下之一显式终止:return、carp、croak、die、exec、exit、goto 或 throw。

末尾没有显式 return 语句的子例程可能会令人困惑。推断返回值可能具有挑战性。

此外,如果程序员无意有一个重要的返回值,并且省略了返回语句,则子例程的一些内部数据可能会泄漏到外部。

但 Perlcritic 并不总是正确的 - 如果有充分的理由做你正在做的事情,那么就将其关闭。只要您考虑过并意识到风险和后果即可。

就我个人而言,我认为显式返回某些内容是更好的风格,即使它只是return;.

不管怎样,以(粗略的)面向对象的方式重新起草你的代码:

#!/usr/bin/perl
use strict;
use warnings;

package MyArray;

my $default_array = [ 1,4,2,6,1,8,5,5,2 ];

sub new {
   my ( $class ) = @_;
   my $self = {};
   $self -> {myarray} = $default_array;
   bless ( $self, $class );
   return $self;
}

sub get_array { 
   my ( $self ) = @_;
   return ( $self -> {myarray} ); 
}

sub sort_array{
    my ( $self ) = @_;
    @{ $self -> {myarray} } = sort ( @{ $self -> {myarray} } );
    
    for ( @{ $self -> {myarray} } ) {
        print $_,"\n";
    }
    return 1;
}

sub push_array{
    my ( $self ) = @_;
    for ( 1 .. 9 ){
        push @{$self -> {myarray}}, $_;
    }
    return 1;
}

sub pop_array {
    my ( $self ) = @_;
    for ( 1 .. 3 ){
        pop @{$self -> {myarray}};
    }
    return 1;
}

1;

然后用以下命令调用它:

#!/usr/bin/perl

use strict;
use warnings;

use MyArray;

my $array = MyArray -> new();

print "Started:\n";
print join (",", @{ $array -> get_array()} ),"\n";

print "Reshuffling:\n";
$array -> sort_array();

$array -> push_array();
$array -> pop_array();

print "Finished:\n";
print join (",", @{ $array -> get_array()} ),"\n";

它可能可以整理一下,但希望这说明了 - 在你的对象中,你有一个内部“数组”,然后你可以通过调用来“做一些事情”。

结果大致相同(我想我已经复制了逻辑,但不要完全相信这一点!)但是你有一个独立的事情正在发生。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子例程是否应该始终显式返回? 的相关文章

随机推荐