【问题标题】:Why does substr work differently when passed directly into a method?为什么直接传递给方法时 substr 的工作方式不同?
【发布时间】:2011-06-19 01:58:04
【问题描述】:

我有一个关于 perl 的问题,我过去不关心,但现在困扰着我。

我有一个方法调用 saveItems,它从文本日志中获取一个值并解析输入。

所以我在方法中有这几行。

$intime  = $_[1];
$timeHr  = substr($intime, 0,2); 
$timeMin = substr($intime, 2,2);
$timeSec = substr($intime, 5,2);
$object[$_[0]]->hr($timeHr);
$object[$_[0]]->min($timeMin);
$object[$_[0]]->sec($timeSec);

$intime 是传递给此方法的时间值。 $intime 示例:0431:12

我的问题是,为什么上面没有给我任何错误,但是当我尝试像这样缩短行时:

$object[$_[0]]->hr(substr($intime, 0,2));
$object[$_[0]]->min(substr($intime, 2,2));
$object[$_[0]]->sec(substr($intime, 5,2));

只有第一个有效,其余的给我一个字符串错误。

如您所见,我对 perl 比较陌生,但是谁能给我一个答案?

编辑

人力资源示例:

sub hr {
    my $self = shift;
    if (@_) { $self->{HR} = shift }
    return $self->{HR};
}

编辑

Case Closed..阅读我的回答帖子

【问题讨论】:

  • 您能告诉我们您看到的确切错误吗?
  • "substr 在第 xx 行的字符串之外".. 其中 xx 包含 "$object[$_[0]]->min(substr($intime, 2,2)); "
  • 如果在每个 substr 后面加上 .'' 会得到什么?
  • 不知何故,无论我如何重新排列行,它都只会抱怨第二行
  • @Eric 有效!但你能解释一下为什么吗?

标签: arrays perl substring substr


【解决方案1】:

从上面的 cmets 中,在每个 substr 之后添加 .'' 解决了您的问题。原因是->hr->min->sec 方法正在以某种方式修改它们的参数。如果没有进一步观察,我无法确定正在发生的事情。

substr 函数返回一个有效的左值。这意味着它可以被分配到。因此,当这些方法中的某些内容从 substr 分配给切片时,它会干扰其他方法。

附加一个空字符串通过破坏切片和原始字符串(存储在$intime)之间的别名来解决问题。

如果您编写了hrminsec 方法,您应该弄清楚它们为什么要修改参数。在每个方法调用之间添加print "[$intime]\n"; 语句应该是有启发性的。

【讨论】:

  • 所以通过附加一个空字符串,它将切片与原始切片分离为某种新变量,从而使我们能够对其进行操作?
  • 它仍然在每个方法调用之间打印 [0431:12],我已经用 hr 方法的示例更新了问题
  • 连接运算符. 将其参数复制到一个新字符串中。在这个复制过程中,别名被破坏了。
  • 我明白了。。谢谢你的时间。我已经完全理解了这个概念
  • @robobooga:您显示的示例 hr 不会有描述的问题,并且它在每个方法调用之间打印完整的 0431:12 也表明发生了其他事情,至少在您的一些尝试。
【解决方案2】:

你能想出一个独立的可运行代码来演示这个问题吗?您描述的问题与您显示的代码不太匹配,尽管我不明白@object 在您的代码中的作用。

以下工作正常:

use strict;
use warnings;

package Class;

sub new { bless {} }

sub saveItems {
    my $intime = $_[1];
    $_[0]->hr(substr($intime, 0,2));
    $_[0]->min(substr($intime, 2,2));
    $_[0]->sec(substr($intime, 5,2));
}

sub hr {
    my $self = shift;
    if (@_) { $self->{HR} = shift }
    return $self->{HR};
}

sub min {
    my $self = shift;
    if (@_) { $self->{MIN} = shift }
    return $self->{MIN};
}

sub sec {
    my $self = shift;
    if (@_) { $self->{SEC} = shift }
    return $self->{SEC};
}

package main;

my $object = Class->new();
$object->saveItems( '0431:12' );
print "hr: ", $object->hr(), " min: ", $object->min(), " sec: ", $object->sec(), "\n";

【讨论】:

    【解决方案3】:

    这个问题已经解决了。

    substr的使用方式如下,能够正常执行,不会报错。

    $object[$_[0]]->hr(substr($intime, 0,2)); 
    $object[$_[0]]->min(substr($intime, 2,2)); 
    $object[$_[0]]->sec(substr($intime, 5,2)); 
    

    但是,导致此脚本失败的是带有尾随空白行的日志文件。

    感谢@ysth 让我重现问题,当我意识到问题实际上出在日志文件而不是脚本上时。

    经验教训:在提出问题之前检查代码和来源

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 2012-03-07
      • 2016-02-20
      • 2021-06-11
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 2022-01-26
      • 1970-01-01
      相关资源
      最近更新 更多