Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.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_Pass By Reference - Fatal编程技术网

在Perl中仅通过引用传递一些子例程参数

在Perl中仅通过引用传递一些子例程参数,perl,pass-by-reference,Perl,Pass By Reference,我正在写一个包含许多参数的子程序。大多数参数都是标准的按值传递排序,在子例程中对它们所做的更改在子例程之外并不重要。但其中一个是一个对象(祝福引用),我想对其进行更改,如果传入的话,可以在子例程之外进行更改。如果没有传入,我想实例化它,并以传入的方式处理它(但最终返回它) 例如: 我希望使用尽可能干净的语法来实现这一点,并且我可以使用PerlV5.22及更高版本中提供的任何功能。(我已经尝试过使用重构来解决这个问题,但它不是很干净。) 我缺少什么?首先,子程序参数总是通过引用传递 $ pe

我正在写一个包含许多参数的子程序。大多数参数都是标准的按值传递排序,在子例程中对它们所做的更改在子例程之外并不重要。但其中一个是一个对象(祝福引用),我想对其进行更改,如果传入的话,可以在子例程之外进行更改。如果没有传入,我想实例化它,并以传入的方式处理它(但最终返回它)

例如:




我希望使用尽可能干净的语法来实现这一点,并且我可以使用PerlV5.22及更高版本中提供的任何功能。(我已经尝试过使用
重构
来解决这个问题,但它不是很干净。)


我缺少什么?

首先,子程序参数总是通过引用传递

$ perl -e'sub f { $_[0] = "def"; }   my $x = "abc"; f($x); CORE::say $x;'
def
更重要的是,您的代码完全符合您的要求

$ perl -e'
    {
        package Private::Foo;

        sub new { my $class = shift; bless({ something => "old_value" }, $class) }

        sub do_things {
            my ($self, $arg1, $arg2, $foo) = @_;

            unless (defined $foo) {
                 $foo = Private::Foo->new();
            }

            if ($arg1 eq "abc") {
                $foo->{something} = "new value";
                return;
            }

            return $foo;
        }
    }

    use feature qw( say );

    my $foo = Private::Foo->new();
    Private::Foo->do_things("abc", "xyz", $foo);
    say $foo->{something};

    my $foo2 = Private::Foo->do_things("def");
    say $foo2->{something};
'
new value
old_value
也就是说,您可以通过以下方式清理您的方法:

sub do_things {
    my ($class, $arg1, $arg2, $foo) = @_;

    $foo //= $class->new();

    if ($arg1 eq 'abc') {
        $foo->{something} = 'new value';
    }

    return $foo;
}
如果你清理一下你的通话习惯,那就更好了

Private::Foo->do_something($arg1, $arg2, $foo);

my $foo2 = Private::Foo->do_something($arg1, $arg2);
远不如

$foo->do_something($arg1, $arg2);

( my $foo2 = Private::Foo->new )->do_something($arg1, $arg2);

首先,子例程参数总是通过引用传递

$ perl -e'sub f { $_[0] = "def"; }   my $x = "abc"; f($x); CORE::say $x;'
def
更重要的是,您的代码完全符合您的要求

$ perl -e'
    {
        package Private::Foo;

        sub new { my $class = shift; bless({ something => "old_value" }, $class) }

        sub do_things {
            my ($self, $arg1, $arg2, $foo) = @_;

            unless (defined $foo) {
                 $foo = Private::Foo->new();
            }

            if ($arg1 eq "abc") {
                $foo->{something} = "new value";
                return;
            }

            return $foo;
        }
    }

    use feature qw( say );

    my $foo = Private::Foo->new();
    Private::Foo->do_things("abc", "xyz", $foo);
    say $foo->{something};

    my $foo2 = Private::Foo->do_things("def");
    say $foo2->{something};
'
new value
old_value
也就是说,您可以通过以下方式清理您的方法:

sub do_things {
    my ($class, $arg1, $arg2, $foo) = @_;

    $foo //= $class->new();

    if ($arg1 eq 'abc') {
        $foo->{something} = 'new value';
    }

    return $foo;
}
如果你清理一下你的通话习惯,那就更好了

Private::Foo->do_something($arg1, $arg2, $foo);

my $foo2 = Private::Foo->do_something($arg1, $arg2);
远不如

$foo->do_something($arg1, $arg2);

( my $foo2 = Private::Foo->new )->do_something($arg1, $arg2);

“我错过了什么?”,没什么。您的代码按原样工作。Re“大多数参数都是标准的按值传递排序”,Perl总是按引用传递。例如,
perl-e'subf{$\u0]=“def”}my$x=“abc”;f(x美元);核心::比如说$x;'输出
def
。呸,你说得对,这看起来确实有效。我之前尝试过的一些事情给了我错误;我想他们没有关系。另外,我称之为“按值传递”的是标准的
my($foo)=@
,在我的示例(而不是您的示例)中,它直接出现在子例程的开头。在收到参数后复制这些参数不会改变它们通过引用传递的事实。你复制了一个论点的事实并不能阻止你改变论点。如果你问“我遗漏了什么?”,没什么。您的代码按原样工作。Re“大多数参数都是标准的按值传递排序”,Perl总是按引用传递。例如,
perl-e'subf{$\u0]=“def”}my$x=“abc”;f(x美元);核心::比如说$x;'输出
def
。呸,你说得对,这看起来确实有效。我之前尝试过的一些事情给了我错误;我想他们没有关系。另外,我称之为“按值传递”的是标准的
my($foo)=@
,在我的示例(而不是您的示例)中,它直接出现在子例程的开头。在收到参数后复制这些参数不会改变它们通过引用传递的事实。您复制了一个参数的事实并不能阻止您更改参数。您的清理方法返回
$foo
,而不管
$arg1
的值是多少,这与我的示例不同。另外,我遗漏了如果
$foo
未定义,我还有其他代码要运行,因此
/=
在这里对我没有多大帮助。Re“您的清理方法返回$foo,而不管$arg1的值如何,这与我的示例不同。”,那又怎样?我从来没有说过它是一样的;我说它更干净。Re“我忘了如果$foo未定义,我还有其他代码要运行”,您可以通过检查
@
的大小来检查提供的参数数量。也就是说,在你提出这个问题之前,你的电话会议已经过于复杂了。区分不存在的参数和未定义的参数太过分了。添加了更简单的调用约定来回答。无论
$arg1
的值是多少,清理后的方法都会返回
$foo
,这与我的示例不同。另外,我遗漏了如果
$foo
未定义,我还有其他代码要运行,因此
/=
在这里对我没有多大帮助。Re“您的清理方法返回$foo,而不管$arg1的值如何,这与我的示例不同。”,那又怎样?我从来没有说过它是一样的;我说它更干净。Re“我忘了如果$foo未定义,我还有其他代码要运行”,您可以通过检查
@
的大小来检查提供的参数数量。也就是说,在你提出这个问题之前,你的电话会议已经过于复杂了。区分缺少的参数和未定义的参数太过分了。添加了更简单的调用约定来回答。