I am trying to find a certain value in a collection. does something if true or does something if false and for some reason it always evaluates to false and I know its there. Any help would be great
sample code.
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
element is an object that has number as a method
--------------------------------- Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now
On Sun, 2 Feb 2003, Janet Abdul-Karim wrote:
I am trying to find a certain value in a collection. does something if true or does something if false and for some reason it always evaluates to false and I know its there. Any help would be great
sample code.
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
My guess is that you want to use #= (equality) not #== (identity equality). Numbers above a certain size are represented in such a way that they are not the same object even when they are the same number, and so they are #= but not #==. For example:
12 = 12 "true" 12 == 12 "true" (12 raisedTo: 10) = (12 raisedTo: 10) "true" (12 raisedTo: 10) == (12 raisedTo: 10) "false"
Avi
I am understanding what you said about the difference between #= and #==, but I still get the same result. I am wondering is my logic somehow work or could I possibly be missing some type of punctuation because I know the object is there but it seems to always evaluate the false part and then prints out the type of the object that i am looking for. Avi Bryant avi@beta4.com wrote: On Sun, 2 Feb 2003, Janet Abdul-Karim wrote:
I am trying to find a certain value in a collection. does something if true or does something if false and for some reason it always evaluates to false and I know its there. Any help would be great
sample code.
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
My guess is that you want to use #= (equality) not #== (identity equality). Numbers above a certain size are represented in such a way that they are not the same object even when they are the same number, and so they are #= but not #==. For example:
12 = 12 "true" 12 == 12 "true" (12 raisedTo: 10) = (12 raisedTo: 10) "true" (12 raisedTo: 10) == (12 raisedTo: 10) "false"
Avi
--------------------------------- Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now
Have you tried stepping through this with the debugger? Below some ideas to help you solving problems like this the next time (how to set breakpoints, have breakpoints with comment and do conditional breakpoints). If you already know this, then it always might help someone else :-)
For example, add a breakpoint by sending a 'halt' message to any kind of object. Then you can step and send through this piece of code to see what exactly goes on:
self do: [:element | self halt. element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
You will see that the message == gets send and what it does. Note that you can accept new code while you go along, and it will immediately take tis into account. Try it to believe it :-)
Note also that you can use 'halt:' and give a string argument that will be shown when the breakpoints pops up. For example the following will pop up the current number it needs to compare. That way you can decide whether to do 'proceed' or 'debug' more easily:
self do: [:element | self halt: element printString. element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
You can easily set conditional breakpoints, since it is just plain Smalltalk code. For example, you might only want to see the cases when numbers are negative like this:
self do: [:element | (element < 0) ifTrue: [self halt: element printString]. element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
With the same mechanism you can pop up the debugger when a certain key is pressed (so that you can let it crunch for a while before going in to inspect the code. I do not know the exact expression in Squeak, but somebody else will be able to help you there. In VisualWorks (another Smalltalk environment) you would say: InputState default shiftDown ifTrue: [self halt].
Hope this helps a bit. But I am pretty sure (like Avi was) that you want to compare using #= in this case. Almost all of the time you want to do that, actually, unless you are really looking for a particular object, and only want that object.
On Monday, February 3, 2003, at 05:44 AM, Janet Abdul-Karim wrote:
I am understanding what you said about the difference between #= and #==, but I still get the same result. I am wondering is my logic somehow work or could I possibly be missing some type of punctuation because I know the object is there but it seems to always evaluate the false part and then prints out the type of the object that i am looking for.
Avi Bryant avi@beta4.com wrote:
On Sun, 2 Feb 2003, Janet Abdul-Karim wrote:
I am trying to find a certain value in a collection. does something
if true or does something if false and for some reason it always evaluates to false and I know its there. Any help would be great
sample code.
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this
portfolio';cr])].
My guess is that you want to use #= (equality) not #== (identity equality). Numbers above a certain size are represented in such a way that they are not the same object even when they are the same number, and so they are #= but not #==. For example:
12 = 12 "true" 12 == 12 "true" (12 raisedTo: 10) = (12 raisedTo: Yahoo! Mail Plus - Powerful. Affordable. Sign up now
Roel Wuyts Software Composition Group roel.wuyts@iam.unibe.ch University of Bern, Switzerland http://www.iam.unibe.ch/~wuyts/ Board Member of the European Smalltalk User Group: www.esug.org
Hi Janet!
I just replied to your first post and then saw this followup.
Janet Abdul-Karim jn_karim@yahoo.com wrote:
I am understanding what you said about the difference between #= and #==, but I still get the same result. I am wondering is my logic somehow work or could I possibly be missing some type of punctuation because I know the object is there but it seems to always evaluate the false part and then prints out the type of the object that i am looking for.
I think that if you look closely in Transcript it shows *for each element* in the collection either the element or the "No such account exists..." string.
So if the collection contains three instances of Account and you search for the one with number 3 (lets say the last one added) it would probably show something like this in Transcript:
No such account exists in this portfolio No such account exists in this portfolio an Account
...or something like that. One line for each element.
regards, Göran
Hi Janet,
I think your mistake lies in what you expect to happen. The comparison wil be evaluated for every element in the collection and thus the transcipt will tell you (n-1) times that the element is not in the collection (where n is the number of elements in the collection) and only once will show the element.
To make it clearer i'd change the code to: (assuming you do this in an inspector where self is bound to the collection) self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: element, ' is not the desired element';cr])].
Of course you could also write: Transcript show: (self detect:[:element | element number == accountNumber] ifNone:['no such element']).
HTH, Torge
03.02.2003 05:44:13, Janet Abdul-Karim jn_karim@yahoo.com wrote:
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this
portfolio';cr])].
My guess is that you want to use #= (equality) not #== (identity equality). Numbers above a certain size are represented in such a way that they are not the same object even when they are the same number, and so they are #= but not #==. For example:
12 = 12 "true" 12 == 12 "true" (12 raisedTo: 10) = (12 raisedTo: 10) "true" (12 raisedTo: 10) == (12 raisedTo: 10) "false"
Avi
Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now
Hi
I have the impression that self should not be your account collections. Because this would mean that you are defining a new kind of collection. While you certainly want to have an object holding a collection of accounts :)
What about
findAccount: aNumber ^ accountCol select: [:each | each number = accountNumber]
Stef
On Monday, February 3, 2003, at 04:38 AM, Avi Bryant wrote:
On Sun, 2 Feb 2003, Janet Abdul-Karim wrote:
I am trying to find a certain value in a collection. does something if true or does something if false and for some reason it always evaluates to false and I know its there. Any help would be great
sample code.
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
My guess is that you want to use #= (equality) not #== (identity equality). Numbers above a certain size are represented in such a way that they are not the same object even when they are the same number, and so they are #= but not #==. For example:
12 = 12 "true" 12 == 12 "true" (12 raisedTo: 10) = (12 raisedTo: 10) "true" (12 raisedTo: 10) == (12 raisedTo: 10) "false"
Avi
Prof. Dr. Stéphane DUCASSE (ducasse@iam.unibe.ch) http://www.iam.unibe.ch/~ducasse/ "if you knew today was your last day on earth, what would you do different? ... especially if, by doing something different, today might not be your last day on earth" Calvin&Hobbes
Dear Janet,
I am trying to find a certain value in a collection. does something if true or does something if false and for some reason it always evaluates to false and I know its there. Any help would be great
sample code.
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:([Transcript show: element;cr]) ifFalse:([Transcript show: 'No such account exists in this portfolio';cr])].
element is an object that has number as a method
You say, "sample code." Is this your exact code? This code should print out a message for each account. Is that what happens? If so, you should have "No such account exists .... " printing out for all accounts but one. From what you say, it sounds like it prints something out only once.
Perhaps your code looks at only one element. If element number == accountNumber, it prints the element in Transcript, if not, it says (falsely), "No such account exists in this portfolio."
You might try something like this:
findAccount: accountNumber "Find the account with the argument number"
self do:[:element | element number == accountNumber ifTrue:[Transcript show: element;cr. ^element]]. "If there is a match, the method returns element." Transcript show: 'No such account exists in this portfolio';cr. ^false "If there is no match, it returns false."
Good luck!
Bill
squeak-dev@lists.squeakfoundation.org