J'ai déjà contacté le support JMP à ce sujet et cela a été marqué comme bug. Voici un simple cas "réel" où ce bug a pu être observé
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
Je travaillais sur un script dans lequel je devais en chiffrer une petite partie, j'enveloppais donc la plupart du code que je devais chiffrer dans une seule fonction pour minimiser les risques de fuite de mes variables (je suis paresseux comme ça dans ce cas ). En écrivant cette fonction unique excessivement volumineuse, j'ai remarqué que j'obtenais des erreurs "La valeur de l'argument n'est pas valide" dans ma boucle For Each même si toutes les variables étaient définies. J'ai fait quelques tests et compris que pour chacune (et pour chaque boucle) ne gérait pas correctement les paramètres locaux par défaut (ou cela semblait être le cas). Ci-dessous deux exemples
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();
Je suis (secrètement) fier de pouvoir laisser cela (pour l'instant) à mon script de production car je ne les ai pas encore eu (mais j'ai été utile et j'ai ajouté au moins le numéro de cas pour mon avenir).
dt = dt; // don't remove, it just works (JMP Support Case 00075244)
J'ai reçu une réponse à ce sujet de la part du personnel d'assistance JMP qui avait contacté le développeur JMP :
Cela ressemble à une mauvaise interaction entre Function Default Local et les fonctions Each. Voici un test échoué :
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])
));
Puisque defloc est un nom non qualifié qui apparaît dans le corps de la fonction, il est marqué comme local par défaut. Cela signifie que JMP crée automatiquement un local si nous écrivons dans le symbole. Cependant, lors de la lecture comme dans le script ci-dessus, il doit ignorer l'image locale et passer à l'image suivante et à la suivante jusqu'à Ici et Global. C'est le comportement attendu et celui que vous obtenez si vous lisez defloc en dehors de la fonction Each. Mais si vous lisez l’intérieur de la fonction Each, ce processus s’interrompt pour une raison quelconque. Peut-être parce que la fonction Each introduit elle-même un autre frame puisqu'elle peut également avoir des locaux.
Le dt = dt est une solution de contournement, tout comme le fait d'éviter complètement Default Local.