【问题标题】:Overloading hash access to read/write to a database重载哈希访问以读取/写入数据库
【发布时间】:2017-11-03 22:55:08
【问题描述】:

我正在尝试实现一种非常简单的语法来使用 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;

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

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


这是我目前所拥有的:

数据库.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 的文档,但我很难准确理解它是如何工作的。

我怎样才能让这种重载以我想要的方式工作?

【问题讨论】:

  • 您的设计没有考虑到常规 SQL 数据库的组织方式。一个数据库可以有许多,每个表可能有多个和多个。您尚未提供选择表或返回给定列的多行的方法。
  • 这不是 SQL 数据库。从数据库中获取值所需的所有信息都是字段名称和下标。我为这个问题留下了下标部分,但为了简化事情。最终目标是拥有类似于 $val = $db{'field_name'}[1] 的语法,其中 1 是所需记录的下标。

标签: database perl hash operator-overloading


【解决方案1】:

您不想查看重载,您想查看绑定变量。使用绑定变量,您可以更改标准 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(实际上是用于存储持久哈希的二进制文件)。

【讨论】:

    猜你喜欢
    • 2012-04-04
    • 2019-07-20
    • 2020-07-10
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 2017-02-28
    相关资源
    最近更新 更多