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

Tom Rushworth tom.b.rushworth at gmail.com
Mon Dec 23 22:13:58 UTC 2013


On 13-12-23 13:13 , Colin Putney wrote:
> On Mon, Dec 23, 2013 at 3:34 PM, Chris Muller <ma.chris.m at gmail.com> wrote:
> 
> 
>> The reason I asked 'why' though was simply that 'Single', while maybe
>> the 95% case, is not the case 100% of the time, so I think it's a
>> misnomer for the name of your pattern.
>>
>> You'd need more than one initializer whenever there's more than one
>> way to create an object.  Consider a NetworkLocation class -- which
>> might be created with an IP OR a hostname.  Whichever is specified,
>> the other could be derived but doesn't really need to be.  Therefore,
>> you don't need to cram it all through one single initializer that
>> parameterizes both.  You need two:  initializeWithHostname:port: and
>> initializeWithIpString:port:.
> 
> 
> No. Again, the whole point of the pattern is to have just one initializer
> per class.

I understood the pattern (coming from an Objective-C developer
viewpoint) not so much as having _one_, as having one _designated_
intiailizer that handles the most general case, dealing with all the
instance vars, any consistency issues, internal state etc.  It's fine to
have other initializers for special cases, but they must call the
designated one.

To use Point as a probably too simple example, the designated
initializer would be something like the existing:

   Point class>>x:y:

and then you might have another initializer something like

   Point class>>initAtIntersectionOf: line1 with: line2

but that method must call x:y:.  The pattern is that you have as many
initializers as makes sense, but they all end up calling the designated
one.  Some of the initializers may just supply default values, some may
do conversions from other objects, whatever makes sense for the problem
at hand.

Since Objective-C was starting fresh and didn't have an image to give
history so much weight :), they got to adopt a convention that all such
methods started with "init", and the methods corresponding to "new"
started with "alloc".  I think alloc and init make the roles clearer,
but that's the benefit of hindsight :).

 If you have more than one, you're defeating the purpose. For
> NetworkLocation, presumably you have just one variant stored internally.
> Let's say it's the IP address. In that case, you'd have one initializer,
> #initializeWithAddress:port: and two constructors, #newWithIpString:port:
> and #newWithHostname:port:. The constructors would be responsible for
> converting their parameters into the right form to pass to the initializer.
> 
> In the example I posted, Square uses this technique.
> 
> 
>> So you think Point class>>x:y: should be #newWithX:y:?
>>
> 
> No, because Point has been around forever, and changing it would create
> pointless *cough* breakage.
> 
> 
>> That is just not how most Smalltalk code is written.  I believe there
>> is value to having unity with the rest of Smalltalk standards and
>> conventions.
>>
> 
> Yeah, but Smalltalk doesn't really have a strong convention for constructor
> names. You see all sorts of conventions in the image and packages. But that
> was just an interesting idea that occurred to me. Ignore it if you don't
> like it.
> 
> What's important about that passage was the bit about constructors. Your
> instinct to call the superclass constructor is spot on, but it should be
> done on the instance side. So instead of #newWithPrefix: calling #new,
> #initializeWithPrefix: calls #initialize.
> 
> Colin
> 
> 
> 
> 


-- 
Tom Rushworth


More information about the Squeak-dev mailing list