この件についてはすでに JMP サポートに連絡しており、バグとしてマークされています。 これは、このバグが見られる単純な「実際の」ケースです。
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
私はスクリプトのごく一部を暗号化する必要があるスクリプトに取り組んでいたので、変数がリークする可能性を最小限に抑えるために、暗号化する必要があるコードの大部分を単一の関数内にラップしていました(この場合、私はそのように怠け者です) )。 この非常に大規模な単一関数を作成しているときに、すべての変数が定義されているにもかかわらず、For Each ループ内で「引数の値が無効です」エラーが発生していることに気付きました。 いくつかのテストを行ったところ、for each (および他の each ループ) が Default Local を正しく処理していない (またはそのように見えた) ことがわかりました。 以下に 2 つの例を示します
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();
私はまだそれらを持っていないので、これを(今のところ)自分の制作スクリプトに任せることができることを(密かに)誇りに思っています(しかし、私は役に立ち、将来の私のために少なくともそこにケース番号を追加しました)。
dt = dt; // don't remove, it just works (JMP Support Case 00075244)
これに関して、JMP 開発者に連絡した JMP サポート担当者から次のような返答を受け取りました。
これは、Function Default Local と Each 関数の間の不適切な相互作用のように見えます。 失敗したテストは次のとおりです。
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])
));
defloc は関数本体に表示される非修飾名であるため、デフォルトのローカルとしてマークされます。 これは、シンボルに書き込むと JMP が自動的にローカルを作成することを意味します。 ただし、上記のスクリプトのようにそこから読み取る場合は、ローカル フレームをスキップして、次のフレームに進み、Here と Global まで進む必要があります。 これは予期された動作であり、Each 関数の外側で defloc を読み取った場合に得られる動作です。 しかし、Each 関数内を読み取ると、何らかの理由でこのプロセスが中断されます。 おそらく、 Each 関数はローカルも持つことができるため、別のフレーム自体を導入するためです。
dt = dt は、Default Local を完全に回避するための回避策です。