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!

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

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!!

···

--
Posted via http://www.ruby-forum.com/.

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.

···

--
Posted via http://www.ruby-forum.com/.

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.

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/\.

Why not use modules as namespaces?

···

On Mon, Aug 13, 2012 at 04:35:00PM +0900, John Doe wrote:

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!!

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

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.

http://c2.com/cgi/wiki?GodObject
http://c2.com/cgi/wiki?GodClass

Kind regards

robert

···

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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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 :wink:

···

--
Posted via http://www.ruby-forum.com/\.

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 Mon, Aug 13, 2012 at 9:17 PM, Chad Perrin <code@apotheon.net> wrote:

Why not use modules as namespaces?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

···

--
Posted via http://www.ruby-forum.com/\.

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!

···

--
Posted via http://www.ruby-forum.com/\.

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.

···

--
Posted via http://www.ruby-forum.com/\.