Closed AndersDeleuran closed 6 years ago
Hi Anders
you noticed that variables in general stick within globals from one iteration into the other once they are declared, right? This is because the editor is connected to one single interpreter, and does not reset its environment all the time. This allows the scripter to check previous variables, etc.
However, in the case of the variable name of the inputs or outputs, I'd agree that this can be considered a bug. After all, the user did not add that variable, so might expect that variable to disappear. I'll add this to the list of things to work on, thanks
I think so. Once a variable is declared it will remain in globals. Even after the variable no longer exists in the script or it has been renamed. The only way to get rid of the "phantom variable" is to go:
del variableName
Alternatively close/open the Grasshopper definition. It is not a major problem, but can lead to debugging issues not revealed until you close/open the definition. Moreover no other Python environment I have used (including the regular EditPythonScript editor) displays this behaviour.
/Anders
Yes, I will consider this suggestion and would like to hear more people's opinion. About other environments, I think it's more a perspective. Like this, what we have is just a Python interpreter that is running, and that is attached to another (Grasshopper) interpreter via its variable names. The Python interactive interpreter definitely displays this behavior. See http://blog.datasingularity.com/?p=134 for an example
Alternatively, we could:
for uniquevar in [var for var in globals().copy() if var[0] != "_"]:
del globals()[uniquevar]
I do not really have a preference myself, as all these options have advantages and disadvantages. For some advanced usages, 1. is best for advanced usages, 2. is often more practical, and 3. allows to do some operations like counters in a very easy way. :)
Hi Giulio,
I see that you clearly have given this a lot more thought than I had :)
Didn't consider how having variables stick around might actually be seen as a feature (case in point for counters etc.).
Would say to just leave it as is for now. I understand that you guys are working on consolidating the programming environments for Grasshopper. So I'm sure there are much more important issues to deal with.
Thanks for the thorough reply,
Best,
Anders
I will close this for now, mark it as "Needs testing" -- and will still like to hear your and everybody else's impression on this. You, me or everybody else might also just reopen the case once we feel this is slowing down too many people or is too counterintuitive. Thanks,
Giulio
Giulio Piacentino for Robert McNeel & Associates giulio@mcneel.com
I vote for number 3. It could be even wrapped in a method similar to what MATLAB has as clear (http://www.mathworks.com/help/matlab/ref/clear.html).
I agree that applying number 1 is tricky since many of the beginner users has no idea about the concept of Class and Function and I think it is a good feature to let them script for awhile without knowing that concepts.
Perhaps simply adding a button or a menu item to the editor for flushing any unused phantom variables would be an option. Guess this is kind of like suggestion 3, but with handy gui functionality ;)
I've been wondering about this for a while. I'm a fan of 2, because it is the closest match to the default behavior when running a python module. I've been assuming so far that the default behavior, (option 3) was a bug that would be eventually fixed. I would expect the python interpreter to be connected to the Grasshopper solution, in the sense that a grasshopper solution re-runs the python module written in the grasshopper component, with fresh globals.
It seems like the question at hand is "what is the most intuitive and expected default behavior?". To me this is definitely 2. Though it apparently has interactive behavior, GhPython does not create the same interface that is used in other interactive interpreters, and instead appears to be a text editor that runs python modules. When running a python module, python is typically launched each time the module is run, with a fresh set of global variables. So option 2 is the closest to common python behavior.
Using the global scope to store variables across Grasshopper solutions or for data persistence seems like a messy strategy. There's plenty of ways to store data even if the scope is refreshed: the Rhino or GH documents, or writing to files.
It seems like the confusion of 3 outweighs the advantages I can imagine, while 2 seems like a very straightforward expected behavior. Could 3 be turned on with a switch, with 2 as the default behavior?
Now that I read @bengolder's comment I think I also agree that number 2 is more close to what a Grasshopper user would assume. I like the option of having a switch for number 3, and having 2 as the default behavior.
Another vote for 2 as default behaviour. I as well assumed that refreshing the grasshopper component would reset the global variables, because that's the behaviour I'm used to with other python editors.
I'm a little confused now about what exactly each ghPython component is. Is it correct to say they are each self-contained editors that share a single Python interpreter?
I am considering an addition to the current behavior to solve this.
Unless we find that it is a bad decision for some other reason, I think this proposal will match both expectations without needing special options. When the user just Tests or Runs the script from the editor, the scope is cleared of all variables. When the script is repeated automatically, to update the solution, nothing special happens.
This will avoid the problem of referencing a name from an old version of the script, and allow to see values across updates. Will this work for you?
(to answer the interpreter question) Rhino only contains one interpreter (it would be very wasteful if it contained many) that is shared by all editors. The editor is just a viewer of text. The "text" code is run in different scopes. This is why you can use modules from the Rhino editor in Grasshopper and viceversa, and share objects via sticky, for example.
@piac sounds like a really good idea. I also tried your suggestion to remove the global vars. The only issue was that it also removes ghenv which I had to take care of. Except that it does what I need. Thanks for the great work!
@piac that solution makes sense to me.
Also thank you for answering my question re: the interpreter. So are these the scopes we have to be aware of?
@saeranv There are lots of scopes in Python. The content of a function creates a scope. A module is in its own scope. So variable names don't get mixed up. http://stackoverflow.com/questions/146359/python-scope
There can be an undefined number of nested scopes. In the big picture, it is not the editor that defines scopes. It's modules that do that. You can think of any editor window as its own "module", just with no physical location on the hard drive. I hope this helps,
Giulio
@piac thank you! This is great.
I agree. This looks like a really good solution. Thanks again Giulio..
@piac Thanks for patiently explaining all this. It helps a lot.
I have been wondering about this one for some time now actually. If you create a variable, run the script and subsequently delete the variable. The variable still exist in globals().
Is this by design? If so, is there a good reason for this that I might be missing? If not, I propose this issue be considered a bug.
Thanks again for all the hard work,
Anders