Hello

sourcery squeak-dev.sourcery at forum-mail.net
Sun May 18 01:49:47 UTC 2003


On Sun, 18 May 2003 00:27:41 +0100, Dominic Fox <dominic.fox1 at ntlworld.com> 
wrote:

> * If I want to expose an instance's private fields, do I have to code 
> accessor methods every time? Is there an alternative to writing
>
> getFoo
> 	^ foo
>
> and
>
> setFoo: newFoo
> 	foo := newFoo
>
> over and over again?

You can write code that generates the accessor and generator methods.  You 
can
add such code to the Browser, and provide menu options that run the code 
for
any selected set of instance variables.

An example of the necessary code:

| names |
names := MyClass instVarNames.
1 to: names size do: [:index |
	| name capitalizedName |
	name := localNames at: index.
	capitalizedName := name withFirstCharCapitalized.
	MyClass 		compile: 'set', capitalizedName, ': a', capitalizedName, '
				', name, ' := a', capitalizedName
		classified: #accessing]

Also, you can use the #instVarAt: and #instVarAt:put: primitives:

'Hello' asText instVarAt: 1 "Evaluates to the String contained in the 
'string' instance variable of a Text."

> * Is the best way to make what in C++ or Java you'd call "constructors" 
> to write class methods that create, initialize and then return an 
> instance, e.g.
>
> newFooWithBar: initialBar
> 	| newFoo |
> 	newFoo := Foo new; setBar: initialBar.
> 	^ newFoo
>
> or is there a more concise way?

Class methods are the way to go, unless one also wants to use the Strategy
pattern to dynamically vary how instances get initialized--in which case
explicit "factory" objects might be called for.

A note on the syntax in your example: 'Foo new; setBar: initialBar' does 
not
do what you think it does.  It results in sending the message #setBar: to
the class Foo, not to the instance you've created in the previous message
send.  To code what you intended, use one of the following:

	1: self basicNew setBar: initialBar "use when #setBar: is fully 
responsible for initializing the instance"
	2: self new setBar: initialBar 	"use when #setBar: is NOT fully 
responsible for initializing the instance"

Usually, the #new class method answers an initialized instance.  It should 
be coded in
an abstract superclass (so that all the subclasses inherit it) as follows:

new
	^self basicNew initialize

By convention, the method #basicNew always answers a new but uninitialized 
object. Using #basicNew therefore guarantees that a) there won't be any 
unexpected
recursion in the class methods that participate in constructing initialized
instances, and b) there won't be any unecessary duplication of work, or
creation of throw-away objects, during the initialization process.

> * Can I treat blocks as first-class entities, e.g. return them from 
> methods, pass them around etc? Can I use them to implement LISP-like 
> closures? Even if I can, is this a "natural" smalltalky way to do things?

Yes, in most Smalltalk implementations.  Unfortunately, Squeak does not yet
fully support blocks as closures.  Blocks as full closures were first 
implemented
in Smalltalk in the 80's by a company known as ParcPlace.  A version of
Smalltalk descended from ParcPlace's implementation is still available as 
the VisualWorks product form Cincom.  Both Squeak and VisualWorks are 
direct
descendents of the original ST-80 described in the "Blue Book."

> * What about function/method pointers? Can I treat one of an instance's 
> methods as a block, or do I have to make a new block and call the method 
> inside that?

The latter.  And it is relatively trivial to create classes with Block-like
APIs that internally invoke some method with some object as the receiver.
See, for example, Object>perform:, Object>perform:with: and 
Object>withArguments:

> Finally,
>
> * Is this list a good place to ask questions like this? If it isn't, is 
> there a more suitable one?

This list is one place to ask such questions.  Another option would be the
newsgroup comp.lang.smalltalk.





-- 
The Stupid Party thinks everyone else is evil.  The Evil Party thinks 
everyone else is stupid.



More information about the Squeak-dev mailing list