PDA

View Full Version : Why does this work in the script editor and not in mel?


robchis
06-20-2007, 04:58 AM
I need to take a string of an array, and make it the value of an integer array that I declare.

print "\nstart\n";
string $a = "{1,2,3}";
int $b[];
eval("$b="+$a);
print $b;
print "stop\n";



While this works fine in the Script Editor, producing an output of start
1
2
3
stop
in mel, the array isn't made... I just get an output of
start
stop and the size of the array is obviously zero.

Why is this happening?:sad:

Robert Bateman
06-20-2007, 09:36 AM
because when you source a file it add's {} around the code, $b therefore becomes a local var. Try executing this in the script editor, and you will see the same results.


{
print "\nstart\n";
string $a = "{1,2,3}";
int $b[];
eval("$b="+$a);
print $b;
print "stop\n";
}

I will say that what you are doing is a truly distgusting thing to do with code however..... you could just do it cleanly like so:


string $buffer[];
$numTokens = `tokenize "{1,2,3}" "{}," $buffer`;
int $b[];
for( $buff in $buffer )
{
$b[ size($b) ] = $buff;
}
print $b;

alexnardini
06-20-2007, 10:22 AM
Is like within a MEL scrip MAYA can not recognize the array variable $b[] anymore,
as it will be erased.

In a test I did, I declared $b[] as Global Int Variable and everything went witn no problems,
but probably declaring $b[] as Global is not what you are looking for...

By the way,
below a simple proc test:


global proc test(string $aa)
{
print "\nstart\n";
global int $bb[]={};
eval("$bb="+$aa);
print $bb;
print "stop\n";
}

test("{1,2,3}");

robchis
06-20-2007, 10:37 AM
Well, the reason why I'm trying to do this is that I have an external text file that contains the populated array in the form of
{1,2,3,4}
And using the fgetline function, I was hoping to easily assign the contents of that text file, the array that's in the form of a string, to the array variable.

Despite the "ugliness" of the code, I thought it would be simple to initialize the array variable, make a string of the assignment of that array data from the text file, and then turn it into the real thing using the "eval" call.

The fewer lines of code, the better, right?

Robert Bateman
06-20-2007, 04:33 PM
In a test I did, I declared $b[] as Global Int Variable and everything went witn no problems,
but probably declaring $b[] as Global is not what you are looking for...

Arrrgh! My comment about this being truly disgusting still holds. Type

print `env`;

see your global at the bottom? Do you know how to get rid of it? Anychance one of your scripts might use the variable $b? How about $i? Know what happens when you do:

int $b;
string $b;

????

Save yourself a lot of trouble and avoid globals at all cost. In this case there really is no need to be doing this. It is a hardcoded non-generic horror of a solution.


proc int[] makeIntArrayFromString(string $s)
{
string $buffer[];
tokenize $s "{}," $buffer;
int $b[];
for( $buff in $buffer ) $b[ size($b) ] = $buff;
return $b;
}

{
int $a[] = makeIntArrayFromString("{1,2,3}");
print $a;

int $b[] = makeIntArrayFromString("{1,2,3,55,66,2345,22}");
print $b;

int $c[] = makeIntArrayFromString("{1,2,3,4,5}");
print $c;

int $d[] = makeIntArrayFromString("{1,2,3,4,5,6,7}");
print $d;

int $e[] = makeIntArrayFromString("{1,2,3,4,3,2,1}");
print $e;

int $f[] = makeIntArrayFromString("{1,2,3,4,5,6,7,8,9}");
print $f;
}


It's generic, reusable, and does not generate globals all over the place

alexnardini
06-21-2007, 12:47 AM
Robert Bateman,
obviously your solution is more elegant but you did not answer to the original question,
even if the orginal example as you said, is disgusting.

The point was'nt how we can write in a better way the original code, but
since the same code, should produce the same result without or within the brackets,
why we are getting different result?

As soon a piece of code and it's variables are typed, declared and used within the brackets,
they will exist and the evaluation should be identical to the same code without the brackets, did you know this?

alexnardini
06-21-2007, 04:30 AM
By the way,
I was still curios in why it not produce the same result and playng a bit
during some free time today, a test come up that work in both case,
does not use Global Variables and following the opening thread
is based on the same disgusting code.. :)


print "\nstart\n";
string $a = "{1,2,3}";
int $b[];
evalEcho("$b="+$a);
evalEcho ("print $b");
print "stop\n";


...and the bracket version:


{
print "\nstart\n";
string $a = "{1,2,3}";
int $b[];
evalEcho("$b="+$a);
evalEcho ("print $b");
print "stop\n";
}


Now,
the original example from Robchis was producing the correct result anyway,
even if the output was obviously looking wrong.

The below example is exactly the same as the code posted originally from Robchis
with the exception of the "evalEcho" command instead of the "eval" command,
just to monitoring what really is store inside there, and surpraisingly,
the array is correctly created but not correctly evaluated from the "print" command.

Executing the below code, we will get the correct output from the "evalEcho" command
even if the final otuput coming from the "print" look wrong:


{
print "\nstart\n";
string $a = "{1,2,3}";
int $b[];
evalEcho("$b="+$a);
print $b;
print "stop\n";
}


The output will be:


start
$b={1,2,3};
// Result: 1 2 3 //
stop


So, in the true the array is stored correctly but not correctly read from the "print"...strange...

trancor
06-21-2007, 04:52 AM
sorry to say, but it seemed to me that robchis wanted a little more cleanlyness in the print. If robchis wanted

$b={1,2,3};
// Result: 1 2 3 //

Printed in the script editor, robchis wouldn't have put the nice a neat start and stop in the code.

evalEcho isn't needed in this case, all that needs to be done is eval

eval("$b="+$a);
eval("print $b");


and brackets are just the propper way of formating mel, I've been a javascripter most of my life and phping for a long time and now that I get to mel, I script the same way and there isn't a difference with or without the {} before and after all of the code

robchis
06-21-2007, 04:53 AM
Thanks for your help, everyone! I'm still trying to get mel wired, and with out you, it'd be a nightmare!

alexnardini
06-21-2007, 05:05 AM
sorry to say, but it seemed to me that robchis wanted a little more cleanlyness in the print. If robchis wanted

$b={1,2,3};
// Result: 1 2 3 //

Printed in the script editor, robchis wouldn't have put the nice a neat start and stop in the code.
evalEcho isn't needed in this case, all that needs to be done is eval


Trancor,
no problem at all, you are absolutely right and in my example
"evalEcho" was used just for "debug",
obviously we have to use "eval" in order to have the cleanlyness Robchis was looking for.

But again, I'm still confuse as to why the script editor handles code fine and mel doesn't as well.

P.S.:
Rob, your solution was great,
no one complain about it, I was only complaining about the difference (in some case)
in the code evaluation between the ScriptEditor and a MEL script.

Robert Bateman
06-22-2007, 09:30 AM
P.S.:
Rob, your solution was great,
no one complain about it, I was only complaining about the difference (in some case)
in the code evaluation between the ScriptEditor and a MEL script.

There is only one difference between them. All variables declared outside of a scope in the script editor automatically get declared as globals. All vars in a script that gets sourced, get locally scoped to that script. You should always therefore write scripts in the script editor scoped by {}.

so in the script editor, this will generate an error :


{
int $a=10;
eval( "print $a;");
}


as this would in a script :


int $a=10;
eval( "print $a;");


which in effect, what it is doing is saying


{
int $a=10;
now_execute_the_following_code_as_another_script( "print $a;" );
}

which then executes the following on it's own:


print $a;


$a is therefore undefined because this code is executed outside of the scope of where $a was defined. The reason


eval("print " + $a);

works, is because it does not use the variable name, it executes:


print 10;

The same rules apply to any callback on a UI control (since it gets evaluated after the script has been run and all vars have fallen out of scope and been destroyed).

CGTalk Moderation
06-22-2007, 09:30 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.