This is an aesthetic problem: I have a method in a module, and I want
to include it in three different classes (they’re all in the same
file). This method refers itself to one of those classes. So i have to
include the module into the classes, but for the method to be parsed,
one of those classes needs to be already defined.
module ElementFactory
def element_factory(what)
(…)
Element.new
end
end
class Element
include ElementFactory
(…)
end
class Document
include ElementFactory
(…)
end
class ElementCollections
include ElementFactory
(…)
end
So for this class Element there’s a circular dependency and, as ruby
does single-pass parsing, this can’t work. What I’ve done so far is to
replace the explicit reference to Element in the module instance
method by a call to Object.const_get(:Element) so that when it’s
called, Element will already be defined. But this looks a bit ugly.
isn’t there a better way to solve this?
The circular dependency hints at not having the module at all and just
putting the instance method element_factory() into Element itself but
there are those other two classes that include it, so I can’t do that.
“Then there were the lonely few of us
who moved back and forth on the strip,
eating rows of beads here and there,
pretending we were Turing machines.”
– xkcd : xkcd: Candy Button Paper
This is an aesthetic problem: I have a method in a module, and I want
to include it in three different classes (they’re all in the same
file). This method refers itself to one of those classes. So i have to
include the module into the classes, but for the method to be parsed,
one of those classes needs to be already defined.
You can define the Element class at the top, and then reopen it later to
include the module and define your methods. Just make sure that if
Element is a subclass of something, the first “class Element” must
have the " < SuperClass". But in this case all you have to do is add
these lines:
This is an aesthetic problem: I have a method in a module, and I want
to include it in three different classes (they’re all in the same
file). This method refers itself to one of those classes. So i have to
include the module into the classes, but for the method to be parsed,
one of those classes needs to be already defined.
You’re still thinking in terms of static typing. In this case you don’t have a circular dependency. You can load ElementFactory first
and it doesn’t matter if Element is not yet defined, as long as you
don’t invoke the method ‘element_factory’
don’t invoke the method ‘element_factory’
Having said that I’d still consider the cyclic dependency (on the
logical level) bad design. We do not know more about those classes but
my impression is that this can probably improved upon.
On Mon, Jun 11, 2007 at 05:20:25PM +0900, Robert K. wrote:
Having said that I’d still consider the cyclic dependency (on the
logical level) bad design. We do not know more about those classes but
my impression is that this can probably improved upon.
I’m new to the mailinglist … so I’m not sure if this has been mentioned
or
not. There’s a cool site which discusses the implementation of (the gang
of
four) patterns in Ruby. In this case you may want to check out
The circular dependency hints at not having the module at all and just
putting the instance method element_factory() into Element itself but
there are those other two classes that include it, so I can’t do that.
Thanks a lot for any ideas!
Forward declaration?
class Element
end
class ElementFactory
…
end
class Element
actual content goes here!
end
-s
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.