无法通过从两个不同子例程传递给新子例程的值来执行计算:Perl

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法通过从两个不同子例程传递给新子例程的值来执行计算:Perl相关的知识,希望对你有一定的参考价值。

我使用匿名哈希将值从两个不同的子例程传递给一个新的子例程。但是,现在我无法使用传递的变量执行计算。

use warnings;
use strict;
use feature 'say';
use DBI;
use autodie;
use Data::Dumper;
use CGI;

print "Enter sequence";
my $seq = <STDIN>;
chomp $seq;
$len = length $seq;
my $f = nuc($seq);
perc({ len => $len });

sub nuc {
  my ($c) = @_;
  chomp $c;
  my $len = length $c;
  for (my $i = 0; $i< = $len; $i++) {
    my $seq2 = substr($c, $i, 1);
    $nuc=$nuc . $seq2;
    chomp $nuc; 
  }
  my $l = perc({nuc => $nuc});
} 

sub perc {
  my $params = shift;
  my $k = $params->{nuc};
  my $w = $params->{len};
  my $db = "hnf1a";
  my $user = "root";
  my $password = "";
  my $host = "localhost";
  my $dbh = DBI->connect("DBI:mysql:database=$db:$host",$user,$password);
  my $sth = $dbh->prepare('SELECT COUNT(*) FROM mody where nm = ?');
  for (1..100) {
    $sth->execute(int(rand(10)));
  }
  chomp (my $input = $k);
  my @num = split /':'/, $input;
  for my $num(@num)  {
    say "rows matching input nuc <$num>:";
    $sth->execute($num);
    my $count = $sth->fetchrow_array;
    say "$count";
    $u += $count;
  }
} 
$h = $u / $w;
print $h;

我通过声明一个匿名哈希将变量:$ nuc和$ len传递给最后一个子程序'perc'。当我使用这些变量进行计算时,我没有得到正确的答案。对于上述部门,我得到了一个声明为“非法分裂”。

请帮帮我。提前致谢。

答案

您正在对perc进行两次单独调用,每次调用只有哈希值中的一个必需值。你不能这样做:子程序不会“记住”在不同的调用中传递给它的值,除非你编写代码来执行该操作

您需要收集所有值并通过一次调用传递给perc

另一答案

这里有很多误解。我们来看看你的代码。

use CGI;

使用CGI.pm有点过时了,但如果你正在编写CGI程序,这并不是一个糟糕的主意。但这不是CGI计划,所以这不是必需的。

print "Enter sequence";
my $seq = <STDIN>;
chomp $seq;
$len = length $seq;
my $f = nuc($seq);

这看起来不错。您提示用户,获取一些输入,从输入的末尾删除换行符,获取输入的长度,然后将输入传递到nuc()

那么,让我们来看看nuc() - 它可能有一个更好的名字!

sub nuc {
  my ($c) = @_;
  chomp $c;
  my $len = length $c;
  for (my $i = 0; $i< = $len; $i++) {
    my $seq2 = substr($c, $i, 1);
    $nuc=$nuc . $seq2;
    chomp $nuc; 
  }
  my $l = perc({nuc => $nuc});
}

你得到传入的参数并从它的末尾删除换行符(这没有任何作用,因为这是已经删除了换行符的$seq)。然后你得到这个字符串的长度(再次!)

然后它变得非常奇怪。首先,有一个语法错误(< =应该是<=)。然后你也使用C风格的循环和substr() ......好吧,基本上你只是以非常低效的方式将$c复制到$nuc。所以这个子程序可以写成:

sub nuc {
  my ($c) = @_;
  $nuc = $c;
  my $l = perc({ nuc => $nuc });
}

哦,我不知道为什么你每次围绕循环chomp($nuc)

两个更奇怪的事情。首先,你没有在任何地方声明$nuc,你的代码中有use strict。这意味着此代码甚至无法编译。 (请不要浪费我的时间使用不编译的代码!)其次,您没有显式返回nuc()中的值,而是将返回值存储在$f中。由于Perl的工作方式,此子例程将返回$l中的值。但最好是明确的。

然后是你的perc()子程序。

sub perc {
  my $params = shift;
  my $k = $params->{nuc};
  my $w = $params->{len};
  my $db = "hnf1a";
  my $user = "root";
  my $password = "";
  my $host = "localhost";
  my $dbh = DBI->connect("DBI:mysql:database=$db:$host",$user,$password);
  my $sth = $dbh->prepare('SELECT COUNT(*) FROM mody where nm = ?');
  for (1..100) {
    $sth->execute(int(rand(10)));
  }
  chomp (my $input = $k);
  my @num = split /':'/, $input;
  for my $num(@num)  {
    say "rows matching input nuc <$num>:";
    $sth->execute($num);
    my $count = $sth->fetchrow_array;
    say "$count";
    $u += $count;
  }
}

你得到散列引用,它在$params的商店中传递。然后你从那个哈希中提取nuclen值并将它们存储在名为$k$w的变量中(你真的需要改进你的变量和子程序名称!)但是每次调用perc时都只设置其中一个值 - 所以只有一个你的两个变量得到一个值,另一个将是undef

那么你就连接到了数据库。并且您运行一个选择查询一百次,传递0到9之间的随机整数。并忽略select语句返回的值。这是奇怪而毫无意义的。

最后,你开始用你的一个输入参数做一些事情,$k(另一个,$w,完全被忽略)。在将其拆分为数组之前,将其复制到另一个标量变量中。然后,对该数组中的每个元素运行一次相同的SQL select语句,并将返回的数字添加到$u中的运行总计中。 $u是另一个你从未声明过的变量,所以(再一次)这段代码不能编译。

在子程序之外,然后使用$u(未声明的变量)和$w(在不同范围内声明的变量)执行一些简单的数学运算,并将结果存储在$h(另一个未声明的变量)中。

我真的不明白这段代码应该做什么。而且,说实话,我不认为你也这样做。如果你在学校,那么你需要回到老师面前说你不知道自己在做什么。如果你在工作,你需要告诉你的老板你不是这个任务的合适人选。

无论哪种方式,如果你想成为一名程序员,你需要回到起点并再次涵盖基础知识。

以上是关于无法通过从两个不同子例程传递给新子例程的值来执行计算:Perl的主要内容,如果未能解决你的问题,请参考以下文章

Perl 中左值子例程的用途是啥?

批处理脚本子例程:传递参数

将两个或多个数组传递给 Perl 子例程

使用函数获取变量的值(将变量从函数传递到子例程)[重复]

九十SAP中ALV事件之四,事件子例程的参数

模块化程序-子例程