首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用:与CompUnit一起使用

如何使用:与CompUnit一起使用
EN

Stack Overflow用户
提问于 2018-10-26 16:57:25
回答 1查看 151关注 0票数 8

我正在尝试通过使用CompUnit类集预编译它们来创建POD6的缓存。

我可以创建、存储和检索pod,如下所示:

代码语言:javascript
复制
use v6.c;
use nqp;
my $precomp-store =     CompUnit::PrecompilationStore::File.new(prefix=>'cache'.IO);
my $precomp = CompUnit::PrecompilationRepository::Default.new(store=> $precomp-store );
my $key = nqp::sha1('test.pod6');
'test.pod6'.IO.spurt(q:to/CONTENT/);
=begin pod
=TITLE More and more

Some more text

=end pod

CONTENT
$precomp.precompile('test.pod6'.IO, $key, :force);
my $handle = $precomp.load($key, )[0];
my $resurrected = nqp::atkey($handle.unit,'$=pod')[0];
say $resurrected ~~ Pod::Block::Named;

那么现在我改变了POD,我如何使用:since标志呢?我认为如果:since包含编译后的时间,那么句柄的值应该是Nil。情况似乎并非如此。

代码语言:javascript
复制
my $new-handle = $precomp.load($key, :since('test.pod6'.IO.modified));
say 'I got a new handle' with $new-handle;

输出是“我有一个新的句柄”。

我做错了什么?下面是一个带有代码和输出的粘贴链接:https://pastebin.com/wtA9a0nP

EN

回答 1

Stack Overflow用户

发布于 2018-10-26 23:47:09

模块加载代码缓存查找,本质上是这样开始的:

代码语言:javascript
复制
$lock.protect: { 
    return %loaded{$id} if %loaded{$id}:exists; 
}

因此,问题变成了“我如何加载一个模块,然后卸载它(这样我就可以再次加载它)?”答案是:你不能卸载一个模块。但是,您可以更改文件名、分发长名(通过更改名称、身份验证、api或版本)或预编译id --无论特定的CompUnit::Repository用来唯一地标识模块--以绕过缓存。

似乎被忽视的是,$key旨在表示一个不可变的名称,这样它将始终指向相同的内容。应该为模块Used::Inside::A加载哪个版本的foo.pm如果foo.pm是由模块AB同时加载的,那么模块A首先加载foo,然后模块B修改foo?加载的是旧版本的模块A,还是(可能与以前的版本冲突)加载的模块B的版本?这种差异对预压缩文件生成本身是如何工作的(同样可以并行发生)?

当然,如果我们忽略以上这些,我们可能会添加代码,为所有CompUnit::Repository类型的每个模块加载进行昂贵的.IO.modified调用(减慢启动速度),从而说“嘿,这个不可变的东西改变了”。但一些操作系统上文件系统修改时间戳的粒度使得检查非常脆弱(特别是对于多线程模块加载和生成的预压缩文件),这意味着每次都需要更昂贵的调用来获取校验和。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53005084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档