On Fri, Jan 30, 2015 at 6:32 AM, Ben Coman <[email protected]
<mailto:[email protected]>> wrote:
Yes. I just got back to looking at it and noticed the culprit was
printString. Now #printString --> #printStringLimitedTo: -->
#streamContents:limitedTo: which uses LimitedWriteStream that
should protect against such recursion.
However Array>>printOn: is...
self shouldBePrintedAsLiteral ifTrue: [self printAsLiteralFormOn:
aStream. ^ self].
self isSelfEvaluating ifTrue: [self printAsSelfEvaluatingFormOn:
aStream. ^ self].
super printOn: aStream
where #shouldBePrintedAsLiteral and #isSelfEvaluating
recursively call themselves - bypassing the protection of
LimitedWriteStream.
As an aside, Array>>shouldBePrintedAsLiteral seems identical to
Array>>isLiteral -- so is it redundant and the former be deprecated?
Now I don't quite follow the semantics of #isLiteral and
#isSelfEvaluating for Arrays.
a := #( 1 2 { 3 . 4 } 5).
a isLiteral. "true"
a isSelfEvaluating. "true"
b := { 1 . 2 . #( 3 4 ) . 5 }.
b isLiteral. "true"
b isSelfEvaluating. "true"
So can someone provide an example for an Array where #isLiteral
or #isSelfEvaluating are false ? Otherwise it seems it will
always take the first condition of Array>>printOn: .
An Array that contains anything that isn't literal. e.g.
{1@2}
{1@2} isLiteral => false
{{1@2} size. #(1@2) size} => #(1 3)
and now normally isSelfEvaluating should return true because
{{1@2} . #(1@2) } isSelfEvaluating
-> true
because 1@2 while not being a literal is still a cool object whose
representation represents it fully.
In pharo
{(1@2). (1 @ 2)} printString
->{(1@2). (1@2)} and not #(....#
cheers -ben
On Fri, Jan 30, 2015 at 9:23 PM, Nicolai Hess <[email protected]
<mailto:[email protected]>> wrote:
Quick and Dirty,
replace Array>>#printOn:
with
printOn: aStream
self class = Array ifTrue: [self
printAsSelfEvaluatingFormOn: aStream. ^ self].
super printOn: aStream
testObject := 'TEST'.
ref1 := { testObject. nil }.
ref2 := { ref1 }.
ref3 := { ref2 }.
ref1 at: 2 put: ref3. "note the reference loop this creates"
testObject pointersTo asString
works
2015-01-30 14:15 GMT+01:00 Nicolai Hess <[email protected]
<mailto:[email protected]>>:
Hi Ben,
i don't know exactly what is happening here, but (size vs.
inpsect)
testObject := 'TEST'.
ref1 := { testObject. nil }.
ref2 := { ref1 }.
ref3 := { ref2 }.
ref1 at: 2 put: ref3. "note the reference loop this creates"
testObject pointersTo size
-> 5
works. So, the problem is not in #pointersTo but
inspecting the result array has one or more recursive self
calls
to its elements.
2015-01-30 3:59 GMT+01:00 Ben Coman <[email protected]
<mailto:[email protected]>>:
I am revisiting my PointerDetective tool, which relies
heavily on ProtoObject>>pointersTo.
The example I recorded at the repository home page is
currently locking & crashing the image due to
#pointersTo being unable to handle the circular
reference. This "must" have been working on Windows
at least around August 2014, but I've been unable to
reproduce a working case since my Windows laptop died
and I've since moved to OSX.
On OSX, in a fresh image 40467 and latest vm 402, the
following crashes the image...
testObject := 'TEST'.
ref1 := { testObject. nil }.
ref2 := { ref1 }.
ref3 := { ref2 }.
ref1 at: 2 put: ref3. "note the reference loop this
creates"
testObject pointersTo inspect.
OSX Memory Monitor shows memory usage shoot from 50MB
to >500MB in a few seconds, then usually the image
crashes, but sometimes just hangs.
I've logged...
https://pharo.fogbugz.com/default.asp?14827
cheers -ben
--
best,
Eliot