一个子程序是否总是显式返回? [英] Should a subroutine always return explicitly?

查看:133
本文介绍了一个子程序是否总是显式返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果 perlcritic 说没有回报一个子是错误的,如果他们真的不需要的话,有什么选择?

我开发了两个显然不好的习惯:


  • 我将变量明确地分配给'$ main ::'命名空间。

  • 然后我在subs中使用这些变量。 li>


例如,我可能会这样做。

 #!/ usr / bin / perl 
use strict;
使用警告;

@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$ _\\\
;



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



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

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



但是正如我所说,perl评论家说它是错误的 - 因为没有回报。所以,任何人都可以解释我正在尝试做什么,并提出更好的方法在Perl中接近这种编码风格?例如。我有点做OOP吗?

解决方案

简而言之 - 是的,你基本上在做OO,但以某种方式混淆每个人。



做这样的潜艇的危险是你在远处行事。这是一种糟糕的编码风格,必须完全查找可能会破坏代码的其他位置。



这就是为什么要尽可能避免使用全局变量的原因。



对于一个简短的脚本, 太不重要了。

关于返回值 - Perl默认返回最后一个表达式的结果。 (请参阅: return


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


原因 Perl评论家标记为:


要求所有子程序通过以下一种方式显式终止:return,carp,croak,die,exec,exit,goto或throw。

子程序没有显式返回语句他们的目的可能会让人困惑。此外,如果程序员不意味着存在显着的返回值,并且省略了返回语句,一些子程序的内部数据可能会泄漏到外面。


Percerritic并不总是正确的 - 如果有充分的理由做你在做什么,然后关掉它。就在你考虑过它并意识到风险后果的时候。



就我个人而言,我认为明确地返回某些东西的样式会更好,即使它只是 return;



无论如何,以粗略的OO方式重新编写代码:

 # !/ usr / bin / perl 
使用strict;
使用警告;

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);
返回$ self;
}

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

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


}
返回1;
}

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

sub pop_array {
my($ self)= @_;
(1 .. 3){
pop @ {$ self - > {myArray的}};
}
返回1;
}

1;

然后调用它:

 #!/ usr / bin / perl 

use strict;
使用警告;

使用MyArray;

my $ array = MyArray - >新();

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

printReshuffling:\\\
;
$ array - > sort_array();

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

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

大概可以整理一下,但希望这可以说明 - 在您的物体中,得到一个内部的数组,然后通过拨打电话随意。

结果是一样的(我想我已经复制了逻辑,但完全不相信!),但是你有一个独立的事情在继续。

If perlcritic says "having no returns in a sub is wrong", what is the alternative if they really aren't needed?

I've developed two apparently bad habits:

  • I explicitly assign variables to the '$main::' namespace.
  • I then play with those variables in subs.

For example, I might do..

#!/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;
    }
}

I don't do this all the time. But in the above, it makes sense, because I can segregate the operations, not have to worry about passing values back and forth and it generally looks tidy to me.

But as I said, perl critic says its wrong - because there's no return..

So, is anyone able to interpret what I'm trying to do and suggest a better way of approaching this style of coding in perl? eg. am I sort of doing OOP?

解决方案

In short - yes, you're basically doing OO, but in a way that's going to confuse everyone.

The danger of doing subs like that is that you're acting at a distance. It's a bad coding style to have to look somewhere else entirely for what might be breaking your code.

This is generally why 'globals' are to be avoided wherever possible.

For a short script, it doesn't matter too much.

Regarding return values - Perl returns the result of the last expression by default. (See: return)

(In the absence of an explicit return, a subroutine, eval, or do FILE automatically returns the value of the last expression evaluated.)

The reason Perl critic flags it is:

Require all subroutines to terminate explicitly with one of the following: return, carp, croak, die, exec, exit, goto, or throw.

Subroutines without explicit return statements at their ends can be confusing. It can be challenging to deduce what the return value will be.

Furthermore, if the programmer did not mean for there to be a significant return value, and omits a return statement, some of the subroutine's inner data can leak to the outside.

Perlcritic isn't always right though - if there's good reason for doing what you're doing, then turn it off. Just as long as you've thought about it and are aware of the risks an consequences.

Personally I think it's better style to explicitly return something, even if it is just return;.

Anyway, redrafting your code in a (crude) OO fashion:

#!/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;

And then call it with:

#!/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";

It can probably be tidied up a bit, but hopefully this illustrates - within your object, you've got an internal 'array' which you then 'do stuff with' by making your calls.

Result is much the same (I think I've replicated the logic, but don't trust that entirely!) but you have a self contained thing going on.

这篇关于一个子程序是否总是显式返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆