djt*_*oms 2 perl loops hashmap
背景:我是Perl的新手,我正在修补一个简单的脚本,它循环遍历一个匿名数组的哈希值.
问题我似乎无法遍历数组.我得到的只是ARRAY(0x1663b78)
代码
#!/usr/bin/perl
package Foo;
use strict "vars";
sub new {
my $class = shift;
my $self = {
distro => "",
pkg_mgr => "",
options => ["PHP + Apache", "PHP + Lighthttpd", "PHP + Nginx", "RubyGems + Rails", "Node JS + NPM"]
};
bless $self, $class;
return $self;
}
sub print_options {
my($self) = @_;
foreach($self->{options}) {
print $_ . "\n";
}
}
my $setup = new Foo();
$setup->print_options();
Run Code Online (Sandbox Code Playgroud)
此外,如果有人可以通知我,use strict "vars";如果我真的不需要私人或公共变量,它是否有用.我知道如何在PHP中执行此操作,但我无法在Perl中解决这个问题.
最后,我使用Perl的原因是因为最终我要创建一个为服务器(包括PHP)安装软件的应用程序.此脚本将需要通过命令行进行用户交互.
一些小的Perl线索:
Data::Dumper将帮助您了解结构.main包装中操作.你应该翻转你的程序.最后两个语句应位于顶部,并在下面定义您的包.如果您使用Data::Dumper并转储了$self调用它时的数据,您将意识到这$self是一个包含三个键的哈希,并且该options键指向一个匿名数组.
为了做你想做的事,你必须取消引用匿名数组:
sub print_options {
my($self) = @_;
for ( @{$self->{options} } ) {
print $_ . "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
但是,让我们清理你的程序,使它成为一个完整的类.首先,方法永远不会打印 - 它们返回值.因此,你不应该有一个print_options方法.相反,它应该返回数组(或对数组的引用).
此外,您的构造函数不必知道您Options的结构.怎么改变它怎么办?让我们来看一个改变的程序:
#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);
my $setup = Foo->new;
for my $option ( $setup->Option ) {
say $option;
}
package Foo;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->Option("PHP + Apache");
$self->Option("PHP + Lighthttpd");
$self->Option("PHP + Nginx");
$self->Option("RubyGems + Rails");
$self->Option("Node JS + NPM");
return $self;
}
sub Distro {
my $self = shift;
my $distro = shift;
if ( defined $distro ) {
$self->{DISTRO} = $distro;
}
return $self->{DISTRO};
}
sub Package_Manager {
my $self = shift;
my $package = shift;
if ( defined $package ) {
$self->{PACKAGE} = $package;
}
return $self->{PACKAGE};
}
sub Option {
my $self = shift;
my $option = shift;;
if ( not exists $self->{OPTION} ) {
$self->{OPTION} = [];
}
if ( defined $option ) {
push @{ $self->{OPTION} }, $option;
}
my @array = @{ $self->{OPTION} };
return wantarray ? @array : \@array;
}
Run Code Online (Sandbox Code Playgroud)
首先,与PHP不同,Perl 在执行之前编译代码.因此,您可以在程序的底部定义包及其子例程.在默认主程序包中运行的几行代码.如果我在包中使用了包变量Foo,我不会在程序中意外使用它.
请注意,我的方法或构造函数都不知道Foo对象的结构.当我在new构造函数中设置选项时,我调用我的Option方法来进行设置.这样,如果我改变了存储选项的方式,我只需要改变我的Option方法而不用担心我的包中的其他地方必须改变它.它还简化了我的程序并使其更容易支持.
通过让我的Option方法设置或获取我的选项,我简化了代码.我可以看到我将选项存储在一个匿名数组中,显然我需要在返回对象时取消引用它.我喜欢使用wantarray并为用户提供他们想要数组还是数组引用的选项.
请注意,我不会简单地返回$self->{OPTION}.它是对数组的引用,应该有效,但是如果我返回它,我将返回该对象的内存位置!因此,如果用户更改了该引用,则他们将更改我的对象而不通过我的方法.因此,我创建另一个数组,并返回对它的引用.使用所有你想要的数组引用,你不会改变我的对象.
此代码不完整.我可以设置选项,但不能设置选项.有一种推送和弹出选项的方法可能会很好.相反,此时您只能返回整个列表,而不是修改它.