【问题标题】:Call subroutine from subroutine从子程序调用子程序
【发布时间】:2014-02-27 09:11:38
【问题描述】:

我有一个子程序(在 Perl 中)需要调用另一个子程序来传输它的参数并添加一个字符串。我已经尝试过这样的事情(但我正在寻找答案,而不仅仅是纠正这个......):

sub TestBase($)
{
    print @_;
    return 'hard processed string';
}

sub Test($)
{
    print @_;
    return TestBase(@_, 'Filename.txt');
}

这个失败,因为“main::TestBase 的参数太多”(这些年来我仍然使用 cmd.com,在这种情况下不容易复制粘贴!)。

【问题讨论】:

  • 我不知道 Perl,我使用的是 Python,考虑到我更愿意学习 Ruby 的时间和愿望。这就是说我不想要大量的 Perl 文档。
  • JavaScript 最适合传递函数。
  • @Dan Dascalescu 我在 Perl 工作,因为这是他们正在使用的(我不想让他们不高兴!)。我无法更改语言。
  • 很容易重新配置 cmd.com 以允许使用鼠标右键进行剪切和粘贴。或者发送到文本文件并在您选择的文本编辑器中打开。

标签: perl subroutine


【解决方案1】:

Perl 最佳实践:don't define function prototypes 除非你真的知道自己在做什么。

#!/usr/bin/perl -w
use strict;

sub test_base {
    print @_;
}

sub test {
    print @_;
    return test_base(@_, 'Filename.txt');
}

test('foo', 'bar');

【讨论】:

  • 我不明白:有人(这个 Alnitak?)否决了你,因为......你正在使用原型?在哪里? sub TestBase($) 在初始代码中做到了。
  • 好吧,这也不是我的,但你可以弥补它(业力:)并接受答案。我非常怀疑是否有更清晰的解决方案。
  • 在 shebang 行中使用 -w 是不好的做法。它早已被use warnings 取代。另外,为什么你在test_base 的结果上使用return 而你不在print 的结果上使用?
  • @Liviu:只有在子例程必须在结束前的某个点退出时,才会看到显式的return。如果意图只是指定一个要返回的值,那么大多数 Perl 程序员将简单地在最后一行定义该值,而不使用 return
【解决方案2】:

为了澄清和总结我对 Dan 的回答的更正,您的代码应该是这样的。

我删除了子程序原型,将左大括号与子程序名称放在同一行(perldoc perlstyle 首选),将名称更改为小写(大写通常保留给全局变量,例如包名称),并删除了 return 关键字。

请注意,您最好保留子例程名称,尤其是当其他人正在编写依赖于它们的代码时。遵循公认的做法很重要,但不如保持现有代码库的接口静态重要。

#!/usr/bin/perl

use strict;
use warnings;

sub test_base {
  print @_;
  'hard processed string';
}

sub test {
  print @_;
  test_base(@_, 'Filename.txt');
}

my $retval = test('A', 'B', 'C');
print "\n\n", $retval, "\n";

输出

ABCABCFilename.txt

hard processed string

【讨论】:

  • 我几乎可以肯定原始子程序的作用域就是它的文件。我打算做一些小的补充(暂时),但我会包括你的建议,我预计这会持续一两个小时,下周。那我大概会接受你的回答,谢谢你的付出!
  • 顺便问一下,对于 perl 风格,没有脚本可以检查吗?我的眼睛很弱:p!
  • @Liviu:如果您的意思是子例程可以调用的范围,那么它就在当前中。如果在编译单元中没有package 语句,则将全局变量放入main 包中。任何包中的任何子例程都可以被调用,只要它的包名是完全限定的。