ZBrushCentral

Scope in routines

I’ve got a routine that will reverse a string - or in this case correctly print “Hello Word!” forward from it’s reverse, as is my want.

Can I just check a couple of things, Marcus?

In order to return a parameter from a funct… I mean routine, you have to define it first and refer to it in the routine when returning.

Secondly what difference does the # make in loop?

Here’s my code:

// Define variable outside button scope
[VarDef, s, “!dlroW olleH”]

// Define routine here
[RoutineDef, reverse_string,

// Define an empty string
[VarSet, rev, “”]

// reverse the string
[VarSet,i,[StrLength,#s]-1]
[Loop,[StrLength,#s],

[VarSet,rev,[StrMerge,rev,[StrExtract,#s,i,i]]]

[VarDec,i]

]

// Set the routine paramater to the new string
[VarSet, s, rev]

// return parameter here
,s] // End of Routine

[IButton, “Reverse string”, “Reverse that string!”,

[Note, s] // forward
[RoutineCall, reverse_string, s]
[Note, s] // reversed
]

Thanks

By declaring the ‘s’ variable globally you’re not using scope in your example (except with the ‘rev’ variable). You could remove the routine parameter and it would still work:

// Define variable outside button scope
[VarDef, s, “!dlroW olleH”]

// Define routine here
[RoutineDef, reverse_string,

// Define an empty string
[VarSet, rev, “”]

// reverse the string
[VarSet,i,[StrLength,#s]-1]
[Loop,[StrLength,#s],
[VarSet,rev,[StrMerge,rev,[StrExtract,#s,i,i]]]
[VarDec,i]
]

// Set the routine paramater to the new string
[VarSet, s, rev]

// return parameter here
] // End of Routine

[IButton, “Reverse string”, “Reverse that string!”,

[Note, s] // forward
[RoutineCall, reverse_string]
[Note, s] // reversed
]

If a variable is global - declared outside any code blocks - then it’s available anywhere. It’s not good practice to declare a global variable and then declare it again as a routine parameter. You’ll get errors sooner or later.

For a variable to be local you should not declare it outside the code block:

// Define variable outside button scope
[VarDef, inStr, “!dlroW olleH”]

// Define routine here
[RoutineDef, reverse_string,

// Define an empty string
[VarSet, rev, “”]

// reverse the string
[VarSet,i,[StrLength,#s]-1]
[Loop,[StrLength,#s],
[VarSet,rev,[StrMerge,rev,[StrExtract,#s,i,i]]]
[VarDec,i]
]

// Set the routine paramater to the new string
[VarSet, s, rev]

// return parameter here
,s] // End of Routine

[IButton, “Reverse string”, “Reverse that string!”,

[Note, inStr] // forward
[RoutineCall, reverse_string,inStr]
[Note, inStr] // reversed
]

The hash # is just used to indicate a variable. It’s just coding style - it can make the code easier to read - and is ignored by ZBrush.

HTH,

Thanks Marcus.

Local good. Jam good. Four legs good. Two legs bad. Got it :slight_smile:

I don’t suppose there’s a way in ZScript to determine if a variable is local or global??

[Note [x in global], 2]

Not directly, that I can think of, though simply using

[Note, [Var, myVariable]]

inside a button will give an error if the variable ‘myVariable’ isn’t available.

But for your own code you can adopt a code style that names global variables beginning with a ‘g’ and local with an ‘l’, such as gMyGlobalV and lMyLocalV.

Thanks, teach.

[VarDef, a, “a”] // global

[IButton, “Local & Global”, “Local & Global”,

[VarDef, b, “b”] // declared inside button, local
// [VarDef, c, “c”] // commented out - not declared at all

[Note, [Var, a]] // “a”
[Note, [Var, b]] // “b”
[Note, [Var, c]] // error
]

:+1: That’s it. :slight_smile:

Also:

[VarDef, a, “a”] // global

[RoutineDef,ReturnC,
[VarSet,c,“Hello, I’m c!”]
,c]

[IButton, “Local & Global”, “Local & Global”,

[VarDef, b, “b”] // declared inside button, local

[Note, [Var, a]] // “a”
[Note, [Var, b]] // “b”
//[Note, [Var, c]] // c is local so would give error

[RoutineCall,ReturnC,b]
[Note, [Var,b]] // b now has a copy of c

]

You sir, are a gentleman and a scholar!