[squeak-dev] Re: [Metacello] Fwd: Metacello questions

Dale Henrichs dale.henrichs at gemstone.com
Tue May 11 21:22:32 UTC 2010


Andreas,

Your 'self answers' all look good.

| 	spec
| 		package:'Foo' with:[spec requires: 'Bar'];
| 		package:'Foo' with:[spec requires: 'Baz'];
| 
| and
| 	spec
| 		package: 'Foo' with:[spec requires: #('Bar' 'Baz')].

are indeed equivalent. So the difference pieces of the spec can be included in different #for:do: blocks based on the platform.

To take you a little bit into the internals...You will notice that all packages/projects/groups are named, so for each spec of a given name an ordered list of modifications are recorded while resolving the spec on a given platform.

  1. all #version: pragmas (no import and therefore self-contained) are processed 
     first
  2. #version:import: pragmas are processed next (using the imported version as a 
     starting point).
  3. within a #version: or #version:import: method, the specs are processed in 
     project attribute order (i.e., for Squeak -> #common, #squeakCommon, #squeak).
  4. the individual statements in the #for:do: for a given attribute are processed 
     in order.
  5. there are 4 unique operations supported:
     - add
     - copy
     - merge
     - remove

Once the initial processing is complete, the operations are collapsed to form the final named spec. The named specs are collected into the version ....

The #add operation is used by the constructors with 'overrides' in their name. The #add operation replaces the named spec.

The #copy operation is used the by the #project:copyFrom:with: constructor. Note that #copy requires that an #add/#merge operation proceeds it in it's list.

The #merge operation merges it's items into the previous version of the named spec. Not that #merge is equivalent to #add if the name spec doesn't exist yet. Most of the constructors use the #merge operation.

The #remove operation is used by the constructors with 'remove' in their name. The #remove operation removes it's from the previous version of the named spec.

So you can imagine that as you traverse through an attribute list for a particular project, that each of the individual constructor statements for a named spec are processed in a very specific order with each of the #add, #copy, #merge, and #remove operations applied in order...

Hope this helps,

Dale

----- "Andreas Raab" <andreas.raab at gmx.de> wrote:

| On 5/6/2010 5:26 PM, Dale Henrichs wrote:
| > I don't think I've completely answered your questions so we might
| want to continue the dialog on this question....
| 
| We're getting close :-) Let me take my own questions and answer them
| in 
| my own words to see if I understand the issues correctly:
| 
| Q1: #includes: vs. #requires:
| 
| If I understand correctly what you're saying then, in heavily
| simplified 
| form, I'd say they're both dependencies, except that #requires: is 
| loaded before the package it relates to and #includes: afterwords.
| Thus:
| 
| 	spec package: 'B' with:[
| 		spec requires: 'A'.
| 		spec includes: 'C'.
| 	].
| 
| will load A, B, and C in that order. One thing one can do with this is
| 
| to have mutually dependent packages, for example if package Foo and
| Bar 
| always must be loaded together (Foo before Bar) one would specify:
| 
| 	spec package: 'Foo' with:[spec includes: 'Bar'].
| 	spec package: 'Bar' with:[spec requires: 'Foo'].
| 
| There is now no way by which Foo or Bar could be loaded without its 
| companion. Correct?
| 
| Q2: Why is HelpSystem not loaded?
| 
| A: That's a bug which I can work around by specifying either #version:
| 
| or #versionString:.
| 
| Q3: When exactly is HelpSystem loaded?
| A: In the context of my configuration HelpSystem is loaded for two 
| reasons: a) because it's a dependency for WebClient-Help and b)
| because 
| no 'default' group has been specified it would be loaded implicitly.
| 
| Q4: How does one define dependencies that differ based on platform?
| A: I'm not really sure about this. My understanding is that I could
| use 
| #includes: to model the dependency in the "for: #pharo" branch, but
| one 
| question that is still open is whether the following two expressions
| are 
| equivalent:
| 
| 	spec
| 		package:'Foo' with:[spec requires: 'Bar'];
| 		package:'Foo' with:[spec requires: 'Baz'];
| 
| and
| 	spec
| 		package: 'Foo' with:[spec requires: #('Bar' 'Baz')].
| 
| Are these equivalent?
| 
| Cheers,
|    - Andreas



More information about the Squeak-dev mailing list