I remember (barely) in C++ that you could create friend classes or methods, capable of accessing your private members. Frankly, I never found that feature particularly useful.
Now I am using Ruby for a game development framework. I'm making a simple node system (a node can contain other children nodes, and have a parent node).
My Node
class has #add_child(child)
. The thing is, when A
node gets a child B
node, I need to set B
's @parent
reference to point to A
. So inside #add_child(child)
I have this call:
child.set_parent(self)
Now B
's @parent
variable points to A
. And this works just fine.
But, #set_parent(parent)
is only meant to be used for this specific scenario. It must only be called when #add_child(child)
is called. If I used #set_parent(parent)
out of context, the node system may break.
Now I do find the class/method friendship thing useful. If I could make #set_parent(parent)
only usable by #add_child(child)
, my system wouldn't break if some random programmer decided to call #set_parent(parent)
by themselves.
From a few searches it doesn't seem like Ruby has this feature explicitly.
Does Ruby offer class/method friendship features like C++ does? If not, how else can I work around the described problem?
This should work:
class Node
def add_child(child)
@children << child # or whatever
child.instance_exec(self) { |parent| set_parent(parent) }
end
end
Inside instance_exec
you're as if inside the other object, so you can invoke private methods, or even directly set instance variables. child.instance_exec(self) { |parent| @parent = parent }
would work as well. You could also do child.send(:set_parent, self)
or child.instance_variable_set(:parent, self)
, but I think instance_exec
makes it a bit clearer what you're doing. YMMV. :)
Ruby only nominally protects the insides of its classes, enough that you don't shoot yourself in the foot by accident. But its introspection capabilities are powerful enough that you can access anything from anywhere if you want to.