I have a large class with many instance methods that I want to namespace: object.namespace1.method_a object.namespace1.method_b object.namespace2.method_c object.namespace2.method_d How do I accomplish this? Of course I can always do this: object.namespace1_method_a object.namespace1_method_b But I'm wondering if there's a better way. Thanks in advance!
on 2012-08-13 03:17
on 2012-08-13 07:23
Hi, When the class is so large that you want to categorize the methods, it's definitely too large. Split the big class into several smaller classes. The obvious approach would be to create a separate class for each of your "namespaces".
on 2012-08-13 09:34
Thanks for the quick reply. I guess what I really want is an object within an object so I can still make calls like: object.namespace1.method_a in other words: object1.object2.method_a class Object1 def object2 Object2.new end end class Object2 def method_a end end object1 = Object1.new object1.object2.method_a And that seems to work :) Thanks again for the help!!
on 2012-08-13 09:49
That does work, but it makes no sense, because you're creating a new object on every call. The objects should be created in the initialize method and then saved in instance variables.
on 2012-08-13 10:09
Lol. Thank you :) looking forward to this journey
on 2012-08-13 10:50
Jan E. wrote in post #1072166: > The objects should be created in the initialize method and then saved in > instance variables. Or you can use a lazy initialize: class Top class Facade1 ... end class Facade2 ... end def facade1 @facade1 ||= Facade1.new(self) end def facade2 @facade2 ||= Facade2.new(self) end end
on 2012-08-13 21:18
On Mon, Aug 13, 2012 at 04:35:00PM +0900, John Doe wrote: > def object2 > object1.object2.method_a > > And that seems to work :) Thanks again for the help!! Why not use modules as namespaces?
on 2012-08-14 01:46
Brian Candler wrote in post #1072176: > Or you can use a lazy initialize: Very nice! Chad Perrin wrote in post #1072243 > Why not use modules as namespaces? I guess I don't know the difference between Classes vs. Modules when it comes to namespacing? My understanding is that you would use a Module if you intended to reuse that class elsewhere. In my case, class Object2 will only be referenced by class Object1 so I think classes seem to work great? I'm probably missing the obvious ;)
on 2012-08-14 10:18
John Doe wrote in post #1072269: > My understanding is that you would use a Module if you intended to reuse > that class elsewhere. No, using modules as mixins for classes is only one purpose. You can also use them as namespaces or as collections of "functions" (like the Math module). Modules are generally used as "static" collections, while classes are used to create instances. But there may be situations where both fit.
on 2012-08-14 10:22
On Mon, Aug 13, 2012 at 9:17 PM, Chad Perrin <email@example.com> wrote: > Why not use modules as namespaces? How would you use modules as namespaces here? If the class includes all those modules their methods are not in different namespaces but all visible at the instance. I agree with what Jan wrote: if the class is so large then there are definitively too many methods and too few classes. OP, can you please show a realistic example or explain what you want to do? Kind regards robert
on 2012-08-14 18:08
Robert Klemme wrote in post #1072313: > OP, can you please show a realistic example or explain what you want to do? Thanks Robert - here's what I'm trying to do: hostname = WebProperty.new 'www.yahoo.com' hostname.DNS.lookup hostname.HTTP.lookup Where hostname, DNS and HTTP all have many of their own methods but there is a direct relationship between hostname + DNS and hostname + HTTP Thanks!
on 2012-08-14 21:46
John Doe wrote in post #1072359: > hostname = WebProperty.new 'www.yahoo.com' > hostname.DNS.lookup > hostname.HTTP.lookup HTTP doesn't have a "lookup" operation, so do you mean something like hostname.HTTP.get('/index.html') ? This is the typical OO conundrum. For a method which takes two object arguments, which class does the logic belong to? If there is no polymorphism involved then it doesn't really matter, and in this case arguably it doesn't belong to either: HTTP.get(hostname, '/index.html') Or maybe the logic belongs in a URI object. One advantage of your approach is that hostname.HTTP could keep track of a persistent HTTP connection, so that a series of hostname.HTTP.get() operations would re-use the same connection. My natural inclination would be instead to have a "HTTP fetcher" class: this is not too dissimilar, but it makes it more obvious how to set options which are specific to the HTTP connection, rather than to the thing you're connecting to. (Timeouts, for example). http1 = HTTP.new :hostname=>'www.google.com', :http_proxy=>"gw1.example.com" http2 = HTTP.new :hostname=>'www.yahoo.com', :http_proxy=>"gw2.example.com" yahoo = http1.get '/index.html' google = http2.get '/index.html' This approach is also arguably more pluggable. But this is entirely subjective: hostname.HTTP.get(path) will obviously work, and if it makes sense for your particular application, then by all means use it.
on 2012-08-14 22:24
Brian, thank you for the taking the time to write such a complete response. It's reassuring to know that I'm on the right track. Thanks again - really appreciate it.
on 2012-08-15 09:04
On Tue, Aug 14, 2012 at 10:24 PM, John Doe <firstname.lastname@example.org> wrote: > Brian, thank you for the taking the time to write such a complete > response. It's reassuring to know that I'm on the right track. I am not sure. What is your motivation for having one object and distributing methods across a number of other objects? I am asking because there is an anti pattern called "god object". What you describe has some similarities with that - but I can't say for sure yet. https://en.wikipedia.org/wiki/God_object http://c2.com/cgi/wiki?GodObject http://c2.com/cgi/wiki?GodClass Kind regards robert