【问题标题】:Perl how to pass data to a sub-routine in a modulePerl如何将数据传递给模块中的子例程
【发布时间】:2016-02-03 22:25:32
【问题描述】:

我已经有一段时间没有做任何 Perl 工作了,我需要编写一个信用卡处理模块。该模块将有几个子例程,但是一旦我弄清楚如何做一个,我就可以做剩下的了。第一个子程序是添加客户信息。我需要的信息是客户编号、名字、姓氏、地址、城市、州和邮政编码。所有这些信息都将由调用程序提供,但有些字段可能是空白的。

sub addCustomer()
{
    my $tx = new Business::OnlinePayment("USAePay");
    $tx->content(
        login           => LOGIN,
        password        => PASSWORD,
        type            => "CC",
        action          => 'Recurring Authorization',
        description    => 'Business::OnlinePayment test',
        amount         => '49.95',
        invoice_number => '100100',
        name           => 'Tofu Beast',
        card_number    => '46464646464646',
        expiration     => '11/08',
        address        => '1234 Bean Curd Lane, San Francisco',
        zip            => '94102',
    );
    $tx->submit();

    if($tx->is_success()) {
        print "Card processed successfully: ".$tx->authorization."\n";
    } else {
        print "Card was rejected: ".$tx->error_message."\n";
    }
}

【问题讨论】:

  • 你应该从阅读和吸收Perl subroutinesPerl module style guide开始
  • Perl Subroutine Arguments的可能重复
  • 不要使用原型(sub 声明中的括号)。它们不是必需的,它们不会做你认为他们做的事。它们比其他任何东西都更有可能给您带来奇怪的错误。它们用于使子程序模仿内置函数,仅此而已。你的应该是sub addCustomer {

标签: perl


【解决方案1】:

你想这样做:

sub addCustomer()

因为你的 sub 原型没有参数。你可能根本不想做原型,因为 perl 原型并不是其他人所说的原型。

但是您可以从 @_ 读取参数 - 这是输入标量的列表 - 它可以是引用,但不需要。

my ( $first_arg, $second, $another, @everything_else ) = @_; 

注意 - 分配给一个列表将消耗其余的值,所以你不能:

my ( @stuff, $last_arg ) = @_; 

对于长列表,传入哈希或哈希引用可能很有用。

【讨论】:

    【解决方案2】:

    传统方式:

    addCustomer($number, $firstName, $lastName, $address, $city, $state, $zip);
    
    sub addCustomer {
        my ($number, $firstName, $lastName, $address, $city, $state, $zip) = @_;
        ...
    

    对于这么多参数,命名参数可能更具可读性:

    addCustomer( number     => $number,
                 first_name => $firstName,
                 last_name  => $lastName,
                 address    => $address,
                 city       => $city,
                 state      => $state,
                 zip        => $zip,
               );
    
    sub addCustomer {
        my %opts = ( city => 'New York', # The defaults.
                     @_);
    

    在较新的 Perl 版本 (5.20+) 中,您还可以使用 signatures feature

    use feature qw{ signatures };
    
    sub addCustomer($number, $firstName, $lastName, $address, $city, $state, $zip) {
    

    对于空白参数,如果不使用命名参数,请使用undefq()

    addCustomer(123, q(), 'Doe', '123 Street', 'London', undef, 'WC1A1BN')
    

    【讨论】:

    • 请注意,其他安装不太可能有 Perl v5.20 可用,因此,如果您打算编写可移植的东西,那么您应该坚持使用传统技术
    • 为什么要使用q(),最简单的表达方式是''"",每个人都明白。
    • @TLP: PBP
    • @choroba 哪里说你应该使用q() 而不是''
    • @TLP 你点击了链接吗? (PBP 是相关章节的链接。)它就在那里......不幸的是(不能说我同意这个建议)。
    【解决方案3】:

    将参数作为散列传递(或者,更准确地说,作为散列引用)。

    # Outside of the subroutine
    my %new_customer = (
        login          => LOGIN,
        password       => PASSWORD,
        type           => "CC",
        action         => 'Recurring Authorization',
        description    => 'Business::OnlinePayment test',
        amount         => '49.95',
        invoice_number => '100100',
        name           => 'Tofu Beast',
        card_number    => '46464646464646',
        expiration     => '11/08',
        address        => '1234 Bean Curd Lane, San Francisco',
        zip            => '94102',
    );
    
    add_customer(\%new_customer);
    
    # Your subroutine
    sub add_customer {
        my ($cust_ref) = @_;
    
        # Note: Don't use indirect object notation
        my $tx = Business::OnlinePayment->new("USAePay");
    
        $tx->content( %$cust_ref );
        $tx->submit();
    
        if ($tx->is_success()) {
            print "Card processed successfully: ".$tx->authorization."\n";
        } else {
            print "Card was rejected: ".$tx->error_message."\n";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 2016-11-22
      • 2021-03-09
      • 1970-01-01
      • 2015-09-27
      • 2015-05-11
      • 1970-01-01
      相关资源
      最近更新 更多