[squeak-dev] The Trunk: Environments-cmm.38.mcz

Chris Muller asqueaker at gmail.com
Sun Dec 22 17:43:37 UTC 2013


So here is another correct example of CPM when more than one variable
needs initialized.

Your home-brew version of CPM does the same thing, but it 1) violates
the rule to say things once and only once, 2) has #initialize getting
called from any of half-a-dozen places rather than the ONE place, 3)
doesn't factor the behavior of simply *constructing* a _well-formed
object_ from the behavior of fully initializing it (i.e.., building up
a large cache).

>> > 1) each class that declares instance variables has exactly one
>> > initialization method
>>
>> Well then you can't have more than one constructor type then.  Not all
>> objects can follow a path down to a single constructor on the
>> class-side that ends up calling #initializeWtih:...
>
> Why not? I've never found this to be an issue.
>
>>
>> In several cases,
>> you'll need #initializeWithThis: and #initializeWithThat:.  And, in
>> both cases, you want to call #initialize from the top of them.  That's
>> repeating yourself and unconventional.
>
> Right. That's why the rule is one initializer.

What is an "initializer?"  Is that an #initialize method or an
#initializeWith... method?  If the former, it makes no sense to say
it's a rule to only have one because that's all you COULD have.  If
the latter, you're contradicting yourself in the above paragraph.

>> > 2) each initialization method must leave the instance in a valid state
>>
>> Of course, as does any initialization method like CPM methods.
>
> Not so. If your class has ivars 'foo' and 'bar' and it needs both of them to
> have values for the object to be valid, then neither #setFoo: nor #setBar:
> leave the object in a valid state. You have to call both of them to get a
> fully-initialized object. But #initializeWithFoo:bar: leaves the object in a
> valid state.

The above makes it very clear you haven't read CPM.

That's why I've committed this change, as second example of CPM
showing it does the same thing, but without repeating itself and
without the other issues associated with the home-brew version.

>> > 3) each initialization method is named verbosely starting with
>> > 'initializeWith' and describes its parameters
>>
>> The ONLY reason you call it "initializeWithThis:that:other:thing:"
>> instead of "setThis:that:other:thing:" is because you want to repeat
>> yourself by calling #initalize at the top of each method.
>
> The reason to call it #initializeWithThis:that: is that it initializes the
> object with this and that. If you like consider this an instance of
> "intention-revealing selector".

But what if I ONLY want a minimally well-formed instance, (e.g.,
minimum number of inst-vars set to make a well-formed instance, but
not, say, 'cache' variables which are derived from the minimum vars --
CPM does the minimum, initializeWith:... implies to build the cache as
well).

>> > 6) there is one or more class-side constructors which send #basicNew and
>> > the
>> > initialization message
>>
>> Why basicNew instead of new?  Honestly, there's no good reason for
>> that and it forces you to repeat yourself in all of your
>> #initializeWith: methods.
>
> Because #new calls #initialize. When following this pattern, #initialize
> still gets called, but by a subclass initializer, not by the constructor. We
> want to avoid calling #initialize twice.

Exactly.  You've articulated one of the problems with your home-brew
CPM.  You're doing this unnecessary dance with calling #basicNew and
#initialize yourself when all you need to say is, simply, #new.
That's a definite regression of CPM.

On Sun, Dec 22, 2013 at 11:23 AM,  <commits at source.squeak.org> wrote:
> Chris Muller uploaded a new version of Environments to project The Trunk:
> http://source.squeak.org/trunk/Environments-cmm.38.mcz
>
> ==================== Summary ====================
>
> Name: Environments-cmm.38
> Author: cmm
> Time: 22 December 2013, 11:23:45.064 am
> UUID: bcae5b17-4e55-4b16-be84-90fc1e283ae4
> Ancestors: Environments-cmm.37
>
> Use proper implementation of Constructor Parameter Method.
>
> =============== Diff against Environments-cmm.37 ===============
>
> Item was changed:
>   ----- Method: EnvironmentInfo class>>name:organization:packages: (in category 'as yet unclassified') -----
>   name: aString organization: aSystemOrganizer packages: aPackageOrganizer
> +       ^ self new
> +               setName: aString
> -       ^ self basicNew
> -               initializeWithName: aString
>                 organization: aSystemOrganizer
>                 packages: aPackageOrganizer!
>
> Item was removed:
> - ----- Method: EnvironmentInfo>>initializeWithName:organization:packages: (in category 'as yet unclassified') -----
> - initializeWithName: aString organization: aSystemOrganizer packages: aPackageOrganizer
> -       self initialize.
> -       name := aString.
> -       organization := aSystemOrganizer.
> -       packages := aPackageOrganizer.
> -       !
>
> Item was changed:
> + ----- Method: EnvironmentInfo>>name (in category 'access') -----
> - ----- Method: EnvironmentInfo>>name (in category 'as yet unclassified') -----
>   name
>         ^ name!
>
> Item was changed:
> + ----- Method: EnvironmentInfo>>organization (in category 'access') -----
> - ----- Method: EnvironmentInfo>>organization (in category 'as yet unclassified') -----
>   organization
>         ^ organization!
>
> Item was changed:
> + ----- Method: EnvironmentInfo>>packages (in category 'access') -----
> - ----- Method: EnvironmentInfo>>packages (in category 'as yet unclassified') -----
>   packages
>         ^ packages!
>
> Item was changed:
> + ----- Method: EnvironmentInfo>>printOn: (in category 'printing') -----
> - ----- Method: EnvironmentInfo>>printOn: (in category 'as yet unclassified') -----
>   printOn: aStream
>         aStream nextPutAll: name.
>         aStream nextPutAll: 'Info'!
>
> Item was added:
> + ----- Method: EnvironmentInfo>>setName:organization:packages: (in category 'initialize-release') -----
> + setName: aString organization: aSystemOrganizer packages: aPackageOrganizer
> +       name := aString.
> +       organization := aSystemOrganizer.
> +       packages := aPackageOrganizer!
>
>


More information about the Squeak-dev mailing list