Jim Freeze <jim / freeze.org> wrote: > On 9/27/05, Jim Freeze <jim / freeze.org> wrote: > > Concerning multiple containers for an object: >> Here are four methods that I can see as potential solutions: >> >> 1. obj.each(:container) { |element| ... } >> 2. obj.each_container { |element| ... } >> 3. obj.container.each { |element| ... } >> 4. obj.container; obj.each { |element| ... } >> >> No. (4) simply sets an internal state variable to indicate which >> container #each uses. Not pretty, and not thread safe, but permits >> Enumerable to >> be used. 4. is definitely a non option. That's in the same league as containers glued together with an iterator (not #each). That's simply a don't do. It's thread unsafe and error prone. I strongly favor 3 with an optional variant of a read only proxy returned (using Enumerator for example). 2 is ok also and maybe 1, too. Normally OO suggests to have separate methods but since you can easily say this in Ruby 1 seems ok, too: def each(cont, &b) instance_variable_get("@#{cont}").each(&b) self end IOW you don't need to touch this method when you add more containers. > I am curious what people think about these methods. > To all you pattern experts, is there a pattern for this > situation? Not that I'm a pattern expert... I'll throw in my 0.02EUR anyway: - My rule of thumb, if the object's main task is to be a container, give it an each method - this makes usage for clients convenient (example TreeNode, each will iterate child nodes). - If there are several containers contained :-) then make them accessible and let clients work with them. You save yourself a lot of hassle and name collisions (KISS). - Remember: there's no way to protect the internals of an instance: if someone wants to screw up your instance he can always use send, instance_eval, instance_variable_get and *_set to access your innards. Kind regards robert