2

Here, I have attempted to set the value of a global variable from inside a function, but the value has not changed:

setGlobalScope: func [theVar1] [
    theVar1: 10
]

theVar: 1

setGlobalScope theVar

print theVar
"This prints 1 instead of 10. The value of theVar has not changed."

Is it possible to modify the value of a function's parameter from inside the function itself, so that the value is modified within the global scope instead of the function's scope?

Anderson Green
  • 30,230
  • 67
  • 195
  • 328

3 Answers3

4

You passed an integer value, not a word. Within the function, the word theVar1 is assigned the value of that integer. Reassigning it doesn't change it, because values like integers and dates and decimal numbers aren't "pointers" under the hood.

Hence, the answer from @sqlab where you can get around this by various ways of getting the word itself. The difference between function ['x] [code] and function [:x] [code] may interest you as an aside...

Why doesn't Rebol 3 honor quoted function parameters that are parenthesized?

But note that series values in Rebol do have modifying functions that affect the target, vs. just reassignment of where the word points. Consider:

setGlobalScope: func [theVar1 [string!]] [
    clear theVar1
    insert theVar1 "Modification"
]

theVar: "Original"

setGlobalScope theVar

print theVar

That prints Modification.

If you need to pass non-series values by reference, you need to put them in a series and use series modification operations instead of assignment. Because an assignment would just overwrite the "pointer" you have to the block or whatever. Worst case scenario you can wrap a single value in a block--if you must. But Rebol has a lot of "wait, look at it this other way..." where dialecting comes to the rescue in creating a better interface than that thing you were trying to clone from another less cool language. :-)

Mitigating the complexity of passing by reference is Rebol's simplicity at handling multiple return results:

foo: function [value1 value2] [
    return reduce [
        value1 + 7
        value2 + 16
    ]
]

set [a b] foo 03 04

print a
print b

That outputs 10 and 20.

Community
  • 1
  • 1
3

By using a combination of lit-word and get-word there is more than one way.

e.g

>> setGlobalScope: func ['theVar1] [set :theVar1 10]
>> theVar: 1
== 1

>> 
>> setGlobalScope theVar
== 10

>> 
>> print theVar
10

and

>> setGlobalScope: func [theVar1] [set :theVar1 10]
>> theVar: 1
== 1

>> setGlobalScope 'theVar
== 10

>> print theVar
10
sqlab
  • 6,412
  • 1
  • 14
  • 29
0

I think you can just modify your variable theVar directly in your setGlobalScope funct.

iArnold
  • 333
  • 2
  • 10