我认为这是一个范围相关的问题。如果我对我的对象有这样的规则:
:- public(new/2).
:- mode(new(+list, -object_identifier), one).
new(Args, Instance) :-
self(Self),
create_object(Instance, [instantiates(Self)], [], []),
Instance::process_arguments(Args).
如果我跳这个舞,我觉得这很好用:
:- object(name, instantiates(name)).
我不完全理解为什么这是必要的,但我怀疑它与我的实际问题有关,即如果我的对象中有标准 Prolog 循环,如下所示:
process_arguments([Arg|Args]) :- process_arg(Arg), process_arguments(Args).
process_arguments([]).
process_arg(Arg) :- ::asserta(something(Arg)).
我发现这种使用::asserta
将事实放在正确的名称空间中(在新创建的实例上)。但是,如果我机智地process_arguments/1
用这个 lambda 表达式替换 的主体:
process_arguments(Args) :- meta::map([Arg]>>process_arg(Arg), Args).
然后我将事实添加到父类并由所有实例共享。如果我用这个替换它:
process_arguments(Args) :-
self(Self),
meta::map([Arg]>>(Self::process_arg(Arg)), Args).
process_arg/1
然后它会起作用,但是当我不想这样做时,我必须制定一条公共规则。我错过了什么?