【问题标题】:Write to the Data Section in Perl在 Perl 中写入数据部分
【发布时间】:2020-10-12 02:37:29
【问题描述】:

从 Perl 中的数据部分 __DATA__ 很容易读取。 以下代码使用预先存在的DATA 句柄:

foreach (<DATA>) {
    print("- $_");
}

__DATA__
1
2
The End of The End

产生:

- 1
- 2
- The End of The End

但是我还没有找到将数据写入该部分的任何巧妙方法。 例如,我尝试了以下方法:

use feature say;

say STDERR 'Some Error';
say STDOUT 'Some Message';
say DATA   'Some Data';

__DATA__
foo bar

STDOUTSTDERR 的打印按预期工作:

perl write.pl 2> /dev/null 
Some Message

但是打印到DATA 什么也没做:

tail -2 write.pl 
__DATA__
foo bar

我也看过 CPAN 的几个模块,但我总是只发现对 read 的支持,而不是 write。 感谢您的任何提示和帮助!

【问题讨论】:

  • 从脚本中修改 Perl 脚本是一个非常非常糟糕的主意。请改用单独的数据文件。
  • 这可能是个坏主意,但它(也许直到现在还无法测试)对于一些花哨的噱头工具来说很方便。我正在寻找一种理智的方式(如果存在任何理智的方式)。疯狂的方法可能是在自己的脚本上打开一个文件句柄......如果这可能的话?
  • 您不能“写入”到 DATA 文件句柄。您可以“打开”$0 - 并寻找/写入它。但这不是一个好主意。
  • 现在在 CPAN 上展示了这个所谓的坏主意:metacpan.org/release/App-Unding

标签: perl


【解决方案1】:

您可以使用文本编辑器写入 DATA 部分。

其他的都是dark magic。将输入和程序状态存储在单独的文件(或数据库)中。

【讨论】:

  • 在这种情况下,我不介意黑魔法!我会尽快检查这个。谢谢提示。如果它按预期工作,那么实施的实际答案将是整洁的。
  • @BorisDäppen 可能不介意黑魔法,但在你之后维护你的软件的人会非常介意。
  • @BorisDäppen 总有一天,有人可能会因为你采用这样的解决方案而对你大发雷霆,而那个人可能就是你。另一方面...it's a really cool solution.
  • 在这里“复制和粘贴”代码而不是仅仅链接不是一件好事吗?
  • 实际上删除链接可能会更好。
【解决方案2】:

这可能没有充分的理由,但方法如下:

#!/usr/bin/env perl

use strict;
use warnings;

seek DATA, 0, 2; # go to the end of the source file
my $offset = tell(DATA); # remember where that is

open my $f, '>>', $0 # open source file for appending
    or die $!;       # of course, you could use DATA instead of $f here

seek $f, $offset, 0; # go to the previously recorded position

print $f "This is a test\n"; # put something there

__DATA__

【讨论】:

  • 此解决方案始终附加在文件末尾。我也在寻找如何替换数据。我认为通过您的解决方案和暴民的“黑魔法”,我将能够做我想做的事。感谢您提供有用的答案!
【解决方案3】:

如果想法是在 DATA 可以输出的内容中添加内容,您可以将其关闭,然后在对包含附加文本的变量的引用上重新打开它,如下所示:

#!/usr/bin/perl

use strict;use warnings;

while(<DATA>) {
    print("- $_");
}

close DATA;

my $additional_text = 'test2';
open DATA, '<', \$additional_text;
$additional_text .= "\ntest3";
while(<DATA>) {
    print("- $_");
}

__DATA__
test

但我认为您需要使用之前包含在DATA部分中的原始数据。

【讨论】:

  • 据我了解,这在文件中并不持久。也许我对这个问题还不够清楚。但我正在寻找持久的东西。
【解决方案4】:

写入 DATA 会更改脚本。这是一个坏主意,因为 DATA 在脚本本身上是开放的以供读取。这个程序说明了为什么这是一个坏主意。

#!/usr/bin/perl

use strict;
use warnings;

seek DATA, 0, 0;
while( <DATA> ){
    print;
}

__DATA__
1
2
3

【讨论】:

  • 通过运行您的脚本,对我来说,您所指的并试图用脚本显示的“为什么”到底是什么对我来说并不明显。能详细解释一下吗?
  • DATA 文件句柄已打开以供在整个脚本上读取。您可以重新打开它进行编写,然后更改整个脚本。这使其容易受到代码注入的影响。
猜你喜欢
  • 2021-10-05
  • 2018-04-20
  • 2022-01-03
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-15
相关资源
最近更新 更多