# Why Can't This Procedure See This Variable?

**URL:** https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363
**Category:** Maya
**Tags:** mel
**Created:** [January 6, 2013, 12:28am UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363 "2013-01-06T00:28:21Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![darian-sizukhan](https://forum.highend3d.com/user_avatar/forum.highend3d.com/darian-sizukhan/32/54652_2.png) [@darian-sizukhan](https://forum.highend3d.com/u/darian-sizukhan)
#### Post date: [January 6, 2013, 12:28am UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363/1 "2013-01-06T00:28:22Z")

</div>

Hi, all. &nbsp;I'm pretty new to MEL, but I'm in the middle of making a GUI for one of my scripts, and I've been thoroughly stumped by this problem for hours now. &nbsp;Here is a simple recreation of what I'm trying to do:

```auto
{
    string $a = "hello";
    if (`window -exists myWindow`)
    {
        deleteUI myWindow;
    }
    window -title "Window" -widthHeight 100 100 myWindow;
    rowLayout -numberOfColumns 1;
    button -label "Press Me" -command "foo()" myButton;
    setParent ..;
    showWindow myWindow;
 
    proc foo()    
    {
        print($a);
    }    
    foo();
}
```

&nbsp;What's happening is that when foo() is called in the last line, it prints out $a ("hello") no problem. &nbsp;However, when the button's command calls foo(), nothing happens. &nbsp;In fact, sometimes when I was trying this before, it was printing random ascii characters. &nbsp;I even had multiple elements within the window simply try to print the variable's value (a checkbox and an optionMenu) with their command flags, and they printed different values even though nothing was changing the variable.

With some scope research, I found that using the brackets to enclose my entire script would make variables declared at the top of the script accessible to procedures throughout the script (something I thought would be possible by default), but even that's not working. &nbsp;The only solution I've found so far is to make the variable (in this case $a) global. &nbsp;I'd like to try to avoid making it global, but moreso than that, I'd like to know why calling foo() from the button is not printing "hello." &nbsp;Is there something about MEL's scope I'm not understanding, or is it something else?

---

<div class="post-metadata">

### Author: ![briankeffer](https://forum.highend3d.com/user_avatar/forum.highend3d.com/briankeffer/32/83_2.png) [@briankeffer](https://forum.highend3d.com/u/briankeffer)
#### Post date: [January 6, 2013, 12:54am UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363/2 "2013-01-06T00:54:55Z")

</div>

try this

if (`window -exists myWindow`)

{

deleteUI myWindow;

}

window -title "Window" -widthHeight 100 100 myWindow;

rowLayout -numberOfColumns 1;

button -label "Press Me" -command "foo()" myButton;

setParent ..;

showWindow myWindow;

global proc foo()

{

string $a = "hello";

print($a);

}

if you want $a to be a global var then you would haved to define $a as&nbsp; global var

string $a = "hello";

if (`window -exists myWindow`)

{

deleteUI myWindow;

}

window -title "Window" -widthHeight 100 100 myWindow;

rowLayout -numberOfColumns 1;

button -label "Press Me" -command "foo()" myButton;

setParent ..;

showWindow myWindow;

global proc foo()

{

global string $a;

print($a);

}

---

<div class="post-metadata">

### Author: ![darian-sizukhan](https://forum.highend3d.com/user_avatar/forum.highend3d.com/darian-sizukhan/32/54652_2.png) [@darian-sizukhan](https://forum.highend3d.com/u/darian-sizukhan)
#### Post date: [January 6, 2013, 2:10am UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363/3 "2013-01-06T02:10:29Z")

</div>

Thanks for the response!

I need the variable accessible by more than one proc, so the first option wouldn't work (unless I don't fully understand global procs which is a real possibility). &nbsp;In that case, $a would be specific to foo(), right, or does making the proc itself global make all of its variables global as well?

I guess I just don't understand why anything needs to be global. &nbsp;It doesn't make sense to me why I can't reference a variable in a proc that's been declared above the proc in the code, especially when I have brackets surrounding the entire script. &nbsp;I thought those outer brackets extended the scope of variables defined within them to be accessible by anything else within the brackets WITHOUT allowing access to the variables from, say, other scripts (which would happen if I made the variables global, right?).

---

<div class="post-metadata">

### Author: ![joojaa](https://forum.highend3d.com/letter_avatar_proxy/v4/letter/j/5daacb/32.png) [@joojaa](https://forum.highend3d.com/u/joojaa)
#### Post date: [January 6, 2013, 6:20am UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363/4 "2013-01-06T06:20:07Z")

</div>

> I guess I just don't understand why anything needs to be global.

Computer programs work on stacks, when a procedure exits its stack gets cleaned away. Otherwise the computer would massively leak memory. The global part is just the lowest stack that gets cleaned out when the programming environment is cleaned up. The local variables will cease to exist once the procedures are run. They no longer exist anywhere, they will be recreated next time such things happen.

having global variables is a bit tricky, since you might by mistake use a variable used somewhere else without you knowing.

> > &nbsp; I thought those outer brackets extended the scope of variables defined within them to be   
> > accessible by anything else within the brackets WITHOUT allowing access to the variables from, say, other scripts

Yes but you see foo does nolonger exists. Its gone by the time you press the button. It died when the code was run (it died when your code hit the bracket). If you want to use it in a gui item and not have microsecond fast user interactions then globals are prettymuch the only way you can do this in mel. Mel is not realy a programming language.

Use python it works more like you think, if you use something like partial functions.

---

<div class="post-metadata">

### Author: ![darian-sizukhan](https://forum.highend3d.com/user_avatar/forum.highend3d.com/darian-sizukhan/32/54652_2.png) [@darian-sizukhan](https://forum.highend3d.com/u/darian-sizukhan)
#### Post date: [January 6, 2013, 1:58pm UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363/5 "2013-01-06T13:58:49Z")

</div>

So when I run the code from the MEL window, is Maya essentially just sourcing the procs for later use in the script (unless they're called in the script)? &nbsp;Is it what I'm trying to do not working because when I click the button, the proc is no longer a part of the script (no longer having access to the variables in the script), it's just being run on its own? &nbsp;I hope that question makes sense...

And yeah, I probably will convert this to Python later, but I'd like to try to understand MEL a little more before I do that 😛&nbsp;

---

<div class="post-metadata">

### Author: ![joojaa](https://forum.highend3d.com/letter_avatar_proxy/v4/letter/j/5daacb/32.png) [@joojaa](https://forum.highend3d.com/u/joojaa)
#### Post date: [January 6, 2013, 3:40pm UTC](https://forum.highend3d.com/t/why-cant-this-procedure-see-this-variable/363/6 "2013-01-06T15:40:10Z")

</div>

Kindof,its not actually sourcing anything yet. See the code:

```auto
button -label "Press Me" -command "foo()" myButton;
```

puts a string into the gui button this gets evaluated (using eval) when the button is pressed. Hence your code would work as follows, your code gets sourced and run. But the GUI lives beyond your code its still alive after your code so essentially you have a problem of type:

```auto
{
$a=10;
}
print($a);
```

which will obviously not work. It wouldn't work in any language there's just no hint for the computer to know that it should keep $a around (as in fact you explicitly told mel to thorw $a away). Since mel is simple, there's no mechanism for partially storing for future. But there is a mechanism for storing session wide. And that's using globals. So if you want anything to be remotely persistent you NEED to be global. You can then clean the stuff away later but remember others can see you now. (mel like python has no concept of privacy, everything you do is a open book to everybody else)

To be honest theres still 4 other ways to solve this. One is to store the value in the GUI (it may be hidden). In the evaled script, it can be later changed if you wish. In a node the node makes it possible to have scene wide persistence. In a optionvar for user level persistence.

PS: seems to me thet 90% of beginning mel users dont get this on their own without a hint. Even tough it SHOULD be evident form the use of quotation marks.
