Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly happened when not using "copy" to deal with a string?

Tags:

rebol

rebol3

The purpose of the function below is to return a string having inserted the argument value between two stars.

star-name: func [name /local stars] [
    stars: "**"
    insert next stars name
    stars
]
print star-name "test" ;*test*
print star-name "this" ;*thistest*, but what I really want is *this*  

The second time I call the function, the argument of the first call still remains inserted. I know the answer is to use copy "**". My question is, doesn't it reassign the stars variable to "**" every time the function is called?

like image 870
Wayne Cui Avatar asked Aug 09 '13 07:08

Wayne Cui


People also ask

Can you ignore Settingswithcopywarning?

One approach that can be used to suppress SettingWithCopyWarning is to perform the chained operations into just a single loc operation. This will ensure that the assignment happens on the original DataFrame instead of a copy. Therefore, if we attempt doing so the warning should no longer be raised.

What is setting with copy warning?

This is what the warning is telling us. 'A value is trying to be set on a copy of a slice of a dataframe'. We discussed above that Pandas can either create a view or a copy when we are trying to access (get) a subset of an operation.

What does copy on a DataFrame do?

Pandas DataFrame copy() Method The copy() method returns a copy of the DataFrame. By default, the copy is a "deep copy" meaning that any changes made in the original DataFrame will NOT be reflected in the copy.


2 Answers

In the case of the function there is just one "**" string definition. That definition is used by Rebol load function just once, since load is run just once to translate the code to Rebol internal form - a block. It is true that the assignment occurs twice if you call the function twice, but the assignment does not create anything, it just makes the variable refer to the same string again.

In your comment you should notice that you actually have two "**" string definitions leading to two strings being created by load. If you use

code: [stars: "**" insert next stars something]
something: "this"
do code
something: "that"
do code

you will notice that there is just one string definition and while you do not have any function the behaviour is the same as it was when a function was used.

like image 134
Ladislav Avatar answered Oct 24 '22 01:10

Ladislav


If you use a set-word on a series, then the default behavior is to allocate the memory for that series just the once. This allows you to use that as a static variable that persists between function calls as you have found.

If you don't want that behavior, then you need to explicitly copy the series to create a new series each time.

This is another way you can do this as the stars local is not required

star-name: func [ name ][
  rejoin [ "*" name "*" ]
]
like image 40
Graham Chiu Avatar answered Oct 24 '22 01:10

Graham Chiu