Robert Klemme
5/26/2007 11:20:00 AM
On 26.05.2007 13:12, Peter Seebach wrote:
> I am trying to figure out what the cleanest way is to express a class that has
> subclasses.
First of all, your example is about nested classes and not subclasses.
> Imagine, if you will:
> class Foo
> def initialize
> @bar = Foo::Bar.new(self)
> end
> end
>
> class Foo::Bar
> def initialize(foo)
> @foo = foo
> end
> end
>
> Is that a good rubyish way to do this? If I put Foo::Bar in
> its own file, should foo.rb be responsible for requiring it?
> What originally got me thinking was that my habit is to put requires,
> includes, and such at the top of the file... But then the
> declaration "class Foo::Bar" refers to an undefined constant.
That's not an issue as long as you evaluate that only after the constant
has been defined:
irb(main):001:0> def test() Foo.new end
=> nil
irb(main):002:0> class Foo; end
=> nil
irb(main):003:0> test
=> #<Foo:0x7ff95f40>
> Of course, I can write:
> class Foo
> end
> require 'foo/bar.rb'
>
> Is there a clear preference here in Ruby Style?
I would not put these in different files as Foo depends on Foo::Bar and
Foo::Bar depends on Foo.
I'd do
class Foo
def initialize
@bar = Bar.new self
end
class Bar
def initialize(foo)
@foo = foo
end
end
end
irb(main):012:0> Foo.new
=> #<Foo:0x7ff7883c @bar=#<Foo::Bar:0x7ff78738 @foo=#<Foo:0x7ff7883c ...>>>
Another question is whether you really want nested classes or maybe
rather classes in the same namespace. Basically I create nested classes
if the nested class only makes sense in the context of the outer class.
The situation is however different than in Java where all this is much
more strict (and thus clear).
Kind regards
robert