子程序是否应该明确返回?

BIG*_*OSE 2 oop perl function subroutine perl-critic

如果perlcritic说"没有子回报是错误的",如果真的不需要它们会有什么选择?

我养成了两个显然不好的习惯:

  • 我明确地将变量分配给'$ 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不是一直这样做的.但在上面,它是有道理的,因为我可以隔离操作,而不必担心来回传递值,它通常看起来整洁.

但正如我所说,perl评论家说错了 - 因为没有回报......

那么,是否有人能够解释我正在尝试做什么并建议在perl中采用这种编码风格的更好方法?例如.我有点做OOP吗?

Sob*_*que 6

简而言之 - 是的,你基本上都在做OO,但这种方式会让所有人感到困惑.

像这样做潜艇的危险在于你是在远距离行动.这是一个糟糕的编码风格,必须完全看看其他地方可能会破坏您的代码.

这通常是为什么尽可能避免"全局"的原因.

对于一个简短的脚本,也没关系太多太多.

关于返回值 - Perl默认返回最后一个表达式的结果.(参见:return)

(如果没有显式返回,子例程,eval或do FILE会自动返回最后一个表达式的值.)

Perl评论家标记它的原因是:

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

在其末尾没有显式返回语句的子例程可能会令人困惑.推断返回值将是多么具有挑战性.

此外,如果程序员并不意味着存在重要的返回值,并且省略了return语句,则某些子例程的内部数据可能泄漏到外部.

Perlcritic并不总是正确的 - 如果有充分的理由去做你正在做的事情,那就把它关掉.只要你已经考虑过它并且意识到风险会产生后果.

就个人而言,我认为明确返回某些东西的风格更好,即使它只是return;.

无论如何,以(粗)OO方式重新绘制代码:

#!/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;
Run Code Online (Sandbox Code Playgroud)

然后调用它:

#!/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";
Run Code Online (Sandbox Code Playgroud)

它可能可以整理一下,但希望这说明 - 在你的对象中,你有一个内部的'数组',然后通过打电话你"做".

结果大致相同(我认为我已经复制了逻辑,但完全不相信!)但是你有一个自包含的东西.