Rebol Talk Forum  |  Getting Started  |  Newbie Help  |  Topic: array problem
Pages: [1] Print
Author Topic: array problem  (Read 578 times)
lazi
Newbie
*
Offline Offline

Posts: 3


View Profile
array problem
« on: January 24, 2007, 04:20:09 AM »

Hi!

This is my first post here, so greetings to every member and especially to Carl!
I am working on Amiga OS4 with the 68k Amiga release of Rebol/View, but before I made this post tested the problem on the latest Win release V1.3.2 and it made the same results.

I have a problem with an array which is filled with poke.
The code is importing a csv text file and inserts a field name before each value after parsing it line by line.
The result should be an array which holds the lines of the csv as blocks.

The problem is that the resulting names array holds the last poked value on every indexes. However probe names/:i in the iteration prints each of the desired vaues.

Here is the contents of the test.csv file:

a1;b1;c1
a2;b2;c2
a3;b3;c3
a4;b4;c4
a5;a5;c5     


And the rebol source:

REBOL []

import: read/lines %test.csv
temp: array 6
names: array length? import
i: 0

foreach line import[

     i: add i 1
     film: parse/all line ";"

     poke temp 1 'nr
     poke temp 2 first film

     poke temp 3 'title
     poke temp 4 second film

     poke temp 5 'genre
     either none? film/3 [ poke temp 6 ""] [ poke temp 6 third film ]

     poke names i temp
     probe names/:i

]

probe names


Here is the output:

First the output of probe names/:i in the iteration

[nr "a1" title "b1" genre "c1"]
[nr "a2" title "b2" genre "c2"]
[nr "a3" title "b3" genre "c3"]
[nr "a4" title "b4" genre "c4"]
[nr "a5" title "a5" genre "c5"]

And after the foreach iteration the probe names shows this. Every item is holding the same value. Huh

[[nr "a5" title "a5" genre "c5"] [nr "a5" title "a5" genre "c5"] [nr "a5" title "a5" genre "c5"] [nr "a5" title "a5" genre "c5"] [nr "a5" title "a5" genre "c5"]]

Edit: simplify the data in the csv to be more easy to get the problem
« Last Edit: January 24, 2007, 05:44:05 AM by lazi » Logged
henrikmk
Jr. Member
**
Offline Offline

Posts: 50


View Profile
Re: array problem
« Reply #1 on: January 24, 2007, 06:02:21 AM »

The problem is that you've manipulated the same 'temp the entire time in the original 'foreach block for each element in the big block. When the end has been reached, you probe 'names for each line and get a different result for each line, which looks fine.

But in reality, you've inserted a reference to the same 'temp in each position in 'array, so you see the same block (the last one) in all entries.

Try adding a probe names right after probe names/:i and you'll see all elements change in 'names. :-)

You need to copy 'temp before poking it in names with poke names i copy temp.
Logged
henrikmk
Jr. Member
**
Offline Offline

Posts: 50


View Profile
Re: array problem
« Reply #2 on: January 24, 2007, 06:13:37 AM »

And now for inspiration: You can do this way more elegantly, because there are much easier ways to manage blocks in REBOL than poking and using indexes:

Quote

REBOL []

import: read/lines %test.csv


You have the data now, same as before. Then you parse it, which is also fine. But, instead you can create the lines by building the block like this:

Quote

reduce ['nr film/1 'title film/2 'genre any [film/3 copy ""]]


That's it! One line of powerful code instead of all that poking. :-) Try to figure out what the 'any part does. It does the same as in your own code.

Now onto the loop, so we can see it as a whole:

Quote

names: make block! []

foreach line import [
  film: parse/all line ";"
  append names reduce [
    'nr film/1 'title film/2 'genre any [film/3 copy ""]
  ]
]


Believe it or not, we're done. :-)
Logged
lazi
Newbie
*
Offline Offline

Posts: 3


View Profile
Re: array problem
« Reply #3 on: January 24, 2007, 07:38:30 AM »

But in reality, you've inserted a reference to the same 'temp in each position in 'array, so you see the same block (the last one) in all entries.
[...]
You need to copy 'temp before poking it in names with poke names i copy temp.

Yep!
That was my problem!
Thank you very much!

Still doesn't understand this 'reference' thing.
Why sets the same value to every 0->i indexes the poke names i temp?

Best regards
Logged
lazi
Newbie
*
Offline Offline

Posts: 3


View Profile
Re: array problem
« Reply #4 on: January 24, 2007, 07:43:52 AM »

foreach line import [
  film: parse/all line ";"
  append names reduce [
    'nr film/1 'title film/2 'genre any [film/3 copy ""]
  ]
]
[/tt]

Believe it or not, we're done. :-)
Quote

Beleive it or not, I started like this  Smiley
However this results a series of all data, but my need was an array filled with series, like this:

[[a b][c d][e f]]

Regards
Logged
henrikmk
Jr. Member
**
Offline Offline

Posts: 50


View Profile
Re: array problem
« Reply #5 on: January 24, 2007, 09:43:50 AM »

Quote
Yep!
That was my problem!
Thank you very much!

Still doesn't understand this 'reference' thing.
Why sets the same value to every 0->i indexes the poke names i temp?

It's a well known feature of REBOL, in that as much as possible, it doesn't copy information, but binds it.

I used the term reference, but it's not actually correct, sorry.

It's not really a reference or a pointer as in C, because there's no symbol involved. The block is simply situated at a specific memory location and that is enough to refer to it in REBOL. I know the gurus will have a more elaborate and correct explanation, as I don't entirely know the internals of REBOL. ;-)

This makes it possible to manipulate series (blocks, strings, etc.) directly inside a block and it will truly be changed everywhere it's bound to and this can help skip over cases where you'd need to treat the block as a separate variable.

For example:

Quote

>> a: ""
== ""

>> head insert a 5
== "5"

>> b: reduce [a a]
== ["5" "5"]


This shouldn't surprise you, because you'd expect the reduction to give the contents of 'a inside the block.

But: the two strings in the block are in fact the very same string! The same string stored in the same memory location, just represented in two different places in a block.

Now you can do this:

Quote

>> head insert a 1
== "51"

>> b
== ["51" "51"]


Notice that I didn't call 'reduce. I didn't redefine the block. The contents just change, because the contents have changed at the memory location, that both entries in the block are looking at.

We can actually prove this:

Quote

>> same? b/1 b/2
== true

>> same? a b/1
== true


Why is this a feature? Because it gives speed and leverage. :-) Using it more in depth allows you to skip variable maintenance and shorten your code.

But it can be difficult to manage. Let's redefine 'a:

Quote

>> a: "7"
== "7"

>> b
== ["51" "51"]


When 'a was redefined, the binding to that memory location was lost. The binding still exists inside the block though and you can reconnect it:

Quote

>> a: b/1
== "51"

>> head insert a 7
== "751"

>> b
== ["751" 751"]


As another feature, you can define a block and manipulate it in place without ever assigning a variable to it.

Quote

>> repeat i 5 [append [] i]
== [1 2 3 4 5]


Hope this helps a bit.
Logged
henrikmk
Jr. Member
**
Offline Offline

Posts: 50


View Profile
Re: array problem
« Reply #6 on: January 24, 2007, 09:54:25 AM »

Quote
Beleive it or not, I started like this  Smiley
However this results a series of all data, but my need was an array filled with series, like this:

[[a b][c d][e f]]

Well, the above example should work just fine, though I forgot about blocks inside blocks. append/only will help with this as it inserts the block as a block.
Logged
Pages: [1] Print 
Rebol Talk Forum  |  Getting Started  |  Newbie Help  |  Topic: array problem
Jump to:  

  
Quick Search...

Advanced search
  
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 02, 2008, 06:19:06 AM
Username: Password: Session Length:
  

News: 01-09-08

Alpha version of REBOL 3 has been released!


  
2311 Posts in 595 Topics by 4138 Members
Latest Member: Irrederwasy

  Rebol Talk Forum | Powered by SMF 1.0.9.
© 2001-2005, Lewis Media. All Rights Reserved.

RT design by Defiant Pc