[Closed] difference between filein() and include()?
Hi,
I’ve been chasing an error for an hour or so with functions not being declared when I include them in another .ms file and include() them into my main script. I then stumbled across filein() and that fixed my problems.
I don’t quite understand the documentation on include and filein, my reading of the include documentation is that it would have declared my functions as it simply places the included script into the main script at evaluation time.
My script works fine using filein() but I’m just interested as to why it didn’t work using include().
Sounds like a scope issue. Does the script work if you physically place the included code in the editor?
did you place your functions scripts in “stdplugs\stdscripts” folder?
placing them there as I understand it loads them on startup
Nope, however I know the path is correct as I can run the include command from the listener and it returns the contents of the file.
Placing them in stdplugs\stdscripts may work, but I’d need to restart max each time I change the included functions.
cheers
ben
Cannot tell without seeing the source, but the general difference is this:
Imagine you have one script.
Now you open another script, select all its content, press Ctrl+C to copy into the Clipboard.
Now you go to the first script, place the mouse pointer ANYWHERE between the comands of your code and press Ctrl+V to paste the clipboard.
Well, INCLUDE() does exactly the equivalent of this, but in an elegant way. Whenver the first script is evaluated, any calls to INCLUDE() cause the source code from the referenced file to be pasted into the main code BEFORE evaluating. So it is like a programmable Copy&Paste, allowing you to split the source into pieces and put them back together at evaluation time. Anything that gets “pasted” is evaluated in the scope of the code it is pasted into.
Now imagine you have one script that wants to call some functions from another script.
You go to MAXScript>Run Script in the menu, and pick the second file containing those functions. As result, the code inside the picked file get evaluated. Then you evaluate the first script and it is able to see any global functions or variables defined in the second script.
Well, fileIn() does exactly what MAXScript>Run Script menu does – it simply loads the code of the specified file and evaluates it in the global scope just like when running a script or opening a script and pressing Ctrl+E. It does not matter that the fileIn() call is placed in another script – the two scripts have nothing to do unless both are trying to use the global scope for communication.
Hi,
I don’t think it’s a scope issue, as filein() works fine. Its seems that include() works just as bobo says, copying the text into the script. however it’s not actually declaring any of the functions.
here’s an example.
write and save (but don’t evaluate) these two scripts.
script_one.ms – worded as follows :
function print_func1 =
(
print “FUNCTION is declared – include worked ! “
)
script_two.ms – worded as follows :
function print_func2 =
(
print "FUNCTION is declared - filein worked ! "
)
now run the following code :
include “$scripts\BenCowell\script_one.ms”
filein “$scripts\BenCowell\script_two.ms”
(you’ll need to edit the path for your script folder)
type print_func1() and you’ll get an error, it’s not been declared
type print_func2() and all should be fine.
What I’m trying to understand is why the include doesn’t evaluate the text it brings across from script_one.ms
cheers
ben
To get this to work make a third file:
– strart script_three.ms:
include “$scripts\BenCowell\script_one.ms”
filein “$scripts\BenCowell\script_two.ms”
– end script
It needs to be run and not evaluated. When it is evaluated it just prints script_one.ms contents to the listner but doesn’t actually execute it. Or atleast that was my experience.
According to the Reference (that portion was written by John W. back in 1997),
include() can be used either to get some text from an external file INTO the Listener WITHOUT EVALUATING IT, or to get the source into another file (the case we are talking about) AND EVALUATE IT.
So include() in the Listener is NOT the same as include() in a source .MS file.
When you evaluate a source file containing includes, these will also be evaluated.
When you call include() in the Listener, all that happens is that the code is pasted (but not evaluate) into the Listener.
When you type in “include” in the MAXScript Reference > Index tab, you will get two topics:
The first one is “Including Scripts Within Scripts”.
[left]MAXScript provides a compile-time source-file include mechanism, allowing you to break up large scripts into smaller files that can be included at nearly any point in a script. You can use the include <file> construct at any point in your code to effectively insert the contents of a file at that point in your code.
[/left]
[left]The form is:
[/left]
[left]include “filename_string”
[/left]
[left]
[/left]
[left]This is a compile-time construct, therefore the file name specification must be a string literal, and not a variable or an expression.
[/left]
[left]The include <file> construct is effectively replaced in the source code at that point with the contents of the named file.
[/left]
[left]You can nest included files as deeply as needed; included files can include other files, and so on.
[/left]
[left]Because include is a compile-time construct, the current MAXScript scope is maintained within the included file. This is opposed to the fileIn() method described in Running Scripts, whose script file content is compiled in a global scope context. For more information, see Scope_of_Variables.
[/left]
[left]The include <file> can appear at any point a new token is expected, such as a name, literal, or punctuation. This means that you could complete a partial expression with an included file.
[/left]
The second topic is related to Listener selections and also says the following:
[left]include <filename_string>
[/left]
[left]Inserts the specified files content into the Listener output pane. The inserted text is not evaluated. You can use this method to load a script and then step through it, executing any selected text with SHIFT+ENTER. <filename_string> is a string literal or an expression that evaluates to a string, and specifies the name of the file to insert.
[/left]
Hi Ben i thing you are missing
filein “$max\Scripts\BenCowell\script_two.ms” instead of filein “$scripts\BenCowell\script_two.ms” i what i use on my code and doesnt give me any problem.
.
I always used filein in my scripts, always use it on my macros so the macro is calling a external .ms file and dont have to relaunch max everytime I change a macroscript.
Can you bobo explain de advantage or disadvantage or using filein and global scope on the scripts.
I think with include you could use global on front of your variables to get them as a global scope is this right??? are all the variables inside the include are declare as local scope. What i try to do in my script is have variables with the scriptname at the beginning to avoid problems of variables in two script calld the same ,example: like Sp-value.
Is a bad abbit to use filein or if you take care with your variables names is not a problem.
thanks for your previous explanation good as always.
Read my first post in this thread. I used a comparison to copy and paste which explains what happens technically when using the one and the other.
fileIn() does not do anything to the variables. It just takes the whole source code and evaluates it as if it was called via MAXScript>Run Script.
So if the content of the file SomeScript.ms was something like
(
local a = 10
print a
)
nothing will become global, except that the whole script will create a local scope BELOW the global scope. print a will correctly print 10, but if you would try to type in ‘a’ in the Listener , it would return undefined because it was NOT defined in the global scope.
Now if you would have a file AnotherScript.MS file containing
a = 10
print a
and would fileIn() this code, the variable ‘a’ would become global implicitly because there is no other scope defined anywhere and fileIn() works in global scope. Type in ‘a’ in the Listener and you should get 10.
If the same code would be INCLUDED into another script like this,
(
include "AnotherScript.ms"
)
the result would be a LOCAL a = 10 inside the scope defined by the script that called include().
You get the picture?
I use both, mostly fileIn() when I want to make sure that some set of functions my code will need to call are actually declared already.
I use include() to split the source code into smaller manageable pieces or replace portions of the code with version-specific chunks (like ActiveX vs. DotNet controls being inserted depending on which Max version is calling the script).
There is nothing wrong in using either, as long as you understand what you are doing and what is happening when you do it.
Thanks bobo know i understand it better , so i will try to use filein only when is needed, thank for the long reply that makes me understand it better.