Hi - While I’m sure everyone can give you an answer - it’s more useful to teach you how to answer these questions for your self.
Try right clicking with your cursor on asString and choose “implementors of” (it may have a slightly different name friending on Pharo version - or press “meta”-m. Do the same for printString and compare the results. Also, do the same using “senders of” (meta-n).
Most code in Pharo is explorable like this, and you can generally answer most questions by seeing his other code in the system interacts or uses what you are exploring.
Sent from my iPhone
On 13 Oct 2019, at 11:50, Samuel Teixeira Santos <[hidden email]> wrote:
Hi folks. I'm starting in Pharo studies by FUN Mooc. In Week 03, on An Overview of Essential Collections there is the example below:
days keysAndValuesDo: [:key :value |
Transcript print: key; nextPutAll: ' has '; print: value;
nextPutAll: ' days'; cr].
works too and in some Smalltalks is easily the most efficient approach, as it
does not construct any strings you have no other use for.
In Pharo, however, there is a reason to prefer
Transcript nextPutAll: (key asString, ' has ', value asString, '
days', String cr).
The reason is that in Pharo 7, Transcript is an instance of
and each public operation like #nextPut: or #print: locks the stream.
In fact we have
self critical: [self print: anObject; endEntry].
self nextPutAll: anObject asString.
self critical: [stream nextPutAll: aString].
self nextPut: Character cr.
self critical: [stream nextPut: aCharacter].
So the code I exhibited second (using #nextPutAll:) locks the Transcript *once*
ensuring that nothing else can be written between 'days' and cr, whereas both
versions you exhibited have a timing window between #show: and #cr where
another Smalltalk process could write something.
But you are asking about the difference between #asString and #printString.
So look up the definitions! In a Playground, type
and then Ctrl-m (for iMplementors). We see almost at once that
so that for numbers there is NO difference between the two (except a
little bit of
overhead for #asString). But we also see
"complicated code logically equivalent to"
^String withAll: self
Just for grins, the following interaction was with GNU Smalltalk.
st> #January asString
st> #January printString
st> 31 asString
st> 31 printString
Pharo does exactly the same.
On Sun, 13 Oct 2019 at 23:51, Samuel Teixeira Santos
<[hidden email]> wrote:
> Hi folks.
> I'm starting in Pharo studies by FUN Mooc.
> In Week 03, on An Overview of Essential Collections there is the example below:
> | days |
> days := Dictionary new.
> at: #January put: 31;
> at: #February put: 28;
> at: #March put: 31.
> days keysAndValuesDo:
> [ :k :v | Transcript show: k asString, ' has ', v printString, ' days'
> ; cr ]
> The code in blue I change for
> days keysAndValuesDo:
> [ :k :v | Transcript show: k asString, ' has ', v asString, ' days'
> ; cr ]
> And works too on Playground.
> There is something different about both? There is someone better than other?
> Thanks in advance,
> Samuel T. Santos
> printString... v asString... There is something different about both?
I will add that conceptually:
- #printString = what a developer would want to see, e.g. in an inspector
- #displayString = a string suitable for UI (i.e. in production)
- #asString - while typically implemented to be the same as #printString,
the meaning for me is a bit different, which is "what this object converted
to a string means in my domain"
That said, IMHO as a community we are not great about properly
distinguishing these, especially #displayString.
I like the way you put because it's a nice way to remember and to teach too.
I'm just bit confusing, and I think this because Object Oriented it's not one of my strong skills, when you say when: "what this object converted to a string means in my domain" - what really means, specially about when you say 'domain'?
On Mon, Oct 14, 2019, 08:49 Samuel Teixeira Santos <[hidden email]> wrote:
when you say when: "what this object converted to a string means in my domain" - what really means, specially about when you say 'domain'?
Could you give some example for this?
A good example might be PLU codes  on produce in North America. They're 4 or 5 digits, and employees of a grocery store usually know them by heart (they're in the "employee of a grocery store" domain). Customers, however, are interested in knowing what the vegetable or fruit is, not the code.
So, depending on the application domain, #asString might print the code (for grocery store employees) or the name of the item (for customers).
Delving deeper, we find these codes even contain info about whether produce is GMO, organic, etc. which could also be used by #asString depending on requirements.
One thing I don't recall seeing in this thread is a discussion of the semantics of the methods names.
I find it helpful to consider #asWhatever to be a conversion method, used to convert one object to another essentially compatible class. e.g. #asFloat sent to an integer would be expected to yield a floating point number with the same value, but #asInteger sent to a floating point number would lose precision but might still be sensible for some purposes. [more on this below]
But, #printString and its ilk (#displayString, #storeString, others) are not intended to be conversion methods. They are to provide an external representation of a format suitable for the intended audience. Typically, (and I say that guardedly), #printString's intended audience is the programmers working on the system and #displayString is intended for the system's users.
In simple cases, #printString is reversible and can be parsed to recover the value of the original object. In general, it doesn't include enough information to do so. The same is true of #displayString. If we consider a slightly more complex example than a number, consider a User Profile. Its #printString might be 'UserProfile(John Doe)'. Its #displayString might be 'John Doe'. Neither of those provide all the details of the object, although they could be parsed and so used to look up an existing object.
[more on this below] above...
I find #asString is one of the most problematic methods that I have ever seen. It is deceptive, an "attractive nuisance", as one colleague liked to say. Clarity comes from being explicit in one's programming. Say what you mean and mean what you say. If you are trying to convert from one object form to another, use a conversion method whose name is precise. If you are trying to provide information for a programmer about an object, #printString is the choice.(e.g. in a stack dump).
As a general rule, #asWhatever methods that are generally applicable to the set of possible values. e.g. number conversion methods are a good example, even though there are exceptions (loss of precision, NaN, and Inf are some).
I have seen a lot of #asWhatever methods added to the String hierarchy, but almost all of them are dubious, in my opinion of course. Most strings are not numbers, for example. String>>#asNumber is one of the worst things I have ever seen, both from a consistency perspective and an implementation perspective. 'abc123def456' asNumber has more variant results than I can enumerate.
On Mon, Oct 14, 2019 at 9:28 AM Samuel Teixeira Santos <[hidden email]> wrote:
Very clear to me now.
Thank you and to others too by your previous answers
It may be worth noting that the 1998 ANSI Smalltalk standard defines
Character, <readableString>, String, and Symbol and for those classes only.
VisualWorks extends #asString to things like Filename and URIs and Text and
several other things for which "convert to String" makes sense and are not
locale-dependent. VW does *not* extend #asString to Object.
Visual Age Smalltalk *does* define Object>>asString ^self printString
but overrides this so that nil asString => ''.
Put it this way: if you use #asString for anything that is not some
kind of text or
some kind of 'locator' having an externally defined representation which can
be converted back to an equal 'locator' (file name, URI, network host name,
X11 font, ISO country currency or language code), don't expect your code to
be even close to portable.
On Wed, 16 Oct 2019 at 00:13, Samuel Teixeira Santos
<[hidden email]> wrote:
> Hi Richard.
> Very useful your considerations. I find too the messages like #asWhatever, like you said, were about type conversions, similar like we have in other languages.
> #printString and the others remember me the special method in Python __str__ or __unicode__ which allow change the default representation of object you dealing of.
> Thank you, I will pay attention when dealing with this messages