Sometimes it does inderstand and sometimes it doesn't =:-O

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Sometimes it does inderstand and sometimes it doesn't =:-O

Fernando Rodríguez
Hi,

I'm playing around with an example that comes in 'On to Smalltalk'
that simulates the population growth of rabbits.

I have a class, called RabbitApplication,  that  understands the
following messages:
a) class messages
new
^ super new initialize

new: aRabbitType
^ super new initialize: aRabbitType

b) Instance messages:
tickTo: limit
[rabbits first deliveryMonth <= limit]
whileTrue: [self updateMonth; step].
self printHistory

If I evaluate this on the workspace, everything works as expected:

x := RabbitApplication new: Rabbit.
x tickTo: 4

However, if I try to evaluate this instead:
RabbitApplication new: Rabbit; tickTo: 4.

I get an error, complaining that RabbitApplication doesn't understand
#tickTo:! Of course it does, actually it just did it! =:-O

What am I doing wrong this time? O:-)

Thanks


Reply | Threaded
Open this post in threaded view
|

Re: Sometimes it does inderstand and sometimes it doesn't =:-O

Udo Schneider
Fernando wrote:
> x := RabbitApplication new: Rabbit.
> x tickTo: 4

In this case you define "x" to be the result of "RabbitApplication new:
Rabbit" which is a newly create instance of RabbitApplication. Then you
send x the message "#tickTo:" with the parameter "4".

> However, if I try to evaluate this instead:
> RabbitApplication new: Rabbit; tickTo: 4.

In this case however, you are using cascaded messages. In this case
#tickTo: is sent to the same object as the message before
(RabitApplication) in your case.

This means if we seperate the two message sends you are having something
like:
RabbitApplication new: Rabbit.
RabbitApplication tickTo: 4

To achieve the result you wanted you have to use pharenthesis to tell
the parser that you want to send the message #tickTo: to the result of
the previous expression. One might start with the following:

RabbitApplication new: Rabbit tickTo: 4.

This however won't work because here you are sending a message #new:tickTo.

To solve the issue just wrap up the instance creation in pharenthesis
like this:

(RabbitApplication new: Rabbit) tickTo: 4.

CU,

Udo


Reply | Threaded
Open this post in threaded view
|

Re: Sometimes it does inderstand and sometimes it doesn't =:-O

Fernando Rodríguez
On Sat, 04 Dec 2004 18:30:01 +0100, Udo Schneider
<[hidden email]> wrote:


>To achieve the result you wanted you have to use pharenthesis to tell
>the parser that you want to send the message #tickTo: to the result of
>the previous expression. One might start with the following:
>
>RabbitApplication new: Rabbit tickTo: 4.
>
>This however won't work because here you are sending a message #new:tickTo.
>
>To solve the issue just wrap up the instance creation in pharenthesis
>like this:
>
>(RabbitApplication new: Rabbit) tickTo: 4.

OK, I got it. Thanks! :-)


Reply | Threaded
Open this post in threaded view
|

Re: Sometimes it does inderstand and sometimes it doesn't =:-O

Chris Burkert-2
In reply to this post by Fernando Rodríguez
Fernando wrote:
> x := RabbitApplication new: Rabbit.
> x tickTo: 4
>
> However, if I try to evaluate this instead:
> RabbitApplication new: Rabbit; tickTo: 4.
>
> I get an error, complaining that RabbitApplication doesn't understand
> #tickTo:! Of course it does, actually it just did it! =:-O

No, it does not! Because you send #tickTo: to RabbitApplication, which
is the class and not the instance. You want:

(myRabbitApplication := RabbitApplication new: Rabbit)
        tickTo: 4.

cheers Chris


Reply | Threaded
Open this post in threaded view
|

Re: Sometimes it does inderstand and sometimes it doesn't =:-O

Fernando Rodríguez
On Sat, 04 Dec 2004 19:12:52 +0100, Chris Burkert
<[hidden email]> wrote:

>Fernando wrote:
>> x := RabbitApplication new: Rabbit.
>> x tickTo: 4
>>
>> However, if I try to evaluate this instead:
>> RabbitApplication new: Rabbit; tickTo: 4.
>>
>> I get an error, complaining that RabbitApplication doesn't understand
>> #tickTo:! Of course it does, actually it just did it! =:-O
>
>No, it does not! Because you send #tickTo: to RabbitApplication, which
>is the class and not the instance. You want:
>
>(myRabbitApplication := RabbitApplication new: Rabbit)
> tickTo: 4.

Hhhmmm... OK, I misunderstood what the ; was doing.

Anyway, what I was tring to do was to 'chain' several methods (each
returns self), something like a function composition.

What's the best way to do this? O:-)

Thanks


Reply | Threaded
Open this post in threaded view
|

Re: Sometimes it does inderstand and sometimes it doesn't =:-O

Udo Schneider
Fernando wrote:
> Anyway, what I was tring to do was to 'chain' several methods (each
> returns self), something like a function composition.

object msg1 msg2 msg3 msg4

This is the easiest way. However - if you are using keyword messages,
you might have to use pharenthesis to express the order of messages.

instance + 1 keywordMessage: anArgument unaryMessage.

This would be seen as:

((instance + 1) keywordMessage: (anArgument unaryMessage)).

The general message precedence is
1) unary message (e.g. #size)
2) binary message (e.g. #+, #*)
3) keyword message (e.g. #doSomething:)

Within one class of messages the order is strict left to right. This
might cause some "confusion":

C/C++/C# ... (the curly braces world ;-): 2 + 3 * 4 equals 14
Smalltalk: 2 + 3 * 4 = 20!!!

CU,

Udo