Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Way to Resolve Circular Module Loading

I'm trying to have two different objects that refer to each other and also use type checking on the attributes. When I do this I get Circular module loading detected trying to precompile. Googling gets me https://docs.raku.org/language/faq#Can_I_have_circular_dependencies_between_modules? which states:

Note that Raku has no “1 file = 1 class” limitation, and circular dependencies within a single compilation unit (e.g., file) are possible through stubbing. Therefore another possible solution is to move classes into the same compilation unit.

I'd rather not put both classes into the same unit if I can avoid it. I'm not sure how to accomplish this with stubbing since there is no example. The following is a small example of what I'm trying to do:

Yak.rakumod

unit class Yak;

use YakStore;

has YakStore $.yak-store is rw;

YakStore.rakumod

unit class YakStore;

use Yak;

has Yak $.yak is rw;

yak.rakutest

use lib '.';

use Test;

use Yak;
use YakStore;

plan 2;

my $yak-store = YakStore.new;

my $yak = Yak.new(:$yak-store);

$yak-store.yak = $yak;

isa-ok $yak-store.yak, Yak;
isa-ok $yak.yak-store, YakStore;

Yeah, I know, the test is lame, but I just wanted to illustrate the problem. Thanks!

like image 744
JustThisGuy Avatar asked Jun 09 '21 23:06

JustThisGuy


People also ask

How do I get rid of circular dependency?

The Mediator Pattern can also help to lift circular dependencies by encapsulating the bidirectional interaction of two or more objects. The downside of your current code is (besides the circular dependency), that whenever class A changes and also data persistence changes, you have to touch and modify class B.

What is the best way to deal with circular dependencies?

In the Node.js docs, it says, “Careful planning is required to allow cyclic module dependencies to work correctly within an application.” In my experience, the best way to deal with circular dependencies is to avoid them altogether.

Does node support circular require/import statements between modules?

Node.js does support circular require/import statements between modules, but it can get messy quickly. In the Node.js docs, it says, “Careful planning is required to allow cyclic module dependencies to work correctly within an application.” In my experience, the best way to deal with circular dependencies is to avoid them altogether.

What is Python circular import problem?

But many times unknowingly, we can run into python circular import problems if we accidentally have another file named as module’s name. As python prefers importing from the local current directory first and then from site-packages, it will create a circular import problem.

How to avoid circular dependencies in Webpack?

This circular relationship caused a problem and webpack could not resolve the dependencies correctly. Our solution was to upgrade our modules to use ES6 import/exports. This enabled us to reuse the react components and avoid circular dependencies while moving us closer to ES standards. We upgraded as much as we could without affecting other teams.


1 Answers

The best way to deal with circular dependencies is to turn your circle into a triangle – that is, to make both classes that would depend on each other instead depend (at least in part) on some third Role.

Here's how that might look with the example you provided and a Shaveable role (Yaks should be Shaveable, right?):

Shaveable.rakumod

unit role Shaveable;

Yak.rakumod

use YakStore;
use Shaveable;

unit class Yak does Shaveable;

has YakStore $.yak-store is rw;

YakStore.rakumod

use Shaveable;
unit class YakStore;

has Shaveable $.yak is rw;

With that change, the tests in your example now pass.

like image 151
codesections Avatar answered Oct 20 '22 20:10

codesections