Cyclical dependency due to platform-specific packages

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Cyclical dependency due to platform-specific packages

Sean DeNigris
I have MyClass in package Project-Core:

  MyClass class>>initialize
    ...
    self doPlatformSpecificStuff

In package Project-Platform:

  MyClass class>>doPlatformSpecificStuff (in *Project-Platform
protocol)

In my baseline, I have:

        spec
                package: 'Project-Core' with: [ spec
                        includes: 'Project-Platform' ];

The problem is:
* When Project-Core is loaded, it tries to send
doPlatformSpecificStuff (which is not there yet)
* if I switch to load Project-Platform first, it complains that
MyClass is an unresolved dependency

n.b. I put the initialize in MyClass to simplify the example, but it's
really two base classes up from MyClass

Two ideas I had:
1. put SuperSuperClassOfMyClass class>>initialize in a Project-
PlatformGlue package that gets loaded after Core and Platform
2. put SuperSuperClassOfMyClass class>>initialize in each Project-
Platform file (yuck, duplication), after extracting the work into a
helper method.
    So this would be duplicated in the Platform files:
        SuperSuperClassOfMyClass class>>initialize
           self doInitialization

But this seems like a lot of work, and I'm tired, so I may be missing
something obvious.

Can you point me to the best way to handle this?

Thanks
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Mariano Martinez Peck
Sean:  I think you are defining incorrectly the platform specific package. I wrote a first draft of a chapter for PharoByExample2. I attach it here. Read
"1.11 Platform specific package"

cheers

mariano

On Sat, May 15, 2010 at 5:25 AM, Sean DeNigris <[hidden email]> wrote:
I have MyClass in package Project-Core:

 MyClass class>>initialize
   ...
   self doPlatformSpecificStuff

In package Project-Platform:

 MyClass class>>doPlatformSpecificStuff (in *Project-Platform
protocol)

In my baseline, I have:

       spec
               package: 'Project-Core' with: [ spec
                       includes: 'Project-Platform' ];

The problem is:
* When Project-Core is loaded, it tries to send
doPlatformSpecificStuff (which is not there yet)
* if I switch to load Project-Platform first, it complains that
MyClass is an unresolved dependency

n.b. I put the initialize in MyClass to simplify the example, but it's
really two base classes up from MyClass

Two ideas I had:
1. put SuperSuperClassOfMyClass class>>initialize in a Project-
PlatformGlue package that gets loaded after Core and Platform
2. put SuperSuperClassOfMyClass class>>initialize in each Project-
Platform file (yuck, duplication), after extracting the work into a
helper method.
   So this would be duplicated in the Platform files:
       SuperSuperClassOfMyClass class>>initialize
          self doInitialization

But this seems like a lot of work, and I'm tired, so I may be missing
something obvious.

Can you point me to the best way to handle this?

Thanks
Sean

Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Sean DeNigris
On May 15, 10:00 am, Mariano Martinez Peck <[hidden email]>
wrote:
> Sean:  I think you are defining incorrectly the platform specific package. I
> wrote a first draft of a chapter for PharoByExample2. I attach it here. Read
Cool, thanks!

Two things:
1. Please be more specific about "incorrectly defining" so I know
where to focus.
2. I didn't see a link, did I miss it? (and didn't see anything
interesting via Google: "pharo by example" Platform specific package).

Sean
Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Mariano Martinez Peck


On Sat, May 15, 2010 at 6:22 PM, Sean DeNigris <[hidden email]> wrote:
On May 15, 10:00 am, Mariano Martinez Peck <[hidden email]>
wrote:
> Sean:  I think you are defining incorrectly the platform specific package. I
> wrote a first draft of a chapter for PharoByExample2. I attach it here. Read
Cool, thanks!

Two things:
1. Please be more specific about "incorrectly defining" so I know
where to focus.

I don't understand why you need a class side initialize.
I am not neither completely sure that's why I recommended you to read what I wrote that at least it is what is explained in Metacello tutorial.

 
2. I didn't see a link, did I miss it? (and didn't see anything
interesting via Google: "pharo by example" Platform specific package).


Sorry, I forgot to attach it. Now it is.

Read "1.11 Platform specific package"  and then maybe we can help you more.

Cheers

Mariano

Metacello.pdf (302K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Sean DeNigris
On May 15, 12:30 pm, Mariano Martinez Peck <[hidden email]>
wrote:
> Read *"1.11 Platform specific package"*  and then maybe we can help you
> more.*

Awesome resource!  Thanks for consolidating all that information.  It
was clear and thorough.  I'm posting my impressions in another thread.

So it may have been a lack of communication, as I think I followed the
procedures you outlined.  Let me see if I can fill in the gaps...

I am porting an existing project, ExternalWebBrowser to Pharo 1.1 and
Squeak 4.2 (trunks).  It currently has a method:
  MyClass class>>initialize
    ...
    self doPlatformSpecificStuff
    ...

So I put MyClass, including this method, in package Project-Core.

Then, in package Project-Platform, I put the platform-specific helper
method:
  MyClass class>>doPlatformSpecificStuff (in *Project-Platform
protocol)

The issue is that, if I require the Platform package in Core, there is
no class MyClass yet, and if I include it, MyClass class>>initialize
will run before doPlatformSpecificStuff is loaded.

After all this (very educational) conversation, I think I'm being a
perfectionist and just move MyClass class>>initialize into both
Platform packages (Squeak and Pharo) and have it just delegate to a
Core method.

Thanks for the support, and again for the excellent document.
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Dale
In reply to this post by Sean DeNigris
Sean,

see embedded comments
----- "Sean DeNigris" <[hidden email]> wrote:

| I have MyClass in package Project-Core:
|
|   MyClass class>>initialize
|     ...
|     self doPlatformSpecificStuff
|
| In package Project-Platform:
|
|   MyClass class>>doPlatformSpecificStuff (in *Project-Platform
| protocol)
|
| In my baseline, I have:
|
| spec
| package: 'Project-Core' with: [ spec
| includes: 'Project-Platform' ];
|
| The problem is:
| * When Project-Core is loaded, it tries to send
| doPlatformSpecificStuff (which is not there yet)
| * if I switch to load Project-Platform first, it complains that
| MyClass is an unresolved dependency
|
| n.b. I put the initialize in MyClass to simplify the example, but
| it's
| really two base classes up from MyClass

Loading Project-Core before Project-Platform is necessary because of the class relationshps.

The MyClass class>>initialize method gets triggered after Project-Core is loaded. In Metacello using #linear loadType Project-Core is loaded, then Project-Core initialize methods are run, then Project-Platform is loaded, then Project-Platform initialize methods are run. If you use #atomic loadType, then Project-Core is loaded, Project-Platform is loaded, then all initialize methods are run.

With that said, I'm not sure thate use #atomic load is the right solution in this case.

What I have done in similar cases is to include an #initialize method in my subclass of MyClass that does the platform-specific initialization for Project-Platform...

In this way you can have multiple Platforms each with their own specific initialization methods .... Trying to do it all from MyClass (which is a superclass) leads to all sorts of difficulties...


|
| Two ideas I had:
| 1. put SuperSuperClassOfMyClass class>>initialize in a Project-
| PlatformGlue package that gets loaded after Core and Platform
| 2. put SuperSuperClassOfMyClass class>>initialize in each Project-
| Platform file (yuck, duplication), after extracting the work into a
| helper method.
|     So this would be duplicated in the Platform files:
|         SuperSuperClassOfMyClass class>>initialize
|            self doInitialization
|
| But this seems like a lot of work, and I'm tired, so I may be missing
| something obvious.
|
| Can you point me to the best way to handle this?

Dale
Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Mariano Martinez Peck
In reply to this post by Sean DeNigris


On Sat, May 15, 2010 at 7:44 PM, Sean DeNigris <[hidden email]> wrote:
On May 15, 12:30 pm, Mariano Martinez Peck <[hidden email]>
wrote:
> Read *"1.11 Platform specific package"*  and then maybe we can help you
> more.*

Awesome resource!  Thanks for consolidating all that information.  It
was clear and thorough.  I'm posting my impressions in another thread.

So it may have been a lack of communication, as I think I followed the
procedures you outlined.  Let me see if I can fill in the gaps...

I am porting an existing project, ExternalWebBrowser to Pharo 1.1 and
Squeak 4.2 (trunks).  It currently has a method:
 MyClass class>>initialize
   ...
   self doPlatformSpecificStuff
   ...

So I put MyClass, including this method, in package Project-Core.

Then, in package Project-Platform, I put the platform-specific helper
method:
 MyClass class>>doPlatformSpecificStuff (in *Project-Platform
protocol)

The issue is that, if I require the Platform package in Core, there is
no class MyClass yet, and if I include it, MyClass class>>initialize
will run before doPlatformSpecificStuff is loaded.

Ok...I understood. Two points:

No...sorry, Dale has just told you about the #type:

So, one point: what about implementing:

MyClass class>>initialize
     self doPlatformSpecificStuff
 

MyClass class >> doPlatformSpecificStuff
    self error: 'This method should have been overridden '

Then...you define


MyClass class >> doPlatformSpecificStuff
     self realCode.....

but with category *MyPackage-Platform

so that you can override the other method?

Cheers

mariano
  



After all this (very educational) conversation, I think I'm being a
perfectionist and just move MyClass class>>initialize into both
Platform packages (Squeak and Pharo) and have it just delegate to a
Core method.

Thanks for the support, and again for the excellent document.
Sean

Reply | Threaded
Open this post in threaded view
|

Re: Cyclical dependency due to platform-specific packages

Sean DeNigris
Thank you Dale and Mariano :)  This forced me to think and learn a lot
about Metacello.

What I ended up doing, to leave the design intact (it's not my
project, and there are no tests, so I don't want to mess with it too
much):

Xxx-Core:
MyClass class>>initializeMe
     ...
     self doPlatformSpecificStuff.
     ...

Xxx-Platform.squeak & Xxx-Platform.pharo:
MyClass class>>initialize
     self initializeMe.

MyClass class >> doPlatformSpecificStuff
    ...

Sean