REBOL 3 Docs | Guide | Concepts | Functions | Datatypes | Errors |
TOC < Back Next > | Updated: 13-Aug-2010 Edit History |
Copies a series or object.
Arguments:
value [series! port! map! object! bitset! any-function!]
Refinements:
/part - Limits to a given length or position
length [number! series! pair!]
/deep - Also copies series values within the block
/types - What datatypes to copy
kinds [typeset! datatype!]
See also:
The copy function will copy any series, such as string! or block!, and most other compound datatypes such as object! or function!. It is not used for immediate datatypes, such as integer!, decimal!, time!, date!, and others.
This example shows what happens if you don't copy:
name: "Tesla"
print name
Tesla
name2: name
insert name2 "Nicola "
print name2
Nicola Tesla
print name
Nicola Tesla
That's because, it's the same string:
same? name name2
true
Here's the example using copy for the second string:
name: "Tesla"
print name
Tesla
name2: copy name
insert name2 "Nicola "
print name2
Nicola Tesla
print name
Tesla
same? name name2
false
The same behavior is also true for blocks. This example shows various results:
block1: [1 2 3]
block2: block1
block3: copy block1
append block1 4
append block2 5
append block4 6
probe block1
[1 2 3 4 5]
probe block2
[1 2 3 4 5]
probe block3
[1 2 3 6]
There will be times in your code where you'll want to append to or insert in a string or other series. You will need to think about what result you desire.
Compare this example:
str1: "Nicola"
str2: append str1 " Tesla"
print str1
Nicola Tesla
print str2
Nicola Tesla
with this example that uses the copy function:
str1: "Nicola"
str2: append copy str1 " Tesla"
print str1
Nicola
print str2
Nicola Tesla
It is fairly common to copy just a sub-string or sub-block. To do so, use the /part refinement. The length of the result is determined by an integer size or by the ending position location.
name: "Nicola Tesla"
copy/part name 6
"Nicola"
copy/part skip name 7 5
"Tesla"
copy/part find name "Tesla" tail name
"Tesla"
Notice that the ending position can be a length or a position within the string (as shown by the tail example above.)
If you use other languages, you will notice that this result is similar to what a substr function provides. Although we recommend using copy with /part, you can easily define your own substr function this way:
substr: func [arg [series!] start length] [ copy/part skip arg start length ]
For example:
substr "string example" 7 7
"example"
We should explain why we don't normally define a substr function. Most of the time when you're extracting substrings, you are either using a function like find or you're using a loop of some kind. Therefore, you don't really care about the starting offset of a string, you only care about the current location.
For example:
str: "This is an example string." str2: copy/part find str "ex" 7
And, in fact, it's common to write use two find functions in this way:
start: find str "ex" end: find start "le" str2: copy/part start end
which advanced users often write in one line this way:
str2: copy/part s: find str "ex" find s "le"
Of course, if the string might not be found, this is a helpful pattern to use:
str2: all [ start: find str "ex" end: find start "le" copy/part start end ]
If the start or end are not found, then str2 is set to none.
Here's an example of a simple loop that finds substrings:
str: "this example is an example" pat: "example" while [str: find str pat] [ print copy/part str length? pat str: skip str length? pat ]
When copying blocks, keep in mind that simple use of the copy function does not make copies of series values within a block.
Notice that the copy here does not copy the name string:
person1: ["Tesla" 10-July-1856 Serbian]
person2: copy person1
insert person/2 "Nicola "
probe person1
["Nicola Tesla" 10-July-1856 Serbian]
If you need to copy both the block and all series values within it, use copy with the /deep refinement:
person1: ["Tesla" 10-July-1856 Serbian]
person2: copy/deep person1
insert person/2 "Nicola "
probe person1
["Tesla" 10-July-1856 Serbian]
probe person2
["Nicola Tesla" 10-July-1856 Serbian]
Here both the block and the string are separate series.
Also be aware that if your block contains other blocks, they will be deep copied as well, including all strings and other series within them.
If you want to deep copy only a specific datatype, such as just strings or just blocks, you can use the /types refinement.
Here are a few examples of its usage:
copy/deep/types block string! copy/deep/types block any-string! copy/deep/types block make typeset! [string! url! file!]
If you use copy on an object, a copy of the object is returned. This can be useful when objects are used only as simple storage structures. Note that rebinding is not done; therefore, do not use copy on objects when that is required.
To see a list of functions that modify their series (not copy), type this line:
? modifies Found these related words: alter function! If a value is not found in a series, append i... append action! Inserts a value at tail of series and returns... bind native! Binds words to the specified context. (Modifi... change action! Changes a value in a series and returns the s... clear action! Removes all values. For series, removes from ... decloak native! Decodes a binary string scrambled previously ... deline native! Converts string terminators to standard forma... detab native! Converts tabs in a string to spaces (default ... encloak native! Scrambles a binary string based on a key. (Mo... enline native! Converts standard string terminators to curre... entab native! Converts spaces in a string to tabs (default ... insert action! Inserts into a series and returns the series ... lowercase native! Converts string of characters to lowercase. (... ...
TOC < Back Next > | REBOL.com - WIP Wiki | Feedback Admin |