5

如何确保所有模块(以及理想情况下已加载或包含的所有其他文件)都是最新的?发布时use_module(mymodule),SICStus 会比较文件的修改日期mymodule.pl并重新加载(如果更新)。此外include-ed 文件将触发重新编译。但它不会重新检查mymodule.

简而言之,我怎样才能获得与 SWI 提供的类似功能make/0

4

2 回答 2

7

SICStus Prolog 中没有任何东西可以提供这种功能。

一个大问题是当前的 Prolog 过于动态,以至于 make/0 之类的东西无法可靠地工作,除非是非常简单的情况。使用术语扩展、加载期间执行的目标(包括常见的文件加载目标)等功能,不可能知道如何可靠地重新加载文件。我没有仔细看过它,但大概是 SWI Prolog 中的 make/0 也有同样的问题。

我通常只是重新启动 Prolog 进程并再次加载“主”文件,即加载我需要的所有内容的文件。

PS。我无法在评论中获得代码格式,所以我把它放在这里:示例为什么 make/0 需要防范 'user' 作为来自 current_module/2 的文件:

| ?- [user].
% compiling user...
| :- module(m,[p/0]). p. end_of_file.

%  module m imported into user
% compiled user in module m, 0 msec 752 bytes
yes
| ?- current_module(M, F), F==user.
F = user,
M = m ? ;
no
| ?-
于 2016-01-01T21:35:14.033 回答
5

到目前为止,我已经经历了几个黑客:

高达 0.7 – 模块前时间

SICStus 始终源自ensure_loaded/1Quintus,它不仅是指令(如 ISO 中的指令),而且还是命令。所以我编写了自己的 make-predicate 来简单地枚举所有文件:

l :-
   ensure_loaded([f1,f2,f3]).

发布后l.,仅重新加载同时修改的那些文件。

可能,我也可以这样写——我会读到意思(原文如此):

l :-
   \+ ( source_file(F), \+ ensure_loaded(F) ).

3.0 – 模块

有了模块,事情发生了一些变化。一方面,有些文件是手动加载到模块中的,例如ensure_loaded(module:[f1,f2,f3]),然后是干净的模块。事实证明,有一种方法可以全局确保模块已加载——无需干扰实际的导入列表,只需说明use_module(m1, [])哪个又是指令和命令。关键是导致模块被重新检查和重新加载的空列表,但是由于空列表可以在任何地方进行声明。

同时,我使用以下模块:

:- module(make,[make/0]).

make :-
   \+ ( current_module(_, F), \+ use_module(F, []) ).

这适用于所有“合法”模块——只要接口不变。我仍然不喜欢它的冗长:对于每个已检查和未修改的模块,都有一个消息行。因此,当我只想检查所有内容是否都是最新的时,我会得到一个充满此类消息的页面。理想情况下,此类消息仅在发生新情况时才会显示。

| ?- make.
% module m2 imported into make
% module m1 imported into make
% module SU_messages imported into make
yes
| ?- make.
% module m2 imported into make
% module m1 imported into make
% module SU_messages imported into make
yes

改进的版本 考虑了@PerMildner 的评论。

如果它们与一个模块相关,则可以重新加载更多文件。特别是,加载到模块user中的文件像.sicstusrc. 有关完整代码,请参见上面的链接。

   % reload files that are implicitly modules, but that are still simple to reload
    \+ (
            source_file(F),
            F \== user,
            \+ current_module(_, F),  % not officially declared as a module
            setof(M,
                P^ExF^ExM^(
                    source_file(M:P,F),
                    \+ current_module(M,ExF), % not part of an official module
                    \+ predicate_property(M:P,multifile),
                    \+ predicate_property(M:P,imported_from(ExM))
                    ),[M]),   % only one module per file, others are too complex
            \+ ensure_loaded(M:F)
    ).

请注意,在 SWI 中既不比较文件修改日期,ensure_loaded/1也不use_module/2比较文件修改日期。因此两者都不能用于确保加载文件的最新版本。

于 2016-01-01T22:30:43.060 回答