如何在Ruby中模拟类/方法友谊?

时间:2013-07-11 00:32:28

标签: ruby methods friend

我记得(几乎没有)在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 ++的类/方法友情功能吗?如果没有,我还能如何处理上述问题?

2 个答案:

答案 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