206 VW compatibility." |
199 VW compatibility." |
207 |
200 |
208 ^ UserMessage key:self catalogID:catalogID |
201 ^ UserMessage key:self catalogID:catalogID |
209 |
202 |
210 " |
203 " |
211 (#theFooMessage << #myMessages) |
204 (#theFooMessage << #myMessages) |
212 (#theFooMessage << #myMessages >> 'cannot read subclass of metaclass') |
205 (#theFooMessage << #myMessages >> 'cannot read subclass of metaclass') |
213 (#theFooMessage >> 'cannot read subclass of metaclass') |
206 (#theFooMessage >> 'cannot read subclass of metaclass') |
214 " |
207 " |
215 ! |
208 ! |
216 |
209 |
217 >> aString |
210 >> aString |
218 "create and return a new UserMessage, with the receiver as key, |
211 "create and return a new UserMessage, with the receiver as key, |
219 and the argument as defaultString. |
212 and the argument as defaultString. |
220 VW compatibility." |
213 VW compatibility." |
221 |
214 |
222 ^ UserMessage key:self defaultString:aString |
215 ^ UserMessage key:self defaultString:aString |
223 |
216 |
224 " |
217 " |
225 (#theFooMessage << #myMessages) |
218 (#theFooMessage << #myMessages) |
226 (#theFooMessage << #myMessages >> 'cannot read subclass of metaclass') |
219 (#theFooMessage << #myMessages >> 'cannot read subclass of metaclass') |
227 (#theFooMessage >> 'cannot read subclass of metaclass') |
220 (#theFooMessage >> 'cannot read subclass of metaclass') |
228 " |
221 " |
229 ! ! |
222 ! ! |
230 |
223 |
231 !Symbol methodsFor:'accessing'! |
224 !Symbol methodsFor:'accessing'! |
232 |
225 |
249 |
242 |
250 !Symbol methodsFor:'comparing'! |
243 !Symbol methodsFor:'comparing'! |
251 |
244 |
252 = something |
245 = something |
253 "return true, if the receiver and argument consist of the same characters. |
246 "return true, if the receiver and argument consist of the same characters. |
254 Redefined here, for more efficient #= comparison of symbols |
247 Redefined here, for more efficient #= comparison of symbols |
255 (which ought to be compared using #==). |
248 (which ought to be compared using #==). |
256 If the argument is a symbol, we use a quick pointer compare, instead of |
249 If the argument is a symbol, we use a quick pointer compare, instead of |
257 the inherited value compare." |
250 the inherited value compare." |
258 |
251 |
259 %{ /* NOCONTEXT */ |
252 %{ /* NOCONTEXT */ |
262 if (! __isNonNilObject(something)) RETURN(false); |
255 if (! __isNonNilObject(something)) RETURN(false); |
263 if ((cls = __qClass(something)) == Symbol) { |
256 if ((cls = __qClass(something)) == Symbol) { |
264 RETURN (self == something ? true : false); |
257 RETURN (self == something ? true : false); |
265 } |
258 } |
266 if (cls == String) { |
259 if (cls == String) { |
267 RETURN (strcmp(__stringVal(self), __stringVal(something)) == 0 ? true : false); |
260 RETURN (strcmp(__stringVal(self), __stringVal(something)) == 0 ? true : false); |
268 } |
261 } |
269 %}. |
262 %}. |
270 "fall back; could be a TwoByteString, or a collection of Characters" |
263 "fall back; could be a TwoByteString, or a collection of Characters" |
271 |
264 |
272 ^ super = something |
265 ^ super = something |
290 * after it got a hashKey assigned. |
283 * after it got a hashKey assigned. |
291 */ |
284 */ |
292 if (val == 0) { |
285 if (val == 0) { |
293 cp = __stringVal(self); |
286 cp = __stringVal(self); |
294 l = __stringSize(self); |
287 l = __stringSize(self); |
295 |
288 |
296 /* |
289 /* |
297 * this is the dragon-book algorithm |
290 * this is the dragon-book algorithm |
298 * We have tested 5-bit shifts as well: |
291 * We have tested 5-bit shifts as well: |
299 * |
292 * |
300 * ST/X Symbols: 17807 |
293 * ST/X Symbols: 17807 |
301 * Hashkey collisions (4bit): 14 0.07% |
294 * Hashkey collisions (4bit): 14 0.07% |
302 * Hashkey collisions (5bit): 300 1.68% |
295 * Hashkey collisions (5bit): 300 1.68% |
303 */ |
296 */ |
304 |
297 |
305 if (l > 0) { |
298 if (l > 0) { |
348 Symbol allInstancesDo:[:instance | |
341 Symbol allInstancesDo:[:instance | |
349 hashColl add:instance identityHash |
342 hashColl add:instance identityHash |
350 ]. |
343 ]. |
351 hashSet := hashColl asSet. |
344 hashSet := hashColl asSet. |
352 |
345 |
353 Transcript showCR:'Symbols: ', hashColl size printString, |
346 Transcript showCR:'Symbols: ', hashColl size printString, |
354 ' unique hash keys: ', hashSet size printString, |
347 ' unique hash keys: ', hashSet size printString, |
355 ' collisions:', (hashColl size - hashSet size) printString. |
348 ' collisions:', (hashColl size - hashSet size) printString. |
356 " |
349 " |
357 |
350 |
358 ! |
351 ! |
359 |
352 |
360 ~= something |
353 ~= something |
361 "return true, if the receiver and argument do not consist of the same characters. |
354 "return true, if the receiver and argument do not consist of the same characters. |
362 Redefined here, for more efficient #~= comparison of symbols |
355 Redefined here, for more efficient #~= comparison of symbols |
363 (which ought to be compared using #~~). |
356 (which ought to be compared using #~~). |
364 If the argument is a symbol, we use a quick pointer compare, instead of |
357 If the argument is a symbol, we use a quick pointer compare, instead of |
365 the inherited value compare." |
358 the inherited value compare." |
366 |
359 |
367 %{ /* NOCONTEXT */ |
360 %{ /* NOCONTEXT */ |
388 %{ /* NOCONTEXT */ |
381 %{ /* NOCONTEXT */ |
389 OBJ s; |
382 OBJ s; |
390 |
383 |
391 s = __MKSTRING_ST(self); |
384 s = __MKSTRING_ST(self); |
392 if (s != nil) { |
385 if (s != nil) { |
393 RETURN (s); |
386 RETURN (s); |
394 } |
387 } |
395 %}. |
388 %}. |
396 ^ (String new:(self size)) |
389 ^ (String new:(self size)) |
397 replaceFrom:1 with:self startingAt:1 |
390 replaceFrom:1 with:self startingAt:1 |
398 ! |
391 ! |
399 |
392 |
400 asSymbol |
393 asSymbol |
401 "Return a unique symbol with the name taken from the receivers characters. |
394 "Return a unique symbol with the name taken from the receivers characters. |
402 Since I am a symbol - just return myself" |
395 Since I am a symbol - just return myself" |
403 |
396 |
404 ^ self |
397 ^ self |
405 ! |
398 ! |
406 |
399 |
407 asSymbolIfInterned |
400 asSymbolIfInterned |
408 "If a symbol with the receivers characters is already known, return it. Otherwise, return nil. |
401 "If a symbol with the receivers characters is already known, return it. Otherwise, return nil. |
409 Since I am a symbol - just return myself" |
402 Since I am a symbol - just return myself" |
410 |
403 |
411 ^ self |
404 ^ self |
412 ! ! |
405 ! ! |
413 |
406 |
513 |
506 |
514 |storeString| |
507 |storeString| |
515 |
508 |
516 storeString := self storeString. |
509 storeString := self storeString. |
517 (self == #true or:[self == #false or:[self == #nil or:[(storeString at:2) == $']]]) ifTrue:[ |
510 (self == #true or:[self == #false or:[self == #nil or:[(storeString at:2) == $']]]) ifTrue:[ |
518 aStream nextPutAll:storeString. |
511 aStream nextPutAll:storeString. |
519 ] ifFalse:[ |
512 ] ifFalse:[ |
520 aStream nextPutAll:self. |
513 aStream nextPutAll:self. |
521 ]. |
514 ]. |
522 ! |
515 ! |
523 |
516 |
524 storeOn:aStream |
517 storeOn:aStream |
525 "store myself on a stream" |
518 "store myself on a stream" |
528 ! |
521 ! |
529 |
522 |
530 storeString |
523 storeString |
531 "return a String for storing the receiver" |
524 "return a String for storing the receiver" |
532 |
525 |
533 |sz "{Class: SmallInteger }" |
526 |sz "{Class: SmallInteger }" |
534 c anyColon| |
527 c anyColon| |
535 |
528 |
536 sz := self size. |
529 sz := self size. |
537 (sz ~~ 0 and:[(self at:1) isLetter]) ifTrue:[ |
530 (sz ~~ 0 and:[(self at:1) isLetter]) ifTrue:[ |
538 anyColon := false. |
531 anyColon := false. |
539 2 to:sz do:[:index | |
532 2 to:sz do:[:index | |
540 c := self at:index. |
533 c := self at:index. |
541 c == $: ifTrue:[ |
534 c == $: ifTrue:[ |
542 (index == sz or:[(self at:(index+1)) isLetterOrDigit]) ifFalse:[ |
535 (index == sz or:[(self at:(index+1)) isLetterOrDigit]) ifFalse:[ |
543 ^ '#' , super storeString. |
536 ^ '#' , super storeString. |
544 ]. |
537 ]. |
545 anyColon := true. |
538 anyColon := true. |
546 ] ifFalse:[ |
539 ] ifFalse:[ |
547 c isLetterOrDigit ifFalse:[ |
540 c isLetterOrDigit ifFalse:[ |
548 ^ '#' , super storeString |
541 ^ '#' , super storeString |
549 ]. |
542 ]. |
550 ]. |
543 ]. |
551 ]. |
544 ]. |
552 "no colon in symbol or symbol ends with a colon" |
545 "no colon in symbol or symbol ends with a colon" |
553 (anyColon and:[c ~~ $:]) ifFalse:[ |
546 (anyColon and:[c ~~ $:]) ifFalse:[ |
554 ^ '#' , self |
547 ^ '#' , self |
555 ]. |
548 ]. |
556 ]. |
549 ]. |
557 ^ '#' , super storeString |
550 ^ '#' , super storeString |
558 |
551 |
559 " |
552 " |
560 #'abc' storeString |
553 #'abc' storeString |
561 #'abc:' storeString |
554 #'abc:' storeString |
562 #'abc:def:' storeString |
555 #'abc:def:' storeString |
563 #'abc:def' storeString |
556 #'abc:def' storeString |
564 #'abc::def' storeString |
557 #'abc::def' storeString |
565 #'abc &^*' storeString |
558 #'abc &^*' storeString |
566 #'abcdef::' storeString |
559 #'abcdef::' storeString |
567 #'hello''world' storeString |
560 #'hello''world' storeString |
568 #'' storeString |
561 #'' storeString |
569 #'''' storeString |
562 #'''' storeString |
570 #'_hello' storeString |
563 #'_hello' storeString |
571 #'123' storeString |
564 #'123' storeString |
572 " |
565 " |
573 ! ! |
566 ! ! |
574 |
567 |
575 !Symbol methodsFor:'queries'! |
568 !Symbol methodsFor:'queries'! |
576 |
569 |
594 "return true, if the receiver is a keyword message selector" |
587 "return true, if the receiver is a keyword message selector" |
595 |
588 |
596 ^ self includes:$: |
589 ^ self includes:$: |
597 |
590 |
598 " |
591 " |
599 #at:put: isKeyword |
592 #at:put: isKeyword |
600 #at: isKeyword |
593 #at: isKeyword |
601 #+ isKeyword |
594 #+ isKeyword |
602 #size isKeyword |
595 #size isKeyword |
603 " |
596 " |
604 |
597 |
605 "Created: / 1.11.1997 / 12:34:55 / cg" |
598 "Created: / 1.11.1997 / 12:34:55 / cg" |
606 "Modified: / 1.11.1997 / 12:36:37 / cg" |
599 "Modified: / 1.11.1997 / 12:36:37 / cg" |
607 ! |
600 ! |
608 |
601 |
609 isSymbol |
602 isSymbol |
610 "return true, if the receiver is some kind of symbol. |
603 "return true, if the receiver is some kind of symbol. |
611 Since I am a symbol, return always true" |
604 Since I am a symbol, return always true" |
612 |
605 |
613 ^ true |
606 ^ true |
614 ! |
607 ! |
670 rid of the receiver. For symbols, this is not allowed, if the receiver |
663 rid of the receiver. For symbols, this is not allowed, if the receiver |
671 is used as a key in some SystemDictionary. |
664 is used as a key in some SystemDictionary. |
672 This can be a very dangerous operation - be warned. |
665 This can be a very dangerous operation - be warned. |
673 |
666 |
674 Notice: because of the danger here, this method may report an error |
667 Notice: because of the danger here, this method may report an error |
675 in future versions" |
668 in future versions" |
676 |
669 |
677 (Smalltalk includesKey:self) ifTrue:[ |
670 (Smalltalk includesKey:self) ifTrue:[ |
678 self primitiveFailed |
671 self primitiveFailed |
679 ] ifFalse:[ |
672 ] ifFalse:[ |
680 super becomeNil |
673 super becomeNil |
681 ] |
674 ] |
682 ! ! |
675 ! ! |
683 |
676 |
684 !Symbol methodsFor:'tracing'! |
677 !Symbol methodsFor:'tracing'! |
685 |
678 |