Namespace instance methods?

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!

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”.

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.

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 :slight_smile: Thanks again for the help!!

Lol. Thank you :slight_smile: looking forward to this journey

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

Brian C. wrote in post #1072176:

Or you can use a lazy initialize:

Very nice!

Chad P. 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 :wink:

John D. 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 Mon, Aug 13, 2012 at 04:35:00PM +0900, John D. wrote:

def object2
object1.object2.method_a

And that seems to work :slight_smile: Thanks again for the help!!

Why not use modules as namespaces?

On Mon, Aug 13, 2012 at 9:17 PM, Chad P. [email protected] 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

Robert K. 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!

John D. 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.

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 Tue, Aug 14, 2012 at 10:24 PM, John D. [email protected] 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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs