Difference between Model and Spec

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

Difference between Model and Spec

Jan Vrany
Hi,

in Metacello core there are two sort of classes (beside others) -
Models (MetacelloProject, MetacelloVersion, MetacelloMCProject,
MetacelloMCVersion,...) and corresponding specs (MetacelloProjectSpec,
MetacelloVersionSpec, MetacelloMCProjectSpec, MetacelloMCVersionSpec,...)

What is the difference and purpose?

Initially I thought that *Spec instances are created from the version
spec methods, all includes/tweaks/references
are then somehow resolved and the model is created so once I have an
instance of MetacelloMCProject, for instance, all data are there and I
can do the fetch/load  or whatever.

However, I haven't found any MetacelloMCPackage (while there is
a MetacelloMCPackageSpec), same for MetacelloMCRepository.

Is there any document describing Metacello internals?

Best, Jan
Reply | Threaded
Open this post in threaded view
|

Re: Difference between Model and Spec

Dale Henrichs
Jan,

There is no internals documentation for Metacello .... Noone else has expressed a strong interest in learning the internals before:)

I'll give a brief overview here and then we can get into more detail depending upon what area(s) you want to concentrate on ...

MetacelloProject (and MetacelloMCProject) is a container object whose primary responsibility is providing access to versions. Internally, the MetacelloProject does supply the specific spec classes to be used.

MetacelloVersion (and MetacelloMCVersion) are also containers. They present the public version api and hide the internal version spec details.

The *Spec classes are where all of the real work is done.

If you are working with the internals of Metacello probably the most important thing for you to understand is how the specs are composed and we'll start by looking at the composition of a package spec. In a standard configuration you a have a packageSpec created in the baseline:

baseline: spec
  <baseline: '1.0-baseline'>

  spec for: #common with: [
    spec blessing: #baseline.
    spec package: 'MyPackage'].

and another in the version:

version: spec
  <version: '1.0' imports: #('1.0-baseline')>

  spec for: #common with: [
    spec blessing: #release.
    spec package: 'MyPackage' with: 'MyPackage-dkh.1'].

If you inspect the spec for the baseline:

  (ConfigurationOfMyProject project version: '1.0-baseline')
    inspect

take a look at the packageList instance variable. In the MetacelloPackagesSpec, you'll want to look at the list and memberMap instance variables. The list is a simple collection of the specs encountered in order in the baseline definition ("in order" is somewhat complicated, but we'll worry about that later). At this point it is probably useful to know that you can list a package multiple times in a spec method:


baseline: spec
  <baseline: '2.0-baseline'>

  spec for: #common with: [
    spec blessing: #baseline.
    spec
      package: 'AnotherPackage';
      package: 'MyPackage';
      package: 'MyPackage' with: [spec requires: 'AnotherPackage']].

Inspecting the list instance variable (spec .. packageList) for the this version you will notice that there are three MetacelloMCPackageSpec instances listed. Now look at the memberMap. You should see only two entries for 'AnotherPackage' and 'MyPackage'. The instance in the memberMap is the composed package spec and represents what you probably think of as the MetacelloPackage for this version.

The composition of the package depends upon which project attributes that are active for the image and the imports list ... so if you look at the version spec for the following version:

version: spec
  <version: '2.0' imports: #('2.0-baseline')>

  spec for: #common with: [
    spec blessing: #release.
    spec
      package: 'AnotherPackage' with: 'AnotherPackage-dkh.1';
      package: 'MyPackage' with: 'MyPackage-dkh.1'. ].

and look at the packageList list and memberMaps you should start getting a feel for what's going on ...

The cornerstone operation for transforming the list into the memberMap is the #mergeSpec: method which is called during the MetacelloPackagesSpec #map operation.

The test cases in the MetacelloSpecTestCase family explicitly exercises the package, project and group composition operations.

If you getting inside of Metacello, I think that it is critical that you understand how specs are composed and recognize the difference between the specs in the #list and the #memberMap...

BTW, If you build some sample classes, it is probably worth creating an internals/packages directory and we should probably copy this email exchange into some .md files to form the basis of the internals documentation ...

Dale

----- Original Message -----
| From: "Jan Vrany" <[hidden email]>
| To: [hidden email]
| Sent: Thursday, October 4, 2012 2:02:23 AM
| Subject: [Metacello] Difference between Model and Spec
|
| Hi,
|
| in Metacello core there are two sort of classes (beside others) -
| Models (MetacelloProject, MetacelloVersion, MetacelloMCProject,
| MetacelloMCVersion,...) and corresponding specs
| (MetacelloProjectSpec,
| MetacelloVersionSpec, MetacelloMCProjectSpec,
| MetacelloMCVersionSpec,...)
|
| What is the difference and purpose?
|
| Initially I thought that *Spec instances are created from the version
| spec methods, all includes/tweaks/references
| are then somehow resolved and the model is created so once I have an
| instance of MetacelloMCProject, for instance, all data are there and
| I
| can do the fetch/load  or whatever.
|
| However, I haven't found any MetacelloMCPackage (while there is
| a MetacelloMCPackageSpec), same for MetacelloMCRepository.
|
| Is there any document describing Metacello internals?
|
| Best, Jan
|