Hi,
why is the concatenation of symbols a string? e.g. #desc, #Name -> 'descName' this means that I have to always wrap in parentheses and recast, or stream it, e.g. (#desc, #Name) asSymbol -> #descName Symbol streamContents: [ :s | s << #desc; << #Name ] -> #descName both of which introduce extraneous syntactical clutter. The technical reason seems to be ByteSymbol>>#species returning ByteString, but I have no idea why it has to be this complicated. Thanks, Peter |
Hi, All symbols are interned in the Symbol table. If one does (#foo , #bar , #baz) and each returned value would be a symbol, then both #foobar and #foobarbaz would be registered in the symbol table. I would guess that's why the concatenated value is a string and not a symbol, to avoid registering many unused symbols. But maybe I am wrong. If for your use case you need to concatenate symbols and get a symbol out of it, you can define a new method in Symbol to do what you want. For example: Symbol >> ,, arg ^ (self , arg) asSymbol Then #foo ,, #bar Answers directly the symbol #foobar. Best, On Sat, Mar 4, 2017 at 11:36 AM, Peter Uhnak <[hidden email]> wrote: Hi, |
Hmm.. symbols is usually treated like immutable object(s) in system. They tend to stay while rest of data changes.. This could explain why authors of this method purposedly picked to use ByteString for its species to discourage using symbols for collection manipulation(s).. Else, if you would need to change this method as well: at: anInteger put: anObject "You cannot modify the receiver." self errorNoModification because base class #, implementation is going to use at:put: during concatenation. On 4 March 2017 at 13:40, Clément Bera <[hidden email]> wrote:
Best regards,
Igor Stasenko. |
I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable.
$, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... Peter On Sun, Mar 05, 2017 at 04:29:39AM +0200, Igor Stasenko wrote: > Hmm.. symbols is usually treated like immutable object(s) in system. They > tend to stay while rest of data changes.. This could explain why authors of > this method > purposedly picked to use ByteString for its species to discourage using > symbols for collection manipulation(s).. > Else, if you would need to change this method as well: > > at: anInteger put: anObject > "You cannot modify the receiver." > > self errorNoModification > > because base class #, implementation is going to use at:put: during > concatenation. > > > > On 4 March 2017 at 13:40, Clément Bera <[hidden email]> wrote: > > > Hi, > > > > All symbols are interned in the Symbol table. If one does (#foo , #bar , > > #baz) and each returned value would be a symbol, then both #foobar and > > #foobarbaz would be registered in the symbol table. > > > > I would guess that's why the concatenated value is a string and not a > > symbol, to avoid registering many unused symbols. But maybe I am wrong. > > > > If for your use case you need to concatenate symbols and get a symbol out > > of it, you can define a new method in Symbol to do what you want. > > > > For example: > > > > Symbol >> ,, arg > > ^ (self , arg) asSymbol > > > > Then > > > > #foo ,, #bar > > > > Answers directly the symbol #foobar. > > > > Best, > > > > > > > > > > On Sat, Mar 4, 2017 at 11:36 AM, Peter Uhnak <[hidden email]> wrote: > > > >> Hi, > >> > >> why is the concatenation of symbols a string? > >> > >> e.g. #desc, #Name -> 'descName' > >> > >> this means that I have to always wrap in parentheses and recast, or > >> stream it, e.g. > >> > >> (#desc, #Name) asSymbol -> #descName > >> Symbol streamContents: [ :s | s << #desc; << #Name ] -> #descName > >> > >> both of which introduce extraneous syntactical clutter. > >> The technical reason seems to be ByteSymbol>>#species returning > >> ByteString, but I have no idea why it has to be this complicated. > >> > >> Thanks, > >> Peter > >> > >> > > > > > -- > Best regards, > Igor Stasenko. |
I also think that allowing concatenation on Symbols does not violate their immutability contract.
As a thought experiment, what could be the problem with adding Symbol >> , arg ^ (self , arg) asSymbol ? (I have found the original issue raised annoying as well) > On 5 Mar 2017, at 11:35, Peter Uhnak <[hidden email]> wrote: > > I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable. > $, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... > > Peter > > > On Sun, Mar 05, 2017 at 04:29:39AM +0200, Igor Stasenko wrote: >> Hmm.. symbols is usually treated like immutable object(s) in system. They >> tend to stay while rest of data changes.. This could explain why authors of >> this method >> purposedly picked to use ByteString for its species to discourage using >> symbols for collection manipulation(s).. >> Else, if you would need to change this method as well: >> >> at: anInteger put: anObject >> "You cannot modify the receiver." >> >> self errorNoModification >> >> because base class #, implementation is going to use at:put: during >> concatenation. >> >> >> >> On 4 March 2017 at 13:40, Clément Bera <[hidden email]> wrote: >> >>> Hi, >>> >>> All symbols are interned in the Symbol table. If one does (#foo , #bar , >>> #baz) and each returned value would be a symbol, then both #foobar and >>> #foobarbaz would be registered in the symbol table. >>> >>> I would guess that's why the concatenated value is a string and not a >>> symbol, to avoid registering many unused symbols. But maybe I am wrong. >>> >>> If for your use case you need to concatenate symbols and get a symbol out >>> of it, you can define a new method in Symbol to do what you want. >>> >>> For example: >>> >>> Symbol >> ,, arg >>> ^ (self , arg) asSymbol >>> >>> Then >>> >>> #foo ,, #bar >>> >>> Answers directly the symbol #foobar. >>> >>> Best, >>> >>> >>> >>> >>> On Sat, Mar 4, 2017 at 11:36 AM, Peter Uhnak <[hidden email]> wrote: >>> >>>> Hi, >>>> >>>> why is the concatenation of symbols a string? >>>> >>>> e.g. #desc, #Name -> 'descName' >>>> >>>> this means that I have to always wrap in parentheses and recast, or >>>> stream it, e.g. >>>> >>>> (#desc, #Name) asSymbol -> #descName >>>> Symbol streamContents: [ :s | s << #desc; << #Name ] -> #descName >>>> >>>> both of which introduce extraneous syntactical clutter. >>>> The technical reason seems to be ByteSymbol>>#species returning >>>> ByteString, but I have no idea why it has to be this complicated. >>>> >>>> Thanks, >>>> Peter >>>> >>>> >>> >> >> >> -- >> Best regards, >> Igor Stasenko. > |
On 03/05/2017 03:01 AM, Sven Van
Caekenberghe wrote:
I also think that allowing concatenation on Symbols does not violate their immutability contract. As a thought experiment, what could be the problem with adding Symbol >> , arg ^ (self , arg) asSymbol ? Aside from the infinite recursion (I suspect you meant super rather than self) :-) , I wouldn't have any problem with that. (I have found the original issue raised annoying as well)On 5 Mar 2017, at 11:35, Peter Uhnak [hidden email] wrote: I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable. $, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... Somewhat unfortunately, imho, Smalltalk Strings are mutable. I've not seen this feature used often, except by internal operations that could just as well be using a CharacterBuffer or whatever would replace String as the mutable thing if you made String immutable. Regards, -Martin |
> On 5 Mar 2017, at 19:53, Martin McClure <[hidden email]> wrote: > > On 03/05/2017 03:01 AM, Sven Van Caekenberghe wrote: >> I also think that allowing concatenation on Symbols does not violate their immutability contract. >> >> As a thought experiment, what could be the problem with adding >> >> Symbol >> , arg >> ^ (self , arg) asSymbol >> >> ? >> > > Aside from the infinite recursion (I suspect you meant super rather than self) :-) , I wouldn't have any problem with that. Haha, I copied it from lower in the thread, but shame on me that I didn't see that right away ! >> (I have found the original issue raised annoying as well) >> >> >>> On 5 Mar 2017, at 11:35, Peter Uhnak <[hidden email]> >>> wrote: >>> >>> I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable. >>> $, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... >>> > Somewhat unfortunately, imho, Smalltalk Strings are mutable. I've not seen this feature used often, except by internal operations that could just as well be using a CharacterBuffer or whatever would replace String as the mutable thing if you made String immutable. Yes, this distinction, with a default for immutable ones, would be good. We got #beReadOnlyObject in Pharo, so I guess we can start experimenting. Especially literal strings should be read only. > Regards, > > -Martin |
In reply to this post by Martin McClure-2
Here is a concrete proposal:
https://pharo.fogbugz.com/f/cases/19802/Make-sure-Symbol-concatenation-results-in-a-Symbol-not-a-String This gives the following assertions: "Concatenating 2 symbols results in abother symbol" self assert: (#foo , #bar) == #foobar. "Concatenating the empty symbol does not change a symbol" self assert: (#foo, emptySymbol) == #foo. self assert: (emptySymbol, #foo) == #foo. "Strings and symbols can still be mixed, the receiver determines the result type" "Symbol receiver gives symbol result" self assert: (#foo , 'bar') == #foobar. "String receiver gives string result" self deny: ('foo' , #bar) == #foobar. self assert: ('foo' , #bar) equals: #foobar. self assert: ('foo' , #bar) equals: 'foobar'. > On 5 Mar 2017, at 19:53, Martin McClure <[hidden email]> wrote: > > On 03/05/2017 03:01 AM, Sven Van Caekenberghe wrote: >> I also think that allowing concatenation on Symbols does not violate their immutability contract. >> >> As a thought experiment, what could be the problem with adding >> >> Symbol >> , arg >> ^ (self , arg) asSymbol >> >> ? >> > > Aside from the infinite recursion (I suspect you meant super rather than self) :-) , I wouldn't have any problem with that. > >> >> (I have found the original issue raised annoying as well) >> >> >>> On 5 Mar 2017, at 11:35, Peter Uhnak <[hidden email]> >>> wrote: >>> >>> I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable. >>> $, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... >>> > Somewhat unfortunately, imho, Smalltalk Strings are mutable. I've not seen this feature used often, except by internal operations that could just as well be using a CharacterBuffer or whatever would replace String as the mutable thing if you made String immutable. > > Regards, > > -Martin |
Thanks Sven!
this looks good, and now also behaves same way as concating other collections (that is, the result type is the receivers' type). Peter On Mon, Mar 06, 2017 at 10:54:32AM +0100, Sven Van Caekenberghe wrote: > Here is a concrete proposal: > > https://pharo.fogbugz.com/f/cases/19802/Make-sure-Symbol-concatenation-results-in-a-Symbol-not-a-String > > This gives the following assertions: > > "Concatenating 2 symbols results in abother symbol" > self assert: (#foo , #bar) == #foobar. > > "Concatenating the empty symbol does not change a symbol" > self assert: (#foo, emptySymbol) == #foo. > self assert: (emptySymbol, #foo) == #foo. > > "Strings and symbols can still be mixed, the receiver determines the result type" > "Symbol receiver gives symbol result" > self assert: (#foo , 'bar') == #foobar. > "String receiver gives string result" > self deny: ('foo' , #bar) == #foobar. > self assert: ('foo' , #bar) equals: #foobar. > self assert: ('foo' , #bar) equals: 'foobar'. > > > On 5 Mar 2017, at 19:53, Martin McClure <[hidden email]> wrote: > > > > On 03/05/2017 03:01 AM, Sven Van Caekenberghe wrote: > >> I also think that allowing concatenation on Symbols does not violate their immutability contract. > >> > >> As a thought experiment, what could be the problem with adding > >> > >> Symbol >> , arg > >> ^ (self , arg) asSymbol > >> > >> ? > >> > > > > Aside from the infinite recursion (I suspect you meant super rather than self) :-) , I wouldn't have any problem with that. > > > >> > >> (I have found the original issue raised annoying as well) > >> > >> > >>> On 5 Mar 2017, at 11:35, Peter Uhnak <[hidden email]> > >>> wrote: > >>> > >>> I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable. > >>> $, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... > >>> > > Somewhat unfortunately, imho, Smalltalk Strings are mutable. I've not seen this feature used often, except by internal operations that could just as well be using a CharacterBuffer or whatever would replace String as the mutable thing if you made String immutable. > > > > Regards, > > > > -Martin > > |
In reply to this post by Sven Van Caekenberghe-2
On Mon, Mar 6, 2017 at 5:54 PM, Sven Van Caekenberghe <[hidden email]> wrote: Here is a concrete proposal: Those last two seem contradictory. cheers -ben
|
> On 6 Mar 2017, at 14:12, Ben Coman <[hidden email]> wrote: > > > > On Mon, Mar 6, 2017 at 5:54 PM, Sven Van Caekenberghe <[hidden email]> wrote: > Here is a concrete proposal: > > https://pharo.fogbugz.com/f/cases/19802/Make-sure-Symbol-concatenation-results-in-a-Symbol-not-a-String > > This gives the following assertions: > > "Concatenating 2 symbols results in abother symbol" > self assert: (#foo , #bar) == #foobar. > > "Concatenating the empty symbol does not change a symbol" > self assert: (#foo, emptySymbol) == #foo. > self assert: (emptySymbol, #foo) == #foo. > > "Strings and symbols can still be mixed, the receiver determines the result type" > "Symbol receiver gives symbol result" > self assert: (#foo , 'bar') == #foobar. > "String receiver gives string result" > self deny: ('foo' , #bar) == #foobar. > self assert: ('foo' , #bar) equals: #foobar. > self assert: ('foo' , #bar) equals: 'foobar'. > > > Those last two seem contradictory. No, Symbols and String can be used interchangeably in Pharo in lots of contexts. Particularly when comparing them, it makes no difference, all the following are/have always been true, independent of this change: #foo = 'foo' 'foo' = #foo #foo = #foo 'foo' = 'foo' But maybe it is a bit confusing with an extra comment. > cheers -ben > > > > On 5 Mar 2017, at 19:53, Martin McClure <[hidden email]> wrote: > > > > On 03/05/2017 03:01 AM, Sven Van Caekenberghe wrote: > >> I also think that allowing concatenation on Symbols does not violate their immutability contract. > >> > >> As a thought experiment, what could be the problem with adding > >> > >> Symbol >> , arg > >> ^ (self , arg) asSymbol > >> > >> ? > >> > > > > Aside from the infinite recursion (I suspect you meant super rather than self) :-) , I wouldn't have any problem with that. > > > >> > >> (I have found the original issue raised annoying as well) > >> > >> > >>> On 5 Mar 2017, at 11:35, Peter Uhnak <[hidden email]> > >>> wrote: > >>> > >>> I don't need (or want) to mutate the receiver. Actually I thought that String is also immutable. > >>> $, could just return a new symbol instance instead. Concating symbols is quite practical for metaprogramming, as most things are named with symbols and compare by identity... > >>> > > Somewhat unfortunately, imho, Smalltalk Strings are mutable. I've not seen this feature used often, except by internal operations that could just as well be using a CharacterBuffer or whatever would replace String as the mutable thing if you made String immutable. > > > > Regards, > > > > -Martin |
On Mon, Mar 6, 2017 at 9:21 PM, Sven Van Caekenberghe <[hidden email]> wrote:
> >> On 6 Mar 2017, at 14:12, Ben Coman <[hidden email]> wrote: >> >> >> >> On Mon, Mar 6, 2017 at 5:54 PM, Sven Van Caekenberghe <[hidden email]> wrote: >> Here is a concrete proposal: >> >> https://pharo.fogbugz.com/f/cases/19802/Make-sure-Symbol-concatenation-results-in-a-Symbol-not-a-String >> >> This gives the following assertions: >> >> "Concatenating 2 symbols results in abother symbol" >> self assert: (#foo , #bar) == #foobar. >> >> "Concatenating the empty symbol does not change a symbol" >> self assert: (#foo, emptySymbol) == #foo. >> self assert: (emptySymbol, #foo) == #foo. >> >> "Strings and symbols can still be mixed, the receiver determines the result type" >> "Symbol receiver gives symbol result" >> self assert: (#foo , 'bar') == #foobar. >> "String receiver gives string result" >> self deny: ('foo' , #bar) == #foobar. >> self assert: ('foo' , #bar) equals: #foobar. >> self assert: ('foo' , #bar) equals: 'foobar'. >> >> >> Those last two seem contradictory. > > No, Symbols and String can be used interchangeably in Pharo in lots of contexts. Particularly when comparing them, it makes no difference, all the following are/have always been true, independent of this change: > > #foo = 'foo' > 'foo' = #foo > #foo = #foo > 'foo' = 'foo' Ah-ha... gotchya. always something more to learn. So those last three lines a testing that it is a String? This meaning is pretty well hidden in the implicit behaviour. Why not just... self assert: (#foo , 'bar') isString which seems to better "says what it means" If such is poor form in general, I'm curious to what degree such rules may be relaxed for unit tests. Could it be considered something like premature optimisation to make the test too generic?? If isString latter causes a problem later, deal with it then. ==== On another slightly different point, this might be one case where #assert:#equals is less clear than using "=" Its also easy to mis-think the following is contradictory >> self deny: ('foo' , #bar) == #foobar. >> self assert: ('foo' , #bar) equals: #foobar. where the alternative here makes the distinction more clear... self deny: ('foo' , #bar) == #foobar. self assert: ('foo' , #bar) = #foobar. cheers -ben |
Ben,
I tried to avoid #isString and #isSymbol and I thought it was clear that #assert:equals: used #= but I agree that I could be more explicit. Here is the changed version of the unit test (.2 of slice): testConcatenationIsSymbol "Concatenating 2 symbols results in another symbol" self assert: (#foo , #bar) isSymbol. self assert: (#foo , #bar) == #foobar. "Concatenating the empty Symbol does not change a Symbol" self assert: (#foo , emptySymbol) == #foo. self assert: (emptySymbol , #foo) == #foo. "Strings and Symbols can still be mixed, the receiver determines the result type" "Symbol receiver gives Symbol result" self assert: (#foo , 'bar') isSymbol. self assert: (#foo , 'bar') == #foobar. "String receiver gives String result" self assert: ('foo' , #bar) isString. self assert: ('foo' , #bar) = 'foobar'. "Strings and Symbols still compare content-wise" self assert: ('foo' , #bar) = #foobar. "But Strings and Symbols are not identical" self deny: ('foo' , #bar) == #foobar. > On 6 Mar 2017, at 15:18, Ben Coman <[hidden email]> wrote: > > On Mon, Mar 6, 2017 at 9:21 PM, Sven Van Caekenberghe <[hidden email]> wrote: >> >>> On 6 Mar 2017, at 14:12, Ben Coman <[hidden email]> wrote: >>> >>> >>> >>> On Mon, Mar 6, 2017 at 5:54 PM, Sven Van Caekenberghe <[hidden email]> wrote: >>> Here is a concrete proposal: >>> >>> https://pharo.fogbugz.com/f/cases/19802/Make-sure-Symbol-concatenation-results-in-a-Symbol-not-a-String >>> >>> This gives the following assertions: >>> >>> "Concatenating 2 symbols results in abother symbol" >>> self assert: (#foo , #bar) == #foobar. >>> >>> "Concatenating the empty symbol does not change a symbol" >>> self assert: (#foo, emptySymbol) == #foo. >>> self assert: (emptySymbol, #foo) == #foo. >>> >>> "Strings and symbols can still be mixed, the receiver determines the result type" >>> "Symbol receiver gives symbol result" >>> self assert: (#foo , 'bar') == #foobar. >>> "String receiver gives string result" >>> self deny: ('foo' , #bar) == #foobar. >>> self assert: ('foo' , #bar) equals: #foobar. >>> self assert: ('foo' , #bar) equals: 'foobar'. >>> >>> >>> Those last two seem contradictory. >> >> No, Symbols and String can be used interchangeably in Pharo in lots of contexts. Particularly when comparing them, it makes no difference, all the following are/have always been true, independent of this change: >> >> #foo = 'foo' >> 'foo' = #foo >> #foo = #foo >> 'foo' = 'foo' > > Ah-ha... gotchya. always something more to learn. > > So those last three lines a testing that it is a String? > This meaning is pretty well hidden in the implicit behaviour. > Why not just... > self assert: (#foo , 'bar') isString > which seems to better "says what it means" > > If such is poor form in general, > I'm curious to what degree such rules may be relaxed for unit tests. > Could it be considered something like premature optimisation > to make the test too generic?? If isString latter causes a problem later, > deal with it then. > > ==== > On another slightly different point, > this might be one case where #assert:#equals is less clear than using "=" > > Its also easy to mis-think the following is contradictory >>> self deny: ('foo' , #bar) == #foobar. >>> self assert: ('foo' , #bar) equals: #foobar. > > where the alternative here makes the distinction more clear... > self deny: ('foo' , #bar) == #foobar. > self assert: ('foo' , #bar) = #foobar. > > > cheers -ben |
In reply to this post by Sven Van Caekenberghe-2
On 6 March 2017 at 15:21, Sven Van Caekenberghe <[hidden email]> wrote:
You got me with this... Hey, stop confusing people, put #== everywhere! :) But if seriously, #assert:equals: hides this detail from us, that's why it looks confusing.. IMO, for given case it would be better to use just straight #assert:, with explicit expression that using #= for comparands. -- Best regards,
Igor Stasenko. |
On 03/06/2017 11:17 AM, Igor Stasenko wrote:
> You got me with this... > Hey, stop confusing people, put #== everywhere! :) > > But if seriously, #assert:equals: hides this detail from us, that's why > it looks confusing.. > IMO, for given case it would be better to use just straight #assert:, > with explicit expression that using #= for comparands. assert: (anExpression = someOtherExpression) may, in some cases, be slightly more intention-revealing than assert: anExpression equals: someOtherExpression However, I'd like to advocate for the latter, for ease of debugging. I've been in too many situations where a test fails an equality test, and the failure is not easily reproducible. In the debugger, if #assert: was used I'm left with "false" as my only clue to what happened. OTOH, if #assert:equals: was used, I have both the expected value and the actual value in the debugger, which is a much better clue as to the nature of the problem. Regards, -Martin |
In reply to this post by Sven Van Caekenberghe-2
Thanks Sven.
cheers -ben On Tue, Mar 7, 2017 at 2:43 AM, Sven Van Caekenberghe <[hidden email]> wrote: > Ben, > > I tried to avoid #isString and #isSymbol and I thought it was clear that #assert:equals: used #= but I agree that I could be more explicit. Here is the changed version of the unit test (.2 of slice): > > testConcatenationIsSymbol > "Concatenating 2 symbols results in another symbol" > self assert: (#foo , #bar) isSymbol. > self assert: (#foo , #bar) == #foobar. > > "Concatenating the empty Symbol does not change a Symbol" > self assert: (#foo , emptySymbol) == #foo. > self assert: (emptySymbol , #foo) == #foo. > > "Strings and Symbols can still be mixed, the receiver determines the result type" > "Symbol receiver gives Symbol result" > self assert: (#foo , 'bar') isSymbol. > self assert: (#foo , 'bar') == #foobar. > "String receiver gives String result" > self assert: ('foo' , #bar) isString. > self assert: ('foo' , #bar) = 'foobar'. > "Strings and Symbols still compare content-wise" > self assert: ('foo' , #bar) = #foobar. > "But Strings and Symbols are not identical" > self deny: ('foo' , #bar) == #foobar. > > >> On 6 Mar 2017, at 15:18, Ben Coman <[hidden email]> wrote: >> >> On Mon, Mar 6, 2017 at 9:21 PM, Sven Van Caekenberghe <[hidden email]> wrote: >>> >>>> On 6 Mar 2017, at 14:12, Ben Coman <[hidden email]> wrote: >>>> >>>> >>>> >>>> On Mon, Mar 6, 2017 at 5:54 PM, Sven Van Caekenberghe <[hidden email]> wrote: >>>> Here is a concrete proposal: >>>> >>>> https://pharo.fogbugz.com/f/cases/19802/Make-sure-Symbol-concatenation-results-in-a-Symbol-not-a-String >>>> >>>> This gives the following assertions: >>>> >>>> "Concatenating 2 symbols results in abother symbol" >>>> self assert: (#foo , #bar) == #foobar. >>>> >>>> "Concatenating the empty symbol does not change a symbol" >>>> self assert: (#foo, emptySymbol) == #foo. >>>> self assert: (emptySymbol, #foo) == #foo. >>>> >>>> "Strings and symbols can still be mixed, the receiver determines the result type" >>>> "Symbol receiver gives symbol result" >>>> self assert: (#foo , 'bar') == #foobar. >>>> "String receiver gives string result" >>>> self deny: ('foo' , #bar) == #foobar. >>>> self assert: ('foo' , #bar) equals: #foobar. >>>> self assert: ('foo' , #bar) equals: 'foobar'. >>>> >>>> >>>> Those last two seem contradictory. >>> >>> No, Symbols and String can be used interchangeably in Pharo in lots of contexts. Particularly when comparing them, it makes no difference, all the following are/have always been true, independent of this change: >>> >>> #foo = 'foo' >>> 'foo' = #foo >>> #foo = #foo >>> 'foo' = 'foo' >> >> Ah-ha... gotchya. always something more to learn. >> >> So those last three lines a testing that it is a String? >> This meaning is pretty well hidden in the implicit behaviour. >> Why not just... >> self assert: (#foo , 'bar') isString >> which seems to better "says what it means" >> >> If such is poor form in general, >> I'm curious to what degree such rules may be relaxed for unit tests. >> Could it be considered something like premature optimisation >> to make the test too generic?? If isString latter causes a problem later, >> deal with it then. >> >> ==== >> On another slightly different point, >> this might be one case where #assert:#equals is less clear than using "=" >> >> Its also easy to mis-think the following is contradictory >>>> self deny: ('foo' , #bar) == #foobar. >>>> self assert: ('foo' , #bar) equals: #foobar. >> >> where the alternative here makes the distinction more clear... >> self deny: ('foo' , #bar) == #foobar. >> self assert: ('foo' , #bar) = #foobar. >> >> >> cheers -ben > > |
Free forum by Nabble | Edit this page |