Strange array behavior
[1/7] from: geza67:freestart:hu at: 21-May-2002 19:54
Hi REBOL-fellows!
Why does not properly work this code segment:
>> a: array/initial [3 2] [[]]
== [[[] []] [[] []] [[] []]]
>> append a/1/2 3
== [3]
>> a
== [[[3] [3]] [[3] [3]] [[3] [3]]]
Hmmm, I' ve expected at querying 'a :
== [[[] [3]] [[] []] [[] []]]
Maybe the prototype initial value is a reference not a true value?
OK, I tried it even this way:
>> a: array/initial [3 2] copy [[]]
Maybe that even 'copy has made only ONE copy and five references to it
in array 'a ?
Now, if I want to manipulate arrays with "appendable" empty
lists, I don't give initial values and change each occurrances of
'none to copy/deep [[]] and THEN append to the defined location.
Is this the best practice to overcome the seeming limitation of 'array
?
Best wishes:
Geza
[2/7] from: al:bri:xtra at: 22-May-2002 15:36
Geza wrote:
> Why does not properly work this code segment:
It's a bug in Rebol's 'array function. See my fix with new subject line.
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[3/7] from: dockimbel::free::fr at: 22-May-2002 0:51
Geza Lakner MD wrote:
> Hi REBOL-fellows!
> Why does not properly work this code segment:
<<quoted lines omitted: 6>>
> Hmmm, I' ve expected at querying 'a :
> == [[[] [3]] [[] []] [[] []]]
[...]
This should solve your issue :
>> a: array/initial [3 2 1] []
== [[[] []] [[] []] [[] []]]
>> append a/1/2 3
== [3]
>> a
== [[[] [3]] [[] []] [[] []]]
Regards,
-DocKimbel.
[4/7] from: joel:neely:fedex at: 21-May-2002 17:29
Hi, Geza,
Geza Lakner MD wrote:
> Hi REBOL-fellows!
> Why does not properly work this code segment:
<<quoted lines omitted: 4>>
> >> a
> == [[[3] [3]] [[3] [3]] [[3] [3]]]
It's working properly, just not intuitively! ;-)
What's happening is that the initial value consists of a reference
to an (initially) empty series. All of the elements of the new
structure are initialized to that same reference, per the meaning
of the /INITIAL refinement. However, since they are all referring
to the same series, mutations of that series are visible through
all of those references.
> Hmmm, I' ve expected at querying 'a :
> == [[[] [3]] [[] []] [[] []]]
<<quoted lines omitted: 3>>
> Maybe that even 'copy has made only ONE copy and five references to it
> in array 'a ?
You got it!
> Now, if I want to manipulate arrays with "appendable" empty
> lists, I don't give initial values and change each occurrances of
> 'none to copy/deep [[]] and THEN append to the defined location.
>
> Is this the best practice to overcome the seeming limitation of
> 'array ?
>
How about this:
>> a: copy/deep array/initial [3 2] [[]]
== [[[] []] [[] []] [[] []]]
which uses ARRAY/INITIAL to make a "prototype" structure, then lets
COPY/DEEP make all of the blocks unique, after which:
>> append a/1/2 3
== [3]
>> a
== [[[] [3]] [[] []] [[] []]]
-jn-
[5/7] from: ingo:2b1 at: 22-May-2002 0:34
Hi Geza,
Geza Lakner MD wrote:
> Hi REBOL-fellows!
> Why does not properly work this code segment:
<<quoted lines omitted: 7>>
>>
> == [[[3] [3]] [[3] [3]] [[3] [3]]]
<..>
> Now, if I want to manipulate arrays with "appendable" empty
> lists, I don't give initial values and change each occurrances of
> 'none to copy/deep [[]] and THEN append to the defined location.
>
> Is this the best practice to overcome the seeming limitation of 'array
> ?
Or you could patch the array function to copy series values before
initializing, maybe like this:
array: func [
{Makes and initializes a series of a given size. *PATCHED* (iho)
copy/deep's series values, so you can use it to initialize with blocks}
size [integer! block!] "Size or block of sizes for each dimension"
/initial "Specify an initial value for all elements"
value "Initial value"
/local block rest
][
if not initial [value: none]
rest: none
if block? size [
rest: next size
if tail? rest [rest: none]
size: first size
if not integer? size [make error! "Integer size required"]
]
block: make block! size
either not rest [
; changes \/ \/ \/
either series? value [
loop size [ insert block copy/deep value ]
] [
insert/dup block value size
]
; changes /\ /\ /\
] [
loop size [
block: insert/only block array/initial rest value
]
]
head block
]
And after that:
>> a: array/initial [3 2] [[]]
== [[[] []] [[] []] [[] []]]
>> append a/1/2 3
== [3]
>> a
== [[[] [3]] [[] []] [[] []]]
I hope that helps,
Ingo
[6/7] from: greggirwin:mindspring at: 21-May-2002 18:19
Hi Geza,
You correctly deduced that REBOL is giving you multiple references to the
same empty block when it builds the array. What about this as a solution?
>> a: compose/deep array/initial [3 2] [[(copy [])]]
== [[[] []] [[] []] [[] []]]
>> append a/1/2 3
== [3]
>> a
== [[[] [3]] [[] []] [[] []]]
--Gregg
[7/7] from: geza67:freestart:hu at: 23-May-2002 22:21
Hello Joel, Ingo, Nenad, Gregg and Andrew
Thank you all for your feedback and the different solutions to the
problem. Now I see that this was really a bug in 'array but the
circumvention of this problem is rather easy!
--
Bye,
Geza mailto:[geza67--freestart--hu]
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted
Librarian comment