如何确保所有模块(理想情况下还包括已加载或包含的所有其他文件)都是最新的?发出mymodule.pl
时,SICStus会比较文件include
的修改日期并重新加载,如果更新的话。此外,mymodule
- ed文件将触发重新编译。但它不会重新检查make/0
使用的所有模块。
简介,如何获得与SWI提供的def zipMerge(*lists):
dicts = map(dict, lists)
base = { }
items = 0
for d in dicts:
items += 1
for k,v in d.iteritems():
if k not in base:
base[k] = [k] + [None] * len(lists)
base[k][items] = v
return map(tuple, sorted(base.itervalues()))
相似的功能?
答案 0 :(得分:5)
SICStus Prolog中没有提供这种功能。
一个很大的问题是,除了非常简单的情况之外,当前的Prolog对于像make / 0这样的东西来说太过动态了。通过术语扩展,加载期间执行的目标(包括常见的文件加载目标)等功能,无法知道如何可靠地重新加载文件。我没有密切关注它,但可能在SWI Prolog中使得/ 0有同样的问题。
我通常只是重新启动Prolog进程并再次加载“main”文件,即加载我需要的所有内容的文件。
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
| ?-
答案 1 :(得分:3)
到目前为止,我和几个黑客一起生活过:
SICStus始终拥有Quintus原点的ensure_loaded/1
,它不仅是指令(如ISO),而且也是一个命令。所以我编写了自己的make-predicate,简单地枚举了所有文件:
l :-
ensure_loaded([f1,f2,f3]).
发出l.
后,只会重新加载同时修改过的那些文件。
也许,我本来也可以这样写 - 我会读懂平均值(原文如此):
l :-
\+ ( source_file(F), \+ ensure_loaded(F) ).
随着模块的改变,事情发生了变化。一方面,有些文件被手动加载到模块中,如ensure_loaded(module:[f1,f2,f3])
,然后是那些干净的模块。事实证明,有一种方法可以全局确保加载模块 - 只需通过声明use_module(m1, [])
再次作为指令和命令来干扰实际的导入列表。重点是空列表导致模块被重新检查并重新加载,但由于空列表,该语句可以在任何地方进行。
与此同时,我使用以下模块:
:- module(make,[make/0]).
make :-
\+ ( current_module(_, F), \+ use_module(F, []) ).
这适用于所有" legal"模块 - 只要接口不变。我仍然不喜欢的是它的冗长:对于每个选中的和未修改的模块,都有一条消息行。所以当我只是想检查一切是否是最新的时候,我得到一个充满了这样的消息的页面。理想情况下,此类消息只会显示是否有新事件发生。
| ?- 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
improved version考虑了@ 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
都不比较文件修改日期。因此,两者都不能用于确保加载最新版本的文件。