gpt4 book ai didi

Logtalk:meta::map、lambda 表达式和对私有(private)方法的访问

转载 作者:行者123 更新时间:2023-12-02 15:45:44 25 4
gpt4 key购买 nike

我认为这是一个与范围相关的问题。如果我对我的对象有这样的规则:

:- 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 的使用将事实放入正确的命名空间中(在新创建的实例上)。然而,如果我机智地用这个 lambda 表达式替换 process_arguments/1 的主体:

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 设为公共(public)规则。我缺少什么?

最佳答案

让我首先从上面的代码片段开始,其中对象 name 实例化了自身。这样做时,您将 name 创建为它自己的类。没有什么不对的地方。在支持元类的语言中,例如 Smalltalk 和 Logtalk,将类设为自己的元类是避免无限回归的经典方法。例如,请参阅有关元类的维基百科条目 ( http://en.wikipedia.org/wiki/Metaclass )。另请参阅 Logtalk 发行版中的“反射”示例。通过使对象 name 实例化自身,它既扮演实例的角色(因为它实例化对象),又扮演类的角色(因为它由对象实例化)。如果您将 name 定义为独立对象,即与其他对象无关的对象,它将被编译为原型(prototype)。

现在回答你的问题。在 Logtalk 中,元谓词(例如 meta::map/2)在发送者的上下文中调用。如果 process_arguments/1 谓词在 name 中定义,则执行上下文(包括 self 的值)将为 name。因此,something/1 的子句将在 name 中断言。您的解决方法(通过使用内置方法 self/1)按预期工作,但它确实强制您声明 process_arg/1 公共(public)谓词。这是稳定 Logtalk 版本中的一个错误,因为它也应该通过声明 process_arg/1 谓词 protected 或私有(private)来工作(因为发送者name 并且谓词在发送者中声明)。例如:

:- object(name,
instantiates(name)).

:- public(new/2).
:- mode(new(+list, -object_identifier), one).
new(Args, Instance) :-
self(Self),
create_object(Instance, [instantiates(Self)], [set_logtalk_flag(dynamic_declarations, allow)], []),
meta::map({Instance}/[Arg]>>(Instance::process_arg(Arg)), Args).

:- private(process_arg/1).
process_arg(Arg) :-
::asserta(something(Arg)).

:- end_object.

我将在本周晚些时候将错误修复推送到公开可用的 Logtalk 开发版本中。感谢您让我注意到这个错误。

关于Logtalk:meta::map、lambda 表达式和对私有(private)方法的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9460835/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com