[Seaside-dev] basicNew

Julian Fitzell jfitzell at gmail.com
Sun Oct 5 10:12:13 UTC 2008


On Mon, Sep 29, 2008 at 10:20 PM, Avi Bryant <avi at dabbledb.com> wrote:
> On Mon, Sep 29, 2008 at 12:59 PM, Randal L. Schwartz
> <merlyn at stonehenge.com> wrote:
>>>>>>> "Avi" == Avi Bryant <avi at dabbledb.com> writes:
>>
>> Avi> Assuming no other changes to my code, this means that super's
>> Avi> initialize is not called when you use the #x:y: or #point: class side
>> Avi> creation methods, but *only* when you use a bare #new.
>>
>> Well, that's why you don't call basicNew unless you really mean it.
>>
>> The problem is that you need to decide if you're doing it the Squeak
>> way or not.
>>
>> What I described in my earlier post is the Squeak way, and the way
>> I learned looking at the Smalltalk image in 1981.  If you want to
>> do it the Objective C way, be prepared for some incompatibility.
>
> Ok, I'm still looking for a *complete* example of the "Squeak way",
> and none of your posts so far provide one, so let me set up a straw
> man and you can tell me where it's wrong.
>
> WAPoint class>>x: xNumber y: yNumber
>  ^ self new x: aNumber y: aNumber
>
> WAPoint>>x: aNumber y: yNumber
>   x := aNumber.
>   y := aNumber
>
> WAPoint>>initialize
>  super initialize.
>  self x: 0 y: 0
>
> The only interesting/contentious part of this, I think, is the very
> last line, where #x:y: is sent from the overridden #initialize method.
>  I believe you have to include it, because if you don't, then sending
> "WAPoint new" ends up with an uninitialized instance (nil for x and
> y).  If you do include it, however, you end up performing the
> initialization twice - this is not a big deal when all you're doing is
> assigning some instance variables, but you can certainly imagine cases
> where doubly initializing an instance would be costly or incorrect.
> That's why I don't like this approach, but if I've misunderstood it,
> let me know.

That's not the only possible problem. What if you are another level
down and want to call your superclass's parameterized initialization
method with your own values? Do you have to do this in the class-side
methods?

Also, I'm not certain that you need to be able to call #new on a
WAPoint, do you? If your object has initialization that needs to be
done and someone tries to create an instance that bypasses that
initialization, why would you expect it to work? There may not be sane
defaults...

> Here's the alternative I'm proposing again, for reference:
>
> WAPoint class>>x: xNumber y: yNumber
>  ^ self basicNew x: aNumber y: aNumber
>
> WAPoint>>x: aNumber y: yNumber
>   super initialize.
>   x := aNumber.
>   y := aNumber
>
> WAPoint>>initialize
>  self x: 0 y: 0
>
> This way, whether you use #x:y: or #new, you end up initializing the
> instance exactly once - and I'm still unclear on what the concrete
> disadvantages are.

I do think calling "super initialize" from #x:y: is a little wonky.
I've always done something like:

WAPoint class>>x: xNumber y: yNumber
  ^ self basicNew initializeWithX: xNumber y: yNumber; yourself

WAPoint>>initializeWithX: xNumber y: yNumber
  self initialize.
  x := xNumber.
  y := yNumber.

If you really want #new to work and there are reasonable defaults, then add:

WAPoint class>>new
  ^ self x: 0 y: 0

Is there a problem with this approach that I'm missing?

Julian


More information about the seaside-dev mailing list