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

Chris Muller ma.chris.m at gmail.com
Mon Dec 23 20:34:26 UTC 2013


>> >> Your home-brew version of CPM does the same thing,
>> >
>> >
>> > If you need a name for it, let's call it the "Single Initializer"
>> > pattern.
>>
>> Why, it has the same number of "initializers" as CPM.  #initialize
>> (for default values) and #initializeWith:... for constructor
>> parameters.
>
> Because I find "your home-brew version of CPM" insulting. "Single

Insults are totally unproductive, I should have been more sensitive
with my words.  Apologies.

> Initializer" conveys the intent of the pattern pretty well, I think.

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:.

>> You have "self initialize" in all of your #initializeWith:... because
>> you chose to call #basicNew instead of #new.  It's a throwback to
>> 2002.
>
> Ah. Well, I'm not bothered by a single message send appearing in more than
> one place.
>
> Think of #new as a 0-parameter constructor. It sends #basicNew to get an
> instance, then sends #initialize to initialize its state.
>
> Now consider the #prefix: constructor that you changed in
> AddPrefixNamePolicy. It's a 1-parameter constructor, which follows exactly
> the same pattern as #new, extended to take a parameter: it creates an
> instance with #basicNew, then sends #initializeWithPrefix: to set up the
> instance's state. EnvironmentInfo class>>name:organization:packages: also
> follows the pattern. It accepts 3 parameters, creates an instance with
> #basicNew and passes the parameters to the initializer.
>
> Because Smalltalk has keyword messages, we can't include general
> parameterized constructors in the base image, because they wouldn't have
> descriptive names. They'd be called something like #newWith: and
> #newWith:with:with:. It's better to let people define their own
> constructors.
>
> That gives me an idea, though. Instead of #prefix: and
> #name:organization:packages:, these constructors should be called
> #newWithPrefix: and #newWithName:organization:packages:. That would be
> clearer because it mirrors the structure of the initialization messages.

So you think Point class>>x:y: should be #newWithX:y:?

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.

Wow, who'd've ever thought *I* would be arguing for "aesthetics!"  :)

> See, this debate is useful after all.

It's a disaster.  :)

>>  >> 2) has #initialize getting
>> >> called from any of half-a-dozen places rather than the ONE place
>> >
>> > So? Sending a single message in more than one place is fine. It's what
>> > messages are for.
>>
>> When you're duplicating the same code over and over again ("self
>> initialize") in all your subclasses, that should be a clue that you
>> should inherit that behavior from the superclass instead of repeating
>> yourself.
>>
>> That's the standard followed by the rest of the image.
>
>
> It looks like this is the crux of our disagreement. My response above
> applies here too.
>
>>
>> >> 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).
>> >
>> > What are you talking about? None of the classes you've "cleaned up" has
>> > a
>> > cache.
>>
>> The CPM pattern covers general case, not just your classes.
>
>
> Ok, then what makes you think that Single Initializer can't deal with caches
> well? If you have a case where you need to populate a cache separately from
> initializing the object to *have* a cache, well, then write your initializer
> that way.
>
>>
>> Let's move on because I have more important, _design-level_ criticisms
>> of Environments to discuss.
>
>
> Sure, criticize away, I'm happy to discuss. But as long as you're committing
> your "clean ups" to the trunk, I don't want to just drop this.

I was going to propose a compromise where I would give up my "set"
nomenclature which I strongly prefer and use your "initializeWith:" if
you would allow the "no-argument constructor" #new to be the one to
call #initialize, rather than from every #initializeWith: method.

But please feel free to do whatever you want.  Next time, I'll try
harder not to feel insulted myself, because I really do like y'all and
want us to be productive.

 - Chris


More information about the Squeak-dev mailing list