【问题标题】:perl - map not working, "Can't use string ... as a HASH ref"perl - 地图不工作,“不能使用字符串......作为哈希参考”
【发布时间】:2013-12-28 16:51:21
【问题描述】:

我有以下代码:

use strict;
use warnings;
use List::Util qw(max);
use DateTime;
use JSON;

use DBI;

...

my @names = @{ select_users_to_update('last_name') };

sub select_users_to_update {
    my ( $self, $column ) = @_;

    my $sql = qq{
        SELECT DISTINCT `$column`
        FROM `db_name`
        WHERE `first_name` IS NULL
    };
    my $rows = $self->{dbh}->selectall_arrayref( $sql, { Slice => {} } );
    my @fields = map { $_->{$column} } @$rows;

    return \@fields;
}

我收到以下错误:

Can't use string ("last_name") as a HASH ref while "strict refs" in use at update_hpcdb_people.pm line 51.

此代码取自另一个脚本,在该脚本中运行良好。我对 perl 对 map 命令的反对感到困惑——上面的代码有什么问题?

【问题讨论】:

    标签: perl hash map


    【解决方案1】:

    TL;DR:假设省略的代码包含类似这样的内容以连接到数据库:

    my $dbh = DBI->connect(....);
    

    然后像这样改变对select_users_to_update的调用就可以了:

    my @names = @{ select_users_to_update( { dbh => $dbh }, 'last_name') };
    

    解释如下。

    select_users_to_update 子例程期望它的第一个参数 ($self) 是对包含 dbh 字段的哈希的引用,该字段的值是数据库连接的句柄。你没有把任何这样的东西传递给它;你传递的只是列名。

    它可能来自带有自定义模块的程序,编写为对象类,用于处理数据库内容。 select_users_to_update 子例程是作为类的方法编写的,所以我猜测原始程序中的代码会执行您想要执行的操作,如下所示:

    my $customObj = CustomClass->new( database parameters ... );
    my @names = @{ $customObj->select_users_to_update('last_name') };
    

    由于使用方法语法$someRef->subname 调用子例程与传递$someRef 作为第一个参数相同,所以$customObj 中的引用将在子例程中变为$self。只要构造函数CustomClass::new在引用的Hash中填充dbh,它就可以按设计工作。

    但是,如果您不需要它并且只想使用一个子例程,则不必复制所有额外的代码。您可以使用上面 TL;DR 中的代码原样重用它。

    或者,您可以稍微修改子例程,这样它就直接获取未经修饰的数据库句柄,而不是在 hashref 中查找它:

    my @names = @{ select_users_to_update( $dbh, 'last_name') };
    
    sub select_users_to_update {
        my ( $dbh, $column ) = @_;
        ...
        my $rows = $dbh->selectall_arrayref( $sql, { Slice => {} } );
        ...
    }
    

    现在不再是自定义类的方法,而是有一个独立的子例程,可以与任何旧的 DBI 对象一起使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-06
      • 2014-03-31
      • 2011-12-19
      • 1970-01-01
      • 2018-01-07
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多