【问题标题】:Perl variables and subroutinesPerl 变量和子例程
【发布时间】:2015-09-24 11:49:20
【问题描述】:

我是 perl 编程语言的新手。我试图了解webmin 模块。我没有收到此代码 sn-p:

sub update_dialer
{
    local $lref = &read_file_lines($config{'file'});
    splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1,
    &dialer_lines($_[0]));
    &flush_file_lines();
}

这里发生了什么?值存储在哪里?请有人详细解释这段代码。

【问题讨论】:

  • 一堆糟糕的做法,如果您对 webmin 不是特别感兴趣,请查看其他一些 perl 代码。给全局$lref 分配了数组引用,$_[0] 是作为第一个参数传递给子例程的哈希引用。
  • $lref 被声明为本地。传递给它的值将存储在一个数组中??如果我的理解有误,请纠正我..
  • 这很有帮助,谢谢..
  • 是的,你几乎不应该在实践中看到local(除了local $_),你也不应该像那样使用&。这段代码是为 Perl4 编写的。然后是我不会做出的三种风格决定。

标签: perl variables webmin


【解决方案1】:

简短的总结:“讨厌的 perl 代码”。

更长的答案:

sub update_dialer {

    # take a global variable $lref.
    # scope it locally it can be modified within the local subroutine
    # run the sub "read_file_lines" and pass it the contents of `$config{'file'}
    # assign the result to $lref
    local $lref = &read_file_lines( $config{'file'} );

   #removes elements from an array.
   #Number based on a hash reference passed in as the first argument in @_
   #but is also calling the dialer_lines subroutine as part of it.
    splice(
        @$lref, $_[0]->{'line'},
        $_[0]->{'eline'} - $_[0]->{'line'} + 1,
        &dialer_lines( $_[0] )
    );

    #run the sub 'flush_file_lines'.
    &flush_file_lines();
}

它正在实施一系列不良做法:

local

手册页指出了这有什么问题:

您可能真的想改用 my,因为 local 并不是大多数人认为的“本地”。 See Private Variables via my() in perlsub for details.

local 作为一种临时覆盖全局变量的方式存在。它很有用 - 例如 - 如果您想更改输入记录分隔符 $/。 你可以这样做:

{
    local $/ = "\n\n";
    my $first_record = <$filehandle>;
    print $first_record;
}

这意味着一旦你退出你的代码块,$/ 将返回到它的原始值,并且不会在你的代码中搞砸文件 IO 的所有其余部分。在此示例中没有充分的理由像这样使用它。

&amp; 子程序前缀

Difference between &function and function() in perl

&amp; 为子添加前缀会做一些你几乎从未真正想要的事情,因为它会弄乱原型设计之类的东西。因此,您通常不应该这样做。

splice

删除和替换数组中的元素。不是特别错误,而是它以它的方式做这件事的事实使得很难告诉它在做什么

(但我认为因为它正在本地化$lref,它的值在这个子的末尾消失了。

$_[0] -&gt; {'line'}

当一个 sub 被调用时,它会传递一个数组 @_ 和函数的参数。您可以使用 $_[0] 访问此数组的第一个元素 - 它 NOT$_ 相同,因为所有原因 $list[0]$list 不一样。

它的使用方式 - $_[0] -&gt; {'line'} 告诉我们这是一个哈希引用,它被取消引用以访问某些变量。

但这并不完全是在创建漂亮且可读的代码。

你可以这样做:

my ( $parameter_ref ) = @_; 

或许:

my $parameter_ref = shift;

这里的口味问题 - 默认情况下,shift 使用 @_ 与许多其他函数默认使用 $_ 的方式大致相同。不过我更喜欢前者。

但是通过命名参数,您可以清楚地了解它们是什么以及它们在做什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多