Ya me comuniqué con el soporte de JMP sobre esto y se marcó como un error. Aquí hay un caso simple "real" donde se puede ver este error.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
f2 = function({}, {Default Local},
Summarize(dt, uniq_values = by(:sex));
all_sex_values = dt[0, "sex"];
//dt = dt; // don't remove, it just works
For Each({uniq_value}, uniq_values,
cur_sex_rows = Loc(all_sex_values, uniq_value);
show(all_sex_values, uniq_value, cur_sex_rows, dt); // dt goes poof inside for each
vals = Transform Each({val}, dt[cur_sex_rows, "age"], Output("List"), Char(val));
show(vals);
);
);
f2();
all_sex_values = {"F", "F", "F", "F", "F", "M", "M", "M", "F", "F", "F", "M", "M", "M", "M", "F", "F", "F", "F", "F", "M", "M", "M", "M", "M", "M", "M", "F", "F", "M", "M", "M", "M", "M", "F", "F", "M", "F", "M", "M"};
uniq_value = "F";
cur_sex_rows = [1, 2, 3, 4, 5, 9, 10, 11, 16, 17, 18, 19, 20, 28, 29, 35, 36, 38];
dt = ␀;
argument value is invalid in access or evaluation of 'Transform Each' , Bad Argument(dt[cur_sex_rows, "age"]), Transform Each/*###*/({val}, dt[cur_sex_rows, "age"], Output("List"), Char(val))
at line 15 in mypath
Estaba trabajando en un script en el que tengo que cifrar una pequeña parte, así que estaba envolviendo la mayor parte del código que tengo que cifrar dentro de una sola función para minimizar la posibilidad de que mis variables se filtren (soy así de vago en este caso). ). Mientras escribía esta función única excesivamente grande, noté que recibía errores de "el valor del argumento no es válido" dentro de mi bucle For Each a pesar de que todas las variables estaban definidas. Hice algunas pruebas y descubrí que for each (y otros bucles de each) no manejaban correctamente el local predeterminado (o parecía así). A continuación se muestran dos ejemplos.
Names Default To Here(1);
thing = Expr(
Summarize(dt, uniq_values = by(:sex));
all_sex_values = dt[0, "sex"];
For Each({uniq_value}, uniq_values,
cur_sex_rows = Loc(all_sex_values, uniq_value);
vals = Transform Each({val}, dt[cur_sex_rows, "age"], Output("List"), Char(val));
show(vals);
);
);
f1 = function({}, {Default Local},
thing;
);
f2 = function({}, {Default Local},
Summarize(dt, uniq_values = by(:sex));
all_sex_values = dt[0, "sex"];
//dt = dt; // don't remove, it just works
For Each({uniq_value}, uniq_values,
cur_sex_rows = Loc(all_sex_values, uniq_value);
show(all_sex_values, uniq_value, cur_sex_rows, dt); // dt goes poof inside for each
vals = Transform Each({val}, dt[cur_sex_rows, "age"], Output("List"), Char(val));
show(vals);
);
);
f3 = function({}, {all_sex_values, cur_sex_rows},
Summarize(dt, uniq_values = by(:sex));
all_sex_values = dt[0, "sex"];
For Each({uniq_value}, uniq_values,
cur_sex_rows = Loc(all_sex_values, uniq_value);
vals = Transform Each({val}, dt[cur_sex_rows, "age"], Output("List"), Char(val));
show(vals);
);
);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
Print("Thing Expr");
Try(thing, show(exception_msg));
Print("\!NThing Expr inside Function");
Try(f1(), show(exception_msg));
Print("\!NThing Function Only default local");
Try(f2(), show(exception_msg));
Print("\!NThing Function Only local list");
Try(f3(), show(exception_msg));
Close(dt, no save);
Names Default To Here(1);
my_val = 1;
my_func1 = function({}, {Default Local},
show(my_val);
);
my_func2 = function({}, {Default Local},
my_func1();
);
my_func22 = function({}, {Default Local},
my_func2();
);
my_func222 = function({}, {Default Local},
my_func = function({}, {Default Local},
show(my_val);
);
my_func();
);
my_func3 = function({}, {Default Local},
my_func1(); // even this goes null
For Each({z}, {"b","c"}, show(my_val));
);
my_func1();
my_func2();
my_func22();
my_func222();
my_func3();
Estoy (secretamente) orgulloso de poder dejar esto (por ahora) en mi guión de producción, ya que aún no los he tenido (pero fui útil y agregué al menos el número de caso allí para mi futuro).
dt = dt; // don't remove, it just works (JMP Support Case 00075244)
Recibí una respuesta sobre esto del personal de soporte de JMP que se había puesto en contacto con el desarrollador de JMP:
Esto parece una mala interacción entre la función local predeterminada y las funciones de cada uno. Aquí hay una prueba fallida:
ut test("EachLoop", "Default Local in Body Expr", Expr(
defloc = 5;
f = Function({}, {Default Local}, Transform Each({x}, 1::5, x*defloc));
ut assert that(Expr(f), [5 10 15 20 25])
));
Dado que defloc es un nombre no calificado que aparece en el cuerpo de la función, está marcado como local predeterminado. Esto significa que JMP crea automáticamente un local si escribimos en el símbolo. Sin embargo, al leerlo como en el script anterior, debe omitir el cuadro local y pasar al siguiente cuadro y al siguiente hasta Aquí y Global. Este es el comportamiento esperado y el que obtienes si lees defloc fuera de la función Cada. Pero, si lees dentro de la función Cada, este proceso se interrumpe por alguna razón. Posiblemente porque la función Cada introduce otro marco, ya que también puede tener locales.
dt = dt es una solución alternativa, al igual que evitar por completo el local predeterminado.