Perl - 将对象的哈希值作为单个对象从类中返回

时间:2017-11-02 08:25:49

标签: perl oop object hashmap

通常,perl对象是数据结构,例如散列,数组,标量,文件句柄等。

我在想一个perl模块可以将对象的哈希值(每个对象作为哈希值)作为单个对象返回的场景。请考虑以下情况。

我有一个包含多个文档的YAML文件。 (或具有多组相同配置节点的XML)。我需要一个perl模块,我可以将此YAML文件作为输入传递,并接收对象的散列(每个对象对应于YAML文件中的文档)。

YAML

---
mykey: 1
myname: John
---
mykey: 2
myname: Doe
----
mykey: 3
myname: Chris
...

上面的YAML文件中有3个文件。让我们考虑一下这将是输入文件。

我想写下面的内容并访问对象的哈希值。

SimpleParser.pl

use strict;
use warnings;
use YAMLParser;
my %objHashRef = YAMLParser->new('input.yml');

print keys %objHashRef;    #print keys for each objects
print values %objHashRef;  #print hash reference of each object

my $thirdObjectName = $objHashRef{3}->get_name();
print $thirdObjectName;    #this prints 'Chris'

要实现此行为,perl模块文件中所需的所有修改都与下面的内容类似?

YAMLParser.pm

use strict;
use warnings;
sub new {
    my ($class) = shift;
    my $self = {
         inputFile => shift,
         name => shift
    };
    bless $self, $class;
    return $self;
}

sub set_name {
    $self->{name} = $name;
}

sub get_name {
    my ($self) = @_;
    return $self->{name};
} 
1;

以下是一个示例YAML解析代码段,如果需要可以提供帮助。

my @list;
my $myname;
my $i = 0;
my @conf = LoadFile('input.yml');   #returns array of reference to each document in the YAML file
my $config = \@conf;      #Returns reference to an array

foreach ( @conf ) {
    $list[$i] = $config->[$i]->{mykey};
    $objHash{$list[$i]} = YAMLParser->new();
    $myname = $config->[$i]->{myname};
    $objHash{$list[$i]}->setMyname($myname);
    my $host = $objHash{$list[$i]}->getMyname();
    $i++;
}

请让我知道你的想法。

2 个答案:

答案 0 :(得分:2)

只需将结构存储到由mykey键入的哈希值中。我使用map,但也可以使用for循环:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{
    package YAMLHash;
    use YAML qw{ LoadFile };
    sub new {
        my ($class, $file) = @_;
        my %hash = map { $_->{mykey} => $_ } LoadFile($file);
        bless \%hash, $class
    }
}


my $obj = 'YAMLHash'->new('1.yaml');

say keys %$obj;
say values %$obj;

my $third_object_name = $obj->{3}{myname};
print $third_object_name;    #this prints 'Chris'

请注意$obj->{3}不是第三个对象。它是mykey为3的对象。

答案 1 :(得分:0)

CPAN上有很多模块可以很好地用哈希创建一个对象(哎呀,我甚至写了一个:Hash::Wrap)。如果您想以递归方式将对象范例应用于YAML文档的嵌套部分,我最喜欢的是Hash::AsObject。有关类似模块的更全面列表,请参阅Hash::Wrap

这里有一些代码。它返回对象的列表,而不是对象的 hash ,但修复它非常简单。

use 5.010;

use strict;
use warnings;

use Hash::AsObject;
use YAML 'Load';


my $yaml = do { local $/ = undef;
                <DATA>
            };

my @objs = map { Hash::AsObject->new( $_ ) } Load( $yaml );

say " Name: ", $objs[0]->myname;
$objs[0]->myname( "Frank" );
say " Name: ", $objs[0]->myname;

__DATA__

---
mykey: 1
myname: John
---
mykey: 2
myname: Doe
---
mykey: 3
myname: Chris

输出:

 Name: John
 Name::Frank