重载哈希访问以读/写数据库

时间:2017-11-03 14:05:40

标签: database perl hash operator-overloading

我正在尝试使用Perl实现一个非常简单的语法来读取和写入数据库。基本上,最终目标是能够访问数据库中的字段,就像它们是一个简单的Perl哈希一样。

  

不幸的是我试图访问的数据库类型及其API是专有的,因此我无法详细了解如何实际读取和写入数据,只是假设数据库名称是足够的信息连接。在Perl中需要做些什么才能使这项工作非常通用,因此API信息不应该相关。

开始我正在创建一个简单的数据库对象:

my $database = Database->new('NAME');

然后我想从数据库中读取一个我想读的字段名称:

# Read from the database
my $value = $database{'field_name'};

# Write to the database
$database{'field_name'} = $value;

每次从哈希中读取数据时,我都希望它调用一个函数来查询数据库并获取值。

每次将数据写入哈希时,我都希望它调用一个函数将数据写入数据库。

这是我到目前为止所做的:

Database.pm

package Database;

use overload '%{}' => \&access_data;

sub new {
    my $class = shift;
    my $name  = shift;

    my $self = bless {
        name => $name
    }, $class;

    return $self;
}

sub access_data {
    my $self  = shift;
    my $field = shift;
    my $data  = shift;

    if (defined $data) {
        # Write data to the database using the database API
    }
    else {
        # Read data from the database using the database API
    }

    # Not sure what to return to make this work
}

test.pl

use Database;

my $database = Database->new('TESTDB');

# Overloaded to read the actual value from the database
print $database{'field_name'};

我一直在搜索overloading hash access的文档,但我很难理解它是如何工作的。

如何让这种超载按照我想要的方式工作?

1 个答案:

答案 0 :(得分:5)

您不想查看重载,您想查看绑定变量。使用绑定变量,您可以更改标准Perl变量的行为,以便访问变量可以执行标准变量无法执行的操作。

在答案中有点难以解释,但perltie文档非常清楚。

基本上,您定义了自己的包(可以称之为Tie :: Hash :: Database)。然后,您需要为要更改的任何操作定义TIEHASH()方法(相当于构造函数)和方法(称为FETCH())。在伪代码中(因为我不知道你的数据库是如何工作的)它可能看起来像这样:

package Tie::Hash::Database;

use strict;
use warnings;

use Database;

sub TIEHASH {
  my $class = shift;
  my ($db_name) = @_;

  my $self = {
    db => Database->new($db_name);
  };

  return bless $self, $class;
}

# Store value in the hash
sub STORE {
  my $self = shift;
  my ($key, $val) = @_;

  # code to store the key/value pair in the database;
  $self->{db}->store($key, $value);
}

# Get value from hash
sub FETCH {
  my $self = shift;
  my ($key) = @_;

  # code to get value from the database
  return $self->{db}->get($key);
}

# ... etc ...

你可以这样使用它:

use Tie::Hash::Database;

my %db_hash;
tie %db_hash, 'Tie::Hash::Database', 'name_of_database';

$db_hash{some_key} = 'some value';

print $db_hash{some_key};

许多年前,我更详细地写了article that explains all of this。您可能会发现它很有用。

更新:还值得指出标准的Perl发行版附带tied hash support for various DBM files(实际上是用于存储持久性哈希值的二进制文件)。< / p>