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: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 <code@apotheon.net> 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 <lists@ruby-forum.com> 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
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.