<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">2013/12/23 Levente Uzonyi <span dir="ltr">&lt;<a href="mailto:leves@elte.hu" target="_blank">leves@elte.hu</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Sun, 22 Dec 2013, Chris Muller wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So here is another correct example of CPM when more than one variable<br>
needs initialized.<br>
<br>
Your home-brew version of CPM does the same thing, but it 1) violates<br>
the rule to say things once and only once, 2) has #initialize getting<br>
called from any of half-a-dozen places rather than the ONE place, 3)<br>
doesn&#39;t factor the behavior of simply *constructing* a _well-formed<br>
object_ from the behavior of fully initializing it (i.e.., building up<br>
a large cache).<br>
</blockquote>
<br></div>
If you follow this pattern, then #initialize will become a lie, because it&#39;s not initializing anything. You do the actual initialization in the #set* methods.<br>
Also your third point applies to this CPM method (or what) too, because #new will not create a _well-formed object_, the #set* methods will do that. (Yes, there are cases when an object without being initialized _with a parameter_ is not a well-formed object).<br>

<br>
You&#39;re thinking more into #initialize than what it actually is. It&#39;s nothing more than a hook, which is usually called when an object is created, but there are no guarantees. I may override #new whenever I want, or I might call #basicNew. I&#39;m sure there are plenty of classes in the current Trunk, which don&#39;t use #initialize at all.<span class="HOEnZb"><font color="#888888"><br>

<br></font></span></blockquote><div><br></div><div></div><div>An example is Point. Point x: 4 y: 5 will send basicNew, not new.<br></div><div>Point does not define an initialize method. Well it could initialize x:=y:=0; but it doesn&#39;t.<br>
</div><div>Indeed, why would a point initialize x:=y:=0 to immediately change the values?<br>Initializing twice would just be a useless slowdown and is considered as an anti-pattern.</div><div>So Chris, please let us the freedom to not use set, and let instances be initialized by a single method, not a useless two phases (new-&gt;initialize)setThis:andThat:<br>
</div><div><br></div><div>Nicolas<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888">
<br>
Levente<br>
</font></span><br>
P.S.: AFAIK #initialize is a &quot;new concept&quot;, which was not part of ST-80.<br>
P.P.S.: Just because someone (Kent Beck in this case) is doing something differently than you, it doesn&#39;t mean it&#39;s better than what you do.<br>
P.P.P.S.: Most Smalltalkers dislike the #set* methods for some reason.<div class="HOEnZb"><div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

1) each class that declares instance variables has exactly one<br>
initialization method<br>
</blockquote>
<br>
Well then you can&#39;t have more than one constructor type then.  Not all<br>
objects can follow a path down to a single constructor on the<br>
class-side that ends up calling #initializeWtih:...<br>
</blockquote>
<br>
Why not? I&#39;ve never found this to be an issue.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
In several cases,<br>
you&#39;ll need #initializeWithThis: and #initializeWithThat:.  And, in<br>
both cases, you want to call #initialize from the top of them.  That&#39;s<br>
repeating yourself and unconventional.<br>
</blockquote>
<br>
Right. That&#39;s why the rule is one initializer.<br>
</blockquote>
<br>
What is an &quot;initializer?&quot;  Is that an #initialize method or an<br>
#initializeWith... method?  If the former, it makes no sense to say<br>
it&#39;s a rule to only have one because that&#39;s all you COULD have.  If<br>
the latter, you&#39;re contradicting yourself in the above paragraph.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

2) each initialization method must leave the instance in a valid state<br>
</blockquote>
<br>
Of course, as does any initialization method like CPM methods.<br>
</blockquote>
<br>
Not so. If your class has ivars &#39;foo&#39; and &#39;bar&#39; and it needs both of them to<br>
have values for the object to be valid, then neither #setFoo: nor #setBar:<br>
leave the object in a valid state. You have to call both of them to get a<br>
fully-initialized object. But #initializeWithFoo:bar: leaves the object in a<br>
valid state.<br>
</blockquote>
<br>
The above makes it very clear you haven&#39;t read CPM.<br>
<br>
That&#39;s why I&#39;ve committed this change, as second example of CPM<br>
showing it does the same thing, but without repeating itself and<br>
without the other issues associated with the home-brew version.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

3) each initialization method is named verbosely starting with<br>
&#39;initializeWith&#39; and describes its parameters<br>
</blockquote>
<br>
The ONLY reason you call it &quot;initializeWithThis:that:<u></u>other:thing:&quot;<br>
instead of &quot;setThis:that:other:thing:&quot; is because you want to repeat<br>
yourself by calling #initalize at the top of each method.<br>
</blockquote>
<br>
The reason to call it #initializeWithThis:that: is that it initializes the<br>
object with this and that. If you like consider this an instance of<br>
&quot;intention-revealing selector&quot;.<br>
</blockquote>
<br>
But what if I ONLY want a minimally well-formed instance, (e.g.,<br>
minimum number of inst-vars set to make a well-formed instance, but<br>
not, say, &#39;cache&#39; variables which are derived from the minimum vars --<br>
CPM does the minimum, initializeWith:... implies to build the cache as<br>
well).<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

6) there is one or more class-side constructors which send #basicNew and<br>
the<br>
initialization message<br>
</blockquote>
<br>
Why basicNew instead of new?  Honestly, there&#39;s no good reason for<br>
that and it forces you to repeat yourself in all of your<br>
#initializeWith: methods.<br>
</blockquote>
<br>
Because #new calls #initialize. When following this pattern, #initialize<br>
still gets called, but by a subclass initializer, not by the constructor. We<br>
want to avoid calling #initialize twice.<br>
</blockquote>
<br>
Exactly.  You&#39;ve articulated one of the problems with your home-brew<br>
CPM.  You&#39;re doing this unnecessary dance with calling #basicNew and<br>
#initialize yourself when all you need to say is, simply, #new.<br>
That&#39;s a definite regression of CPM.<br>
<br>
On Sun, Dec 22, 2013 at 11:23 AM,  &lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt; wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Chris Muller uploaded a new version of Environments to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Environments-cmm.38.mcz" target="_blank">http://source.squeak.org/<u></u>trunk/Environments-cmm.38.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Environments-cmm.38<br>
Author: cmm<br>
Time: 22 December 2013, 11:23:45.064 am<br>
UUID: bcae5b17-4e55-4b16-be84-<u></u>90fc1e283ae4<br>
Ancestors: Environments-cmm.37<br>
<br>
Use proper implementation of Constructor Parameter Method.<br>
<br>
=============== Diff against Environments-cmm.37 ===============<br>
<br>
Item was changed:<br>
  ----- Method: EnvironmentInfo class&gt;&gt;name:organization:<u></u>packages: (in category &#39;as yet unclassified&#39;) -----<br>
  name: aString organization: aSystemOrganizer packages: aPackageOrganizer<br>
+       ^ self new<br>
+               setName: aString<br>
-       ^ self basicNew<br>
-               initializeWithName: aString<br>
                organization: aSystemOrganizer<br>
                packages: aPackageOrganizer!<br>
<br>
Item was removed:<br>
- ----- Method: EnvironmentInfo&gt;&gt;<u></u>initializeWithName:<u></u>organization:packages: (in category &#39;as yet unclassified&#39;) -----<br>
- initializeWithName: aString organization: aSystemOrganizer packages: aPackageOrganizer<br>
-       self initialize.<br>
-       name := aString.<br>
-       organization := aSystemOrganizer.<br>
-       packages := aPackageOrganizer.<br>
-       !<br>
<br>
Item was changed:<br>
+ ----- Method: EnvironmentInfo&gt;&gt;name (in category &#39;access&#39;) -----<br>
- ----- Method: EnvironmentInfo&gt;&gt;name (in category &#39;as yet unclassified&#39;) -----<br>
  name<br>
        ^ name!<br>
<br>
Item was changed:<br>
+ ----- Method: EnvironmentInfo&gt;&gt;organization (in category &#39;access&#39;) -----<br>
- ----- Method: EnvironmentInfo&gt;&gt;organization (in category &#39;as yet unclassified&#39;) -----<br>
  organization<br>
        ^ organization!<br>
<br>
Item was changed:<br>
+ ----- Method: EnvironmentInfo&gt;&gt;packages (in category &#39;access&#39;) -----<br>
- ----- Method: EnvironmentInfo&gt;&gt;packages (in category &#39;as yet unclassified&#39;) -----<br>
  packages<br>
        ^ packages!<br>
<br>
Item was changed:<br>
+ ----- Method: EnvironmentInfo&gt;&gt;printOn: (in category &#39;printing&#39;) -----<br>
- ----- Method: EnvironmentInfo&gt;&gt;printOn: (in category &#39;as yet unclassified&#39;) -----<br>
  printOn: aStream<br>
        aStream nextPutAll: name.<br>
        aStream nextPutAll: &#39;Info&#39;!<br>
<br>
Item was added:<br>
+ ----- Method: EnvironmentInfo&gt;&gt;setName:<u></u>organization:packages: (in category &#39;initialize-release&#39;) -----<br>
+ setName: aString organization: aSystemOrganizer packages: aPackageOrganizer<br>
+       name := aString.<br>
+       organization := aSystemOrganizer.<br>
+       packages := aPackageOrganizer!<br>
<br>
<br>
</blockquote>
<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div></div>