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 |
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 |
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 |
Free forum by Nabble | Edit this page |