我记得(几乎没有)在C ++中你可以创建朋友类或方法,能够访问你的私人成员。坦率地说,我从未发现这个功能特别有用。
现在我将Ruby用于游戏开发框架。我正在制作一个简单的节点系统(一个节点可以包含其他子节点,并有一个父节点)。
我的Node
班级有#add_child(child)
。问题是,当A
节点获得子B
节点时,我需要将B
的{{1}}引用设置为指向@parent
。所以在A
内我有这个电话:
#add_child(child)
现在child.set_parent(self)
的{{1}}变量指向B
。这很好用。
但是,@parent
仅适用于此特定情况。只有在调用A
时才能调用它。如果我在上下文之外使用#set_parent(parent)
,节点系统可能会中断。
现在我发现类/方法友情有用。如果我#add_child(child)
只能#set_parent(parent)
使用,那么如果某个随机程序员决定自己调用#set_parent(parent)
,我的系统就不会中断。
从一些搜索来看,Ruby似乎没有明确地具有此功能。
Ruby提供类似C ++的类/方法友情功能吗?如果没有,我还能如何处理上述问题?
答案 0 :(得分:5)
这应该有效:
class Node
def add_child(child)
@children << child # or whatever
child.instance_exec(self) { |parent| set_parent(parent) }
end
end
在instance_exec
内,你好像在另一个对象里面,所以你可以调用私有方法,甚至可以直接设置实例变量。 child.instance_exec(self) { |parent| @parent = parent }
也可以。您也可以child.send(:set_parent, self)
或child.instance_variable_set(:parent, self)
,但我认为instance_exec
会让您更清楚自己在做什么。因人而异。 :)
Ruby只是名义上保护其班级的内部,足以让你不会意外地将自己射中脚。但它的内省功能非常强大,如果你愿意,你可以从任何地方访问任何东西。
答案 1 :(得分:1)
还有“朋友”宝石,它将此语言功能添加到ruby:https://github.com/lsegal/friend