【问题标题】:Call to Subroutine from Catalyst Controller从催化剂控制器调用子程序
【发布时间】:2012-08-28 06:00:24
【问题描述】:

我正在研究为数据库设计前端的催化剂。我是 perl 和催化剂的新手。我在控制器中遇到一个错误。

我想从一个表中获取基因名称并将每个基因名称传递给一个子程序gene_name(调用一个子程序gene_name),它将执行某些功能。我知道如何获取带有基因名称的列,但它们是以哈希引用的形式对其他表进行的。我对gene_name 的调用不起作用。

知道如何将值传递给子例程而不是引用吗? 我的代码如下:

my @gene_list = $c->model('Gene::GeneTable')->search({      
},{
                column =>[qw/symbol/],
}
);
foreach my $gene (@gene_list){
push @gene_aliases, &gene_name($gene);
}

执行代码后我得到的错误如下:

DBIx::Class::ResultSet::find(): Can't bind a reference (MyApp::Model::Gene::GeneTable=HASH(0x7ff6d88b7c58))

更新

我的gene_name() 子例程在我包含在控制器中的另一个模块中。现在我已经改变了for循环(在控制器中)如下,目前它正在将基因名称传递给gene_name()以获取别名(但查询保持不变):

foreach my $gene (@gene_list){
push @gene_aliases, &gene_name($gene-> symbol);
}

我正在访问我的视图文件中的@gene_aliases,如下所示:

[% FOREACH g in gene_aliases -%]
[% g %]
[% END -%]

上面的代码是在页面中获取哈希引用而不是名称。我无法在网页上显示基因名称。如果我在 for 循环中给出 [% g.symbol %] 则页面将为空且没有错误消息。希望这足以回答我的问题。如果不是,我会详细说明。

我的SQL查询如下:

Select Symbol from GeneTable;

提前致谢

更新2

由于我不是全职程序员,所以我在博客上提出这些问题。请帮助我解决我的问题。如果我有从用户获取基因名称的搜索表单,并且该基因名称必须传递给gene_name() 子例程,我该如何传递这个(传递给控制器​​以及如何调用gene_name())。请帮助我解决这个问题。 我在view.tt中的表格如下:

<form method="post" action "[% c.uri_for('/gene')%]">
<input type="text" name="search_alias">
<input type="submit" name="alias_search" value="Search">
</form>

我所有的别名都在另一个名为 Alias 的表中,该表在gene_name() 子例程中使用。

【问题讨论】:

  • 首先,使用关键字'columns',而不是'column'。 metacpan.org/module/…
  • 我自己不使用 DBIx::Class,但在我看来,search 的第一个哈希参数应该有一些参数,对吧?构建查询的目的不是相当于SELECT * FROM gene WHERE symbol = ?
  • @ret 抱歉 Ret 我无法将我的问题正确地传达给您。请查看更新后的问题

标签: perl catalyst


【解决方案1】:

gene_name() 函数需要传递给它的 GeneTable 对象,或者您可以这样调用它:gene_name($gene-&gt;symbol)

话虽如此,根据您提供的有限信息,控制器看起来并不适合这样做。

将gene_name 作为Gene::GeneTable 本身的方法会更有意义,即:

package GeneTable;

...

sub gene_name {
    my $self = shift;
    my $gene_name = ... # do something with $self->symbol
    $gene_name
}

...

因此-&gt;gene_name 方法可用于任何上下文中的任何 GeneTable 对象。

更新 在 OP 最初的两个 cmets 之后

听起来gene_name()(可能应该称为gene_aliases())是一个基因对象的方法。将这样的转换放入 Controller 并不符合良好的 MVC 理念。

大概你在某处有模型代码 - MyApp/Model/Gene/ 很可能 - 这个子应该存在于Gene/GeneTable.pm 中。然后你可以这样使用它:

[%- FOREACH g IN gene_list -%]
    [% g.symbol %]<br/><ul>
    [%- FOREACH gn IN g.gene_name -%]
    <li>[% gn %]</li>
    [%- END -%]
    </ul>
[%- END -%]

在您的模板中,以及您拥有 GeneTable 对象或其集合的任何其他地方。

更新 #2 更新后的问题

DBIx:Class 在列表上下文中调用时将返回一个对象数组。或许您需要添加一些 Data::Dumper-&gt;Dumper() 调用来了解每个步骤返回给您的内容。

我建议您在致电-&gt;search()立即添加以下行:

$c->log->debug("gene_list contains: ", Data::Dumper->Dumper(\@gene_list));

...在您填充之后,可能还有对 @gene_aliases 的等效调试。

这可能会让您更清楚地了解您从搜索中得到的结果,但我冒昧地猜测您会得到 Gene::GeneTable 对象。

【讨论】:

  • 感谢您的回复。在说“控制器看起来不适合这个”时,请让我知道您的意思,因为我不清楚还有什么可以添加到控制器中。让我知道为什么会出现上述错误。当我运行以下循环时,我可以访问 .tt 文件中的基因名称:[%FOREACH g IN gene_list-%] [% g.symbol %]
    [% END %]
  • 我不明白发生了什么。如果您能告诉我如何进行,那就太好了。我没有得到我应该在新子例程中添加的内容来获取值(基因名称)。
  • 感谢您的更新。我知道如何将基因名称传递给子程序,但子程序再次将哈希引用返回给调用。我不知道如何取消引用它。在此先感谢...
  • 对不起,你没有给我太多的工作。您能否更新您的原始问题并显示更多代码?另外,请参阅原始问题所附的评论。
  • 感谢您的快速回复。您猜对了,返回的对象是 GeneTable 对象。我正在考虑调用gene_name() 子例程的其他替代方法。查看 update2 并提供您对它的看法。
猜你喜欢
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多