Behavior New Behavior BasicNew Behavior New: Behavior BasicNew:
First, they are "new", "basicNew", etc. Capitalization is important.
Most programmers will never use basicNew and basicNew:. new is used for a normal class, while new: is used for a collection or some other class with an indexible part. Array new: 10 returns an array of length 10. OrderedCollection new: 10 returns an OrderedCollection of length 0 but with space for 10 elements without growing. In general, new returns an object with every variable initialized to nil, unless you redefine it, such as to initialize variables. Only a few classes redefine new, but it *does* get redefined, and that is why basicNew was defined. Stream redefines new to generate an error message. This prevents people from getting an undefined Stream. A subclass might define a new class method "on:" to create instances. This method will have to call "new", but "new" was redefined by its subclass. So, how can it call "new"? The secret is that Behavior defines basicNew to be the same as new, and you are never supposed to redefine basicNew (or any other methods with basic as a prefix). So, if you need to call the original version of "new", and "new" is redefined, call basicNew instead.
-Ralph Johnson
Ralph Johnson wrote:
Behavior New Behavior BasicNew Behavior New: Behavior BasicNew:
First, they are "new", "basicNew", etc. Capitalization is important.
Oops! I knew that. That is what happens to me when I stay up programming rather than going to bed at a reasonable time.
Most programmers will never use basicNew and basicNew:. new is used
The reason that I asked the question is found in the Form class methods extent:depth and extent:depth:bits. They use basicNew rather than new, and I couldn't figure out why.
Form class inherits new and basicNew from Behavior, so it seems like it would be more appropriate for the methods to use new rather than basic new.
for a normal class, while new: is used for a collection or some other class with an indexible part. Array new: 10 returns an array of length 10. OrderedCollection new: 10 returns an OrderedCollection of length 0 but with space for 10 elements without growing. In general, new returns an object with every variable initialized to nil, unless you redefine it, such as to initialize variables. Only a few classes redefine new,
In my Squeak 2.3b image (virgin), there are 77 implementors of new and 13 implementors of new:
They are used for a variety reasons and coded in a variety of styles. The analysis of which is left as an excercise for the student.
but it *does* get redefined, and that is why basicNew was defined. Stream redefines new to generate an error message. This prevents people from getting an undefined Stream. A subclass might define a new class method "on:" to create instances. This method will have to call "new", but "new" was redefined by its subclass. So, how can it call "new"? The secret is that Behavior defines basicNew to be the same as new, and you are never supposed to redefine basicNew (or any other methods with basic as a prefix). So, if you need to call the original version of "new", and "new" is redefined, call basicNew instead.
-Ralph Johnson
Thanks for your comments,
John-Reed Maffeo
John-Reed Maffeo wrote:
Most programmers will never use basicNew and basicNew:. new is used
The reason that I asked the question is found in the Form class methods extent:depth and extent:depth:bits. They use basicNew rather than new, and I couldn't figure out why.
Form class inherits new and basicNew from Behavior, so it seems like it would be more appropriate for the methods to use new rather than basic new.
Looking at superclasses is not enough. The Cursor class, which subclasses from Form has overwritten new. From here things get interesting...
Cursor class>>new calls self extent:fromArray:offset: which it has also overridden.
Cursor class>>extent:fromArray:offset: calls super extent:fromArray:offset: which would get picked up in Form.
Form class>>extent:fromArray:offset: calls (among other things) self extent:depth:
#extent:depth: is not defined on Cursor class so the method in Form would get used (incidently you would have to check every intermediate superclass between Cursor and Form if there were any).
Form class>>extent:depth: calls self basicNew.
If it were to call #new (instead of basicNew) you would be right back up at Cursor class>>new which would loop of course.
That's one of the trip points to refactoring and simplification. You need to look up and down the hierarchy.
This might seem a bit confusing and we can probably (amongst all the mail list readers) come up with a clearer example if this doesn't make sense to you.
have fun...
- Steve
Steve,
Thanks for the concise explanation.
Stephan B. Wessels wrote:
--- snip
Form class>>extent:depth: calls self basicNew.
If it were to call #new (instead of basicNew) you would be right back up at Cursor class>>new which would loop of course.
That's one of the trip points to refactoring and simplification. You need to look up and down the hierarchy.
Is this situation one to which refactoring and simplicication should be applied?
This might seem a bit confusing and we can probably (amongst all the mail list readers) come up with a clearer example if this doesn't make sense to you.
have fun...
Fun is exactly what I am having;)
- Steve
squeak-dev@lists.squeakfoundation.org