如何分解值并单独返回,以便我可以单独访问它们?
我有一个带有数据库的论坛系统,可以跟踪线程中的所有帖子。我有一个名为notice_value
的小组:
sub notice_value {
my ($self,$prefid,$value,$others_post,$clients_post,$assigned_tasks) = @_;
$self->{PREFS}->{$prefid} = { VALUE => $value,
OTHERS_POST => $others_post,
CLIENTS_POST => $clients_post,
ASSIGNED_TASKS => $assigned_tasks };
return $self->{PREFS}->{$prefid};
}
EDIT-原始notice_value
sub notice_value {
my $self = shift;
my $prefid = shift;
$self->{PREFS}->{$prefid} = shift if(@_);
return $self->{PREFS}->{$prefid};
}
-------------------------------------------- -----------------
检索用户的首选项,其中一个是标记类型VALUE
。当我调用标记类型时,我使用$self->markup
来调用 - sub markup_type
这是Taskman::Post
中的方法:
sub markup_type {
my $self = shift;
$self->{MARKUP_TYPE} = shift if(@_);
$self->{MARKUP_TYPE};
}
我的问题是我只想从notice_value中检索VALUE
,而是返回整个事情 - 当我转储$self
时,我得到了:
$VAR1 = bless( {
'POST_TYPE_ID' => 1,
'MINUTES' => '0',
'DEADLINE' => '2014-05-19 18:04:00',
'ESTIMATE' => 300,
'COMMENT' => 'sd',
'POSTER' => 1286,
'STATE_ID' => 14,
'CONTRACTID' => 546,
'PRIORITY' => '3',
'MARKUP_TYPE' => {
'VALUE' => 1,
'OTHERS_POST' => 1,
'CLIENTS_POST' => 1,
'ASSIGNED_TASKS' => 1
},
'TID' => 23133,
'OWNER' => '1286'
}, 'Taskman::Post' );
我希望能够分别访问其他值(OTHERS_POST
,CLIENTS_POST
,ASSIGNED_TASKS
)以及其他功能。
我是Perl的新手,对于如何分解notice_value
sub感到有些困惑,这样我就能更有效,更正确地从中检索出我想要的内容。如果你能展示一个很好的例子。
修改
这是调用notice_value
:
sub __populate {
my $self = shift;
my $sth = $self->{dbh}->prepare("select prefid, value, others_post, clients_post, assigned_tasks from user_preferences where userid=?");
$sth->execute($self->userid);
while(my $href = $sth->fetchrow_hashref()) {
$self->notice_value($href->{PREFID}, $href->{VALUE}, $href->{OTHERS_POST}, $href->{CLIENTS_POST}, $href->{ASSIGNED_TASKS});
}
$sth->finish();
}
原始__populate
只有:
$self->notice_value($href->{PREFID}, $href->{VALUE});
答案 0 :(得分:1)
TL; DR 对广泛问题的广泛猜测/结论:修复notice_value
的返回值或修复该值在其他函数中使用的方式。
这个问题非常笼统,并没有提供太多示例代码:事实上,由于问题的范围很广,它几乎无法按照定义发布示例代码。将问题发布为一般调试策略可能会更好(尽管我不确定这些查询是如何被接受的那样)或者 - 一旦你缩小了你的问题 - 发布关于修复技术的更具体的问题出了什么问题。
许多事情都可能出错:您的notice_value
子例程的返回值是不是应该像return $self->{PREFS}->{$prefid}->{VALUE};
? ie if - 从名称猜测 - 子程序应该“注意”散列/对象的MARKUP
密钥匿名散列密钥的“值”VALUE
(即它是一个“getter”方法/函数除了访问值之外什么也不做。它获取这些值的方式(解除引用,访问数据库等)留作该函数的实现细节。如果取消引用一个充满首选项的数据结构不起作用,并且当您更改访问您的首选项的功能时您的预期行为会发生变化,那么您就可以在正确的轨道上集中注意力了:)
如果我按如下方式创建一个函数并将它传递给一个数组(省略你传入的对象,那么我就省略了$self
):
sub notice_value{
my ($prefid,$value,$others_post,$clients_post,$assigned_tasks) = @_;
$_->{PREFS}->{$prefid} = { VALUE => $value,
OTHERS_POST => $others_post,
CLIENTS_POST => $clients_post,
ASSIGNED_TASKS => $assigned_tasks };
return $_->{PREFS}->{$prefid};
}
现在有一些偏好和数据gunk:
my @pref_and_data_goo = qw( 21323 42 213 214 2 );
现在让我们看一下该函数的作用,它创建一个PREFS
哈希键,并为其提供一个匿名哈希作为其值:
notice_value(@pref_and_data_goo)
$HASH1 = {
ASSIGNED_TASKS => 2,
CLIENTS_POST => 214,
OTHERS_POST => 213,
VALUE => 42
};
VALUE
密钥的值(我很容易被这里的命名方案弄糊涂)或PREFS
密钥的匿名哈希中的其他密钥怎么样:
notice_value(@pre_and_data_goo)->{VALUE}
42
notice_value(@pre_and_data_goo)->{ASSIGNED_TASKS}
214
如果你想要结束notice_value
,那么它只返回VALUE
键的值,你需要告诉该函数的代码如何获得该嵌套的匿名散列键。
现在将哈希/对象传递给您的其他函数markup_type
并快速剪切并粘贴到re.pl
(因此奇数标记例如 re.pl$
和>
):
re.pl$ my $whacky_hash = {
> 'POST_TYPE_ID' => 1,
> 'MINUTES' => '0',
> 'DEADLINE' => '2014-05-19 18:04:00',
> 'ESTIMATE' => 300,
> 'COMMENT' => 'sd',
> 'POSTER' => 1286,
> 'STATE_ID' => 14,
> 'CONTRACTID' => 546,
> 'PRIORITY' => '3',
> 'MARKUP_TYPE' => {
> 'VALUE' => 42,
> 'OTHERS_POST' => 1,
> 'CLIENTS_POST' => 1,
> 'ASSIGNED_TASKS' => 1
> },
> 'TID' => 23133,
> 'OWNER' => '1286'
> }
re.pl$ sub markup_type {my $self = shift;
> $self->{MARKUP_TYPE} = shift if(@_);
> $self->{MARKUP_TYPE}; }
re.pl$ markup_type($whacky_hash)
$HASH1 = {
ASSIGNED_TASKS => 1,
CLIENTS_POST => 1,
OTHERS_POST => 1,
VALUE => 1
};
re.pl$ sub markup_type2 {my $self = shift ;
> $self->{MARKUP_TYPE}->{VALUE}; }
re.pl$ markup_type2($whacky_hash)
42
你确定类似的改变不起作用吗?如果您将markup_type
功能更改为:
sub markup_type {
my $self = shift ;
$self->{MARKUP_TYPE}->{VALUE};
}
你应该得到你想从该函数返回的值。如果这打破了其他代码,则跟踪它的使用位置,并尝试找到最适合尝试更改的地方。不幸的是,我们无法帮助您直接帮助您。
您的notice_value
函数需要一长串赋值作为参数:
my ($self,$prefid,$value,$others_post,$clients_post,$assigned_tasks) = @_;
我倾向于不喜欢具有长列表分配的函数,因为很难将值追溯到它们来自的位置。 $value
应该是哈希引用还是对markup_type
或其他内容的返回值的代码引用?这可能只是我很容易混淆,因为许多人更喜欢列表分配方式。尽管如此,如果它应该做的只是notice_value
,那么这个函数需要很多参数?您的尝试如果您检查notice_value
如何获取并使用其参数,您将能够更轻松地发现错误的来源。您的 EDIT 添加仍然让我感到疑惑:为什么使用$href->{VALUE}
而不是$href->{MARKUP_TYPE}->{VALUE}
。
答案 1 :(得分:1)
我注意到您的转储在转储结束时有Taskman::Post
。这意味着这是一个Taskman::Post
对象,因此应该有方法,它将提取它包含的各种数据。可能有标记方法将提取此对象中的信息。
问题是这个对象来自何处。这是你写的吗?这是与您的系统一起安装的Perl模块吗?是否正确编写,因此它包含 POD 文档。
尝试以下命令:
$ perldoc Taskman::Post
如果此方法有效,它将提取有关如何访问您检索到的此Taskman::Post
对象中包含的数据的信息。
如果没有出现,请尝试以下命令:
$ perldoc -l Taskman::Post
这将告诉您是否安装了Taskman :: Post 模块以及它在系统中的位置。您可能必须查看此源以获取它包含的各种方法。这些方法将是该模块内的子程序。以下划线开头的子程序被视为私有,您不应直接使用它们。
如果这不起作用,您需要找到定义此类的位置。有时,人们定义非模块类以在单个程序中使用。例如,我编写了一个程序来跟踪我的员工。我创建了一个Employee类,但不是作为单独的Perl模块安装,而是简单地将它附加到我的Perl程序中。寻找:
package Taskman::Post
代码中的。如果找到它,请查看代码是否包含 POD 文档。您会在整个文档中看到=pod
或=head1
。如果是这样,你可以尝试:
$ perldoc program.pl
program.pl
是你的Perl程序。
回到子程序,你是在写这个类吗?我一直在看$self
。这通常意味着您正在使用对象,因此问题是对象的类型是$self
。例如,做什么:
print "The reference \$self " . ref( $self ) . "\n";
打印出来?
同样,您不应该操纵对象,就好像它只是对哈希的引用一样。事实上,一些开发人员编写了所谓的inside out类,以防止人们执行Data::Dumper
并操纵他们的类而不经过正确的方法。
我发现你的帖子有点令人困惑,因为它听起来像你在编写非面向对象的代码,但你的数据看起来是面向对象的。
您在编写面向对象的代码吗?你知道Perl object oriented programming是如何运作的吗?
如果您正在处理所有内容作为对象。尽量让你的方法理顺。在markup_type
子例程中,对象的类型为$self
。打印出ref $self
并查看它是什么类型的对象。
这应该有助于澄清您正在使用的内容,并且应该帮助您了解您实际提取的内容。
答案 2 :(得分:0)
在我看来,你想要$thing->notice_value(@all_those_arguments)->{VALUE}
。
这是因为返回值是
{ VALUE => $value,
OTHERS_POST => $others_post,
CLIENTS_POST => $clients_post,
ASSIGNED_TASKS => $assigned_tasks }
和$thing->notice_value(@all_those_arguments)
只返回此值。这对你有用吗?