Trouble with symbols

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

Trouble with symbols

Fernando Rodríguez
Hi,

Assume I have a class Person with methods #firstname and #lastname that
I want to put into a SortedBlock.

I want to create a generic sortBlock so I can sort either by #firstname
or by #lastname.

This code (see me previous 'Currying blocks' post) works:

curry := [:query| [:a :b| (a perform: query ) < (b perform: query )]].

curry2 := [:query| [:a :b| (a query asSymbol) < (b query asSymbol)].]

coll := SortedCollection sortBlock: (curry value: #lastname).
or
coll := SortedCollecton sortBlock: (curry2 value: #firstname).

However, if I change te definition of the curryed block to:
curry3 := [:query| [:a :b| (a query ) < (b query )]]

It won't work and when I try to add something to the collection, I get
a DNU error, complaning that Person doesnt understand 'query'.

Why do I have to send the message #asSymbol (see curry2)? After all,
I'm already sending a symbol when I evaluate curry2 value: #firstname.

I think I'm missing something about symbols, but I'm not sure what.

PS I'm using Dolphin 5.1


Reply | Threaded
Open this post in threaded view
|

Re: Trouble with symbols

Volker Zink
There are some problems with your code. I try to point these problems
later on. First i want to know, why you don't use code like following:

sortAspect := #firstname.
coll := SortedCollection sortBlock: [:a :b | (a perform: sortAspect) <
(b perform: sortAspect)].

Should be much simpler. Now to your code:

Fernando wrote:

> Hi,
>
> Assume I have a class Person with methods #firstname and #lastname that
> I want to put into a SortedBlock.
>
> I want to create a generic sortBlock so I can sort either by #firstname
> or by #lastname.
>
> This code (see me previous 'Currying blocks' post) works:
>
> curry := [:query| [:a :b| (a perform: query ) < (b perform: query )]].
>
> curry2 := [:query| [:a :b| (a query asSymbol) < (b query asSymbol)].]

curry2 makes no sense because 'query' is a parameter to the outer block,
'a' and 'b' parameters to the inner block. Nevertheless you have code
like '(a query asSymbol)' which should produce an error because you send
  the message 'query' to the variable 'a'.  You should use perform: in
this case (like your first example '(a perform: query)').

> coll := SortedCollection sortBlock: (curry value: #lastname).
> or
> coll := SortedCollecton sortBlock: (curry2 value: #firstname).
>
> However, if I change te definition of the curryed block to:
> curry3 := [:query| [:a :b| (a query ) < (b query )]]
>
> It won't work and when I try to add something to the collection, I get
> a DNU error, complaning that Person doesnt understand 'query'.

Its the same as above. '(a query)' means you send the message 'query' to
'a' which isn't defined. But 'query' is not a method to invoke, its a
variable which holds a Symbol (#firstname or #lastname). So use '(a
perform: query)' which tell the object stored in the variable 'a' (an
instance of the class Person) to invoke a method which name (selector)
is the symbol stored in the variable 'query'.

> Why do I have to send the message #asSymbol (see curry2)? After all,
> I'm already sending a symbol when I evaluate curry2 value: #firstname.
>
> I think I'm missing something about symbols, but I'm not sure what.

You cannot send symbols. You can send only messages (maybe with
parameters) to objects not objects to objects. Messages normally invoke
methods defined in the class (or superclass) of the receiving object
which have the same selector (which is a Symbol).

> PS I'm using Dolphin 5.1
>

This basic stuff should be the same for all Smalltalks. Hope this helps
to clarify things a bit. Take a look at the class named 'Class'. There
is functionality about the methods. In VW you can send
getMethodDictionary to a class (i.e. to Class or Person) and you get the
methods defined in that class.

Volker


Reply | Threaded
Open this post in threaded view
|

Re: Trouble with symbols

Martin Rubi
In reply to this post by Fernando Rodríguez
Fernando

> curry2 := [:query| [:a :b| (a query asSymbol) < (b query asSymbol)].]

Are you sure this actually works ? I don't think it's expected to. When you
write this

(a query asSymbol)

you are actually sending the message #query to the object bound to the
variable named 'a', and then you are sending the message #asSymbol to the
object answered by the previous message send.
In the context of the block you defined, there is also a variable named
'query', but you are not referencing it anywhere in the block. That is
becuase smalltalk sintax expects a message, and not a variable name, after
'a'. In order to send the message selector bound to the variable 'query' to
the object bound to the variable 'a', you must use #perform:, as in your
'curry' example.

However, it seems to me that you want to do something similar to Chris
Uppal's 'CU Sortblocks' goodie, which you can download from here:
http://www.metagnostic.org/DolphinSmalltalk/Miscellanea.html

Perhaps you can use it or take a look at it to get more ideas.

Regards.
Martin