V9.18β6No.10951
秀丸担当 さん 22/08/25 16:11
 
V9.18β6を公開しました。

以下のページの「先行開発バージョンはこちら」からダウンロードできます。
https://hide.maruo.co.jp/software/hidemaru.html

32bit版:
https://hide.maruo.co.jp/software/bin3/hm918b6_signed.exe

64bit版:
https://hide.maruo.co.jp/software/bin3/hm918b6_x64_signed.exe

[ ]
RE:10951 V9.18β6No.10955
こみやんま さん 22/08/25 20:58
 
非同期の例ですが、fetch は狙いはわかりますが、
最初の例としてはちょっと適切さが欠けるかと。

・isMacroExecuting
・postExecMacroFile

多分ほとんど全ての人(例え秀丸マクロ習熟者であったとしても)
秀丸マクロの中に非同期が出てきた時の癖は理解できてないハズですので、

isMacroExecuting とかはマクロファイル内に「マクロが実行中の判定??」とかお
もっちゃうかとw

元々がC++やC#の中で、さらにfreedllせず、
常駐するタイプのdll中で使用する目的で誕生した判定が、
isMacroExecutingのようなものでした。

それらの作成者は、isMacroExecutingの意味するところや、
true/false 時に何が違うのかは理解しているでしょうが、
それが以外の人は理解が難しいように思えます。

さらに言えば、どうしてもファイルが一体(.mac)になっている傾向があるjsmodeでは、
「は? 日本語でOK」っと思ってしまうように思えます。

少なくとも、以下あたりのサンプルを間に挟む必要があるかと

====== test1.mac =======================================

jsmode "WebView2";

js{

    function MethodInAsinc(dir) {
        try {
            // この中では非同期中になるため、直接はhideamruGlobal内のプロパ
ティが指す関数実態は使えない。
            // なぜならマクロが終わっているため。jsmodeやそれに類似したもの
を実装したことがない99.99%の人にとってここが一番通じにくい。
            // message("OK"); ← よってこれはだめ
            // hidemaruGlobal.message("OK"); ← これもだめ

            console.log("Start MethodInAsinc...");

            if (hidemaru.isMacroExecuting() ) {
                console.log("マクロ本体が実行中です");
            } else {
                console.log("現在スクリプトは非同期処理中です。マクロ本体は
終了しています。");
            }

            console.log(cmdir + "\\abc.mac");
            hidemaru.postExecMacroFile(cmdir + "\\test2.mac");
        } catch(e) {
            console.log(e.message);
        }
    }

    debuginfo(2);
    console.log("スタート");
    cmdir = currentmacrodirectory(); // 非同期の中で使うため、秀丸の変数とし
て保持しておく
    setTimeout(MethodInAsinc, 2000);
    console.log("マクロ終了直前");
}


====== test2.mac =======================================



[ ]
RE:10951 変数防御がバグってるというかマNo.10956
こみやんま さん 22/08/25 22:07
 
・まず全ての秀丸エディタ、常駐を終了

・秀丸エディタ起動
・以下のマクロを実行
--------------------------以下のマクロ実行
jsmode "JScript", 1;

js{
    var str = str(3);
    message(str);
}

「オブジェクトを指定してください」とエラー


・str変数が悪いのか? と以下のマクロに修正

--------------------------以下のマクロ実行
jsmode "JScript", 1;

js{
    var str3 = str(3);
    message(str3);
}

「オブジェクトを指定してください」とエラー

とエラーは変わらず。

[ ]
RE:10956 変数防御がバグってるというかマNo.10957
こみやんま さん 22/08/25 22:34
 
同様に、以下もJScript版ではエラーになっています。

----------------------------------------
jsmode "JScript", 1;

js{

function abc() {
    var str = str(3);
    debug("OK");
}

abc();

}

----------------------------------------

ローカル変数は、元の定義に影響を与えないため、防御するべきではありません。

防御するべきは、「元々の定義が書き換えられて、復活しない」からであって、
その関数内で「一時的に見えなくなる」のは問題ないとするべきです。

一方、jsmode-WebView2版の方は、投稿させてもらった内容に近い実装がされており、
この辺は適切な塩梅で機能していると思います)

[ ]
RE:10957 変数防御がバグってるというかマNo.10958
こみやんま さん 22/08/25 22:39
 
jsmode "WebView2", 1;

js{

function abc() {
    let str = str(3);
    console.log(str);
}

abc();

}

------------------------------------------------
こういうのもローカル変数はエラーを出すべきではありません。

守るべきはあくまでも「元の関数を書き換えてしまう」からであって、
一時的に見えなくしていることまで防御すると、
世の中の str , result, x などを「ローカル変数」として
使っているライブラリ全部書き換えないと駄目みたいになってしまいます。

[ ]
RE:10958 変数防御がバグってるというかマNo.10959
こみやんま さん 22/08/25 22:51
 
とおもったら、エラーが出るのは指定のものについて、「右に関数名、左に関数名と
同じ変数名」で受け取った時だけですかね?

以下みたいなのは、最後のところだけ、例のdefineProperty で守られててるから、
これなら大丈夫という気がしますね。

jsmode "WebView2", 1;

js{

function abc() {
    let str = x();
    console.log(str);
}

abc();

var str = x(); // ここはdefineProperty でエラーで守られてる
}



[ ]
RE:10955 V9.18β6No.10960
秀丸担当 さん 22/08/26 09:50
 
setTimeoutで別関数の例はわかりやすくていいですね。
JavaScriptは、非同期といってもシングルスレッドなのではないかと思います。
なのでそれほど変なことは起きないと思います。

他のプロセスでのマクロ実行の影響は、なんとかできたらいいです。
jsmodeは、他のプロセスに切り替えできない制約がデメリットだったのですが、逆に
それをメリットとして、閉じた空間上で複数のプロセスで同時実行できてもいい気が
してきました。
例えば、postExecJS()で1プロセス限定とか、秀丸ファイラーClassicのように先頭
にプロトコル風の"js:"プレフィクスを付けたら最初から1プロセス限定モードで実
行とか…
ちょっといま思いついた程度で実現可能性はわかりませんが。

長引きそうな場合V9.18はいったん現在のマクロでできるところまでに留めて、次の
バージョン番号とかにするかもしれません。

[ ]
RE:10959 変数防御がバグってるというかマNo.10961
秀丸担当 さん 22/08/26 09:53
 
グローバルでvarを書くかどうかで違いがあるとは知りませんでした。
そうなると、ちょっと困りますね。
それで違いが出るのはJScript, Chakra, IE系の、MicrosoftのJavaScriptの特性とい
う気がします。(たぶん)
関数の中でのvarは、そこまで細かい制御はできないです。
IEはあまり知られていないだけでずっと問題だったのだろうし、この場末の秀丸エデ
ィタ上の話でそれを詰めても仕方ないんじゃないかと思います。

せめて書き換えられたものかどうか判別できればいいのですが、str()やlineno()の
中を参照しようとすると文字列プロパティとして"function..."みたいのを返すよう
にしてみたので、判別が難しくなってしまいました。
やっぱり単なるネイティブのメソッドとして、参照はエラーとなるようにしようと思
います。
エラーにしたくない場合は、事前にtypeofで判別して見ないようにしたり、書き換え
られたか判別できそうです。

[ ]
RE:10960 V9.18β6No.10962
こみやんま さん 22/08/26 10:48
 
>長引きそうな場合V9.18はいったん現在のマクロでできるところまでに留めて、次の
>バージョン番号とかにするかもしれません。

そうですね、変数保護のところで、記述していく上でマズイ感じでなくなれば
現状程度で一度(JavaScript部分は)リリースに向けていっていいかと思います。

確かに、非同期問題というよりは、実際には
@秀丸マクロエンジン
AJavaScriptエンジン
両者のライフサイクルの違い、

@とAの両方が有効な「時間」と、
Aだけが有効な「時間」

で挙動が違い、
Aだけの時は、使える道具に結構制限がある、ということを
理解してもらうのが結構あれだなーといったところですかね。
(node.jsやブラウザ.jsなどには存在しない制限なので)

以前、hmJavaVMの時に図解で作った
https://xn--pckzexbx21r8q9b.net/?page=nobu_tool_hm_javavm_process

のJVM ⇒ jsmode と読み替えたようなことを理解してもらう必要があるところが難点
ですね。

図の(秀丸マクロ)青と(jsmode)茶が重なるところがhidearmuGlobalが使えるところと
なる。
より実情を言うなら、evalMacroで実装されているメソッドは青と茶が重なるところ
のみで使える。
evalMacroで実装されているメソッドは、ほぼhidemaruGlobalに集まっている、とい
うのが正しいですか...

ただ、この辺はある程度プログラミングの心得がある部類に入る人だけが
やる感じだと思うのでまぁ、ボチボチでいいかと思います。

[ ]
RE:10951 V9.18β6No.10963
こみやんま さん 22/08/26 10:56
 
JavaScript の hidemaru に
「Hidemaru.exe 本体」にも提供されているもの相当の

@hidemaru.getT***e();
Ahideamru.getL***e();

がありますが、これは非公開でいきますか?

getT***e の方は、すごく使用機会が多いのでマクロ経由しない版があっていいかなーと
思っていたのですが。

[ ]
RE:10963 V9.18β6No.10964
秀丸担当 さん 22/08/26 15:08
 
hidemaru.getTotalTextUnicodeとhidemaru.getLineTextUnicodeのことかと思います。
Hidemaru_GetTotalTextUnicodeとHidemaru_GetLineTextUnicodeなどは、プロセス依
存で秀丸メールで使えないということもあったので、ここらへん一式が揃っていたら
いいかもしれないと漠然と思っていました。
全部揃っていなくて、いまのところ公開とも思っていなかったですが、メソッドの存
在がばれてしまったということで、たぶん単純なもので仕様も変わらないだろうし、
公開としてもどちらでもいいです。

[ ]
RE:10964 V9.18β6No.10965
こみやんま さん 22/08/26 19:59
 
>メソッドの存在がばれてしまったということで、たぶん単純なもので仕様も変わら
>ないだろうし、公開としてもどちらでもいいです。

もし公開されるということであれば、
@hidemaru.getTotalText(): string
Ahideamru.getLineText(lineno: number): string

と「Unicode」というのは関数名から取り除いてしまうのが良いかと思います。
(C-APIの名前がそんな感じだったから、という経緯を知らない人は、
 何か「js内部コードと違う文字コードで来るのか?」と一瞬よぎっちゃうと思うので)


[ ]
RE:10951 JSから exitやquit系関数 ⇒ 怪No.10966
こみやんま さん 22/08/27 23:43
 
タブモードとかの時に、JavaScript から exit 系列の関数を呼び出すと、裏でダイ
アログが出て操作ができなくなりやすいようです。

なんとなくですが、
「st」系列(Statement系列)の関数群では、
evalの結果としての「result」が取れることが前提の作りになっていますが、
exit系列だとマクロ空間の破棄かなにかの都合上、resultが取れなくて
内部的にエラー起こすんじゃないかと。

(jsmode とそっくりな関数群を hmJSやhmV8やhmPython3に移植してみたところ、同じ
ようなところが「ちょっとこれタイミングとか大丈夫なの?」と思った感じでしたの
で)


[ ]
RE:10951 V9.18β6No.10967
こみやんま さん 22/08/28 13:14
 
・getresultex
・getconfig
・geteventparam
・member

は、秀丸マクロにおいて、返り値の型が変化するめずらしい関数(jsmodeではfsnタイ
プ)ですが、
これらを dll に(引数で受け取らず)直接渡した際に、 Hidemaru_GetDllFuncCalledT
ype で渡ってくる型情報が適切ではありません。

秀丸マクロの仕様として、これらの関数は恐らくは、
「代入文の左の変数の要求型  #か$か」を見て決めているため、
仕方ない仕様かな?
とも長年思っていましたが、
普通に考えて、どちらの型なのかは、値を返そうとする段階ではわかっているのでは
ないかと思っています。

そこで今回の「もうちょっと正しい情報を渡せるのではないか?」という要望となり
ます。
 

■現在不具合に思えてしまう具体例

dll側
-------------------------------------------------------
#include <windows.h>
#include <string>

using namespace std;

extern "C" __declspec(dllexport)
intptr_t _cdecl test(intptr_t n, wchar_t* pwsz) {

    HINSTANCE hinstExe = GetModuleHandle(NULL);

    using TpfnHidemaru_GetDllFuncCalledType = int (WINAPI*)(int n);
    TpfnHidemaru_GetDllFuncCalledType pfnHidemaru_GetDllFuncCalledType = NULL;
    pfnHidemaru_GetDllFuncCalledType = (TpfnHidemaru_GetDllFuncCalledType)Ge
tProcAddress(hinstExe, "Hidemaru_GetDllFuncCalledType");

    int paramType1 = pfnHidemaru_GetDllFuncCalledType(1); //第1パラメータの
型を表示
    wstring s2 = L"第1引数" + to_wstring(paramType1);
    ::MessageBoxW(NULL, s2.c_str(), L"", NULL);

    return 1;
}
-------------------------------------------------------

#dll = loaddll(currentmacrodirectory + @"\dll3");

#r = dllfuncw(#dll, "test", getconfig("Font"));
// getresultex
//getconfig
//geteventparam
//member

freedll(#dll);

-------------------------------------------------------

上の例では 「getconfig("Font")」の返り値の型は、文字列型(フォント名)ですが、
Hidemaru_GetDllFuncCalledType では数値型だよ、といった情報で渡ってきます。

$font = getconfig("Font");

と書き分けなければならない理由がちょっと判然としません。
getconfig("Font")の段階で返り値は「文字列型」と分かっているのではないかと思
うのです。

(fsn=hidemacJsGlobalFomulaSorN が微妙にとりまわしわるいのもこのあたりか...)


・getresultex
・getconfig
・geteventparam
・member
の4つの「返り値の型が状況や引数で変化する関数について、」
dllの引数にそのまま(変数に受け取ることなしに)渡したとき、
その引数の型を、Hidemaru_GetDllFuncCalledType において
正しく(少なくとも正しいと思われるものを)伝えることは可能でしょうか。




------以下は本題からそれる話でずらずら記載してますが、自分的にはどうでもいい
話... ----------

本題からはそれますが
いくつかの秀丸の文や関数で、例えば、messageなどで

 ```
 message getconfig("Font")
 ```

などと出来ているのは、いくつかの関数が
JavaScriptでいうところの st1s, st1s2s fn1s fn1s2s として定義されており、
そういったものに含まれる、message関数は内部的に第1引数と第2引数については、
$$$=getconfig("Font")みたいな「文字列型としての受け取り仲介処理」を挟むことで
「元来は上手くはいかない処理」を、うまくいくようにパッチを当てているからだと
思っています。

実際に、そのような特別な処理が当たっていない文や関数、
例えば、

 ```
 title getconfig("Font")
 title -1;
 ```
 ではうまくいかず、

 ```
 $t = getconfig("Font")
 title $t;
 title -1;
 ```
 と分ければ上手くいく、という「messageで上手くいってtitle上手くいかないとは
これ如何に?」という不思議な状態なわけです。



[ ]
RE:10966 JSから exitやquit系関数 ⇒ 怪No.10968
秀丸担当 さん 22/08/29 09:51
 
ご指摘ありがとうございます。
exit系の文は、終わってしまうのでresultの以前にjs内で使えてしまうこと自体がよ
くありませんでした。
hidemaruGlobalやグローバルに展開するサポートの範囲からは外すように変更しよう
と思います。

[ ]
RE:10967 V9.18β6No.10969
秀丸担当 さん 22/08/29 10:36
 
getconfig等は確かに数値でも文字列でもありの、そういう方式になっています。
事前に知ることができるかどうかは、不可能ではないと思いますが、いまから仕様を
変えるのもよくないと思います。
既に行われているように、事前に文字列型変数に入れるなどをして型を確定させてお
けば大丈夫なので、そういう方法で回避してほしいです。

[ ]
RE:10961 str は String のショートカットNo.10970
こみやんま さん 22/08/29 13:12
 
変数防御のやつですが、x だの result だのは、
「いかにも一時変数に使いそうだし、秀丸独自機能も提供している」
ので、守る趣旨もわかりますが、
str とかは、JavaScript の String 「関数兼オブジェクト」機能のうち「数値だ
け」しか提供していないので、

「守るなら、せめてString の別名としてstr(そこそこ価値あるものにする)」

にしてはどうでしょうか。

HidemacJSGlobal あたりで、str = String みたいにする。

var a = str(1.33); // "1.33";
var b = str(true); // "true";

var c = str({"a":3}) // "{object Object]

Stringがあるのでぶっちゃけ特に守る必要もないというか、
変数名抑制してまで str って要るのってレベルだと思います。


[ ]
RE:10970 str は String のショートカットNo.10973
秀丸担当 さん 22/08/29 16:45
 
Stringはstrとほぼ同じような感じでも使えるのですね。
全く同じであればよかったですが、整数化やtrueが違うということのようで、やめて
おこうと思います。
グローバルに展開するのは、今までのマクロをできるだけそのままに近い形にできれ
ばいいと思います。
JavaScript寄りの書き方では、グローバル展開せずにstrの書き換えでも自由にして
もらえればいいです。

[ ]