[Newbies] About methods and parameters

Bert Freudenberg bert at freudenbergs.de
Wed Dec 3 12:02:11 UTC 2008

On 03.12.2008, at 10:23, Delyan Kalchev wrote:

> I have several questions:

Hi! Welcome to a truly object-oriented system, where you might be in  
for some surprises :)

> 1. As I see parameter passing in Smalltalk is always
> call-by-reference, so within a method it is possible to do any
> "destructive" actions over the passed object. Is there a way to
> pass/accept a parameter as "const" so that it won't be changed in the
> method.

In Squeak, nothing can change an object except the object itself. All  
that you can do from the outside is to send messages to the the  
object, which it can choose to react on or not.

So design your objects carefully.

> 2. When we pass an object to a method, it can do anything with it, but
> is there a way to pass a variabe by reference and do change the passed
> variable. For example:
> i := 5.
> MyObj method: i.
> How can i be 6 after the method call.

When written like this, it cannot.

Do you have a specific use case? I can't remember I ever needed this.

> 3. Is there a way to pass a method as a parameter to another method.

That would be a "block" which is pretty much an anonymous method  
written in-line:

   sortBlock := [:a :b | a sortsBefore: b].
   myArray sortedBy: sortBlock.

Everything in square brackets creates a "block" object, you can put  
any code inside it which is not evaluated immediately but later, for  
example inside the sortedBy: method:

   sortedBy: aBlock
     | x y |
     (aBlock value: x value: y)
       ifTrue: [...]
       ifFalse: [...]

Normally you would not use a variable to hold the block, I just wrote  
it that way to make the meaning more obvious. So usually you'ld write

   myArray sortedBy: [:a :b | a sortsBefore: b].

Another, less flexible way is to just pass a method name (which we  
call a "selector"):

   myArray sortedUsing: #sortsBefore:

which then needs to be "performed":

   sortedUsing: aSelector
     | x y |
     (x perform: aSelector with: y)
       ifTrue: [...]
       ifFalse: [...]

And just to wrap that up, "passing a method" would literally be  
possible, too, since methods are of course objects on their own, but  
that's not what you meant.

- Bert -

More information about the Beginners mailing list