我很好奇使用 Storable 的 store_fd 和 fd_retrieve 是否允许我存储将数据结构放入程序自己的 DATA 文件句柄中。我意识到这不是最佳实践,我只是好奇它是否有效,我的快速尝试似乎不起作用。
I was curious if using Storable's store_fd and fd_retrieve would allow me to store a data structure into a program's own DATA filehandle. I realize this isn't Best Practice, I'm just curious if it'd work, my quick attempts to try it don't seem to work.
发布评论
评论(4)
我不确定你为什么要这样做,但你可以假装它。但你应该尽量避免这种情况。
只是为了咯咯笑,您可以打开一个文件句柄,从
$0
读取行并打印它们,直到到达__DATA__
,然后添加新的__DATA__
部分。然后,诀窍是将新文件重命名为$0
,如果您的系统在程序运行时锁定该文件,则可能通过exec
重命名:I'm not sure why you'd want to do that, but you can fake it. You should try to avoid that though.
Just for giggles, you could open a filehandle, read lines from
$0
and print them until you get to__DATA__
, then add your new__DATA__
section. The trick is then to rename your new file to become$0
, perhaps by anexec
if your system locks the file while the program is running:DATA
是一个句柄,用于读取与脚本一起存储的数据。 Conway 的 Inline::Files 是我临时知道的唯一谈论可写虚拟文件。由于脚本文件通常是 ASCII,我不知道如果在 Storable 的输出中得到 MSDOS 上的二进制 26 字节或 UNIX 上的二进制 4 会发生什么。但是,如果您谈论的是通过在其中键入来存储数据,只是为了从脚本中读取数据,那么二进制问题仍然存在面对你。
因此,最好使用 YAML 或 JSON 用于持久性。我知道 YAML 在从 DATA 检索数据时会处理祝福。
DATA
is a handle to read data stored with the script. Conway's Inline::Files is the only module I know offhand that talks of writable virtual files. And since script files are usually ASCII I don't know what would happen if you got a binary 26 byte on MSDOS or a binary 4 on UNIX in the output of Storable.However, if you are talking about you storing data by typing it in there, only to read it from a script, then the binary problem still confronts you.
So, it's better to go with YAML or JSON for persistence. I know that YAML will handle the blessing when retrieving the data from DATA.
在正常情况下这是不可能的:
但您可以创建特殊的条件:
在 Windows 上,由于其默认的文件共享语义,您将收到有关
unlink
的警告。如果这是您的平台,您可以在END
时间进行清理或使用Win32::SharedFileOpen。It's not possible in ordinary conditions:
But you can create extraordinary conditions:
On Windows, you'll get a warning on the
unlink
because of its default file-sharing semantics. If that's your platform, you can clean up atEND
time or use Win32::SharedFileOpen.我想出了自己的解决方案......并不是我特别推荐它或任何其他解决方案;就我而言,它是一个单元测试脚本,具有多维哈希结构中的参考值。我不会详细介绍这个东西的作用和原因,但最终结果是代码中的一个小修复或更改可能会导致许多值需要更新(在验证更改有效之后)。
因此,我使用
Data::Dumper
将哈希移至__DATA__
部分。将其写入文件句柄的代码如下所示:在脚本的开头,我在存储对初始句柄的位置和 mtime 的引用后从
DATA
加载哈希值(mtime 用于确保文件没有在脚本执行期间没有被修改)。最后,为了更新
__DATA__
部分,我在$FILEPOS
打开__FILE__
,截断它并写入。我简化了此示例的错误处理。请务必在开发时保留文件备份,因为一个错误可能会毁掉您的所有代码!
另请注意,这同样适用于
Storable
;存储将更加高效、更快。唯一需要注意的是它是二进制的,这意味着文件差异可能不会显示在源代码管理中,并且它不像 Dumper 的输出那样容易编辑。I came up with my own solution... not that I specifically recommend it or any others; in my case it's a unit test script with reference values in a multi-dimensional hash structure. I won't go into the technical details of what this things does and why, but the end result is that a small fix or change in the code can result in many values requiring an update (after validating the change is valid).
Therefore I moved the hash into the
__DATA__
section usingData::Dumper
. The code to write that to a file handle looks like:At the beginning of the script I load the hash from
DATA
after storing references to the initial handle's position and mtime (mtime is used to ensure the file hasn't been modified during the script's execution).Finally, to update the
__DATA__
section I open__FILE__
at$FILEPOS
, truncate it and write to it. I simplified error handling for this example.Be sure to keep backups of your files as you develop as a single mistake could destroy all your code!
Also note that the same would work with
Storable
; storage would be more efficient and faster. The only caveat is that it's binary, which means file diff will likely not show up in source control, and it's not as easy to edit as Dumper's output.