変奏現実

パソコンやMMORPGのことなどを思いつくまま・・・記載されている会社名・製品名・システム名などは、各社の商標、または登録商標です。

この画面は、簡易表示です

パソコン

[JavaScript]Promise

Promiseオブジェクトの作り方には大きく2つある。

  1. new Promise( )
  2. Promise.resolve( )

new Promise( ) は、新たにオブジェクトを作るけど、Promise.resolve( ) の方はstaticなPromiseオブジェクトを使いまわししているだろう。

class Promise {
    constractor () {
    ・・・
    }
    static staticResolve = new Promise().resolve(undefined);
    resolve() {
      if (typeof(this) === "undefined") {
        return Promise.staticResolve;
      ・・・
    }
}

と考えると、Promise.resolve( ) はpromise状態が履行 (fulfilled)に確定しているところから始まるから

Promise.resolve().then( (a)=>{
    /* なんたら */ 
}).then( (b)=>{
   /* かんたら */
}).then( (c)=>{
   /* それから */
}).then( (d)=>{
   /* こうして */
}).then( (e)=>{
   /* こうなった */
}).catch((e)=>{
   /* どうして、そうなった? */
});

と書いても、「なんたら」部の最後まで進めば、直ぐに「かんたら」に突入し、ストレートに「こうなった」まで進んで一気に進むので、完全な同期処理である。

単に、try…catch…finally なんて美しくないという人向けでしかない。

ただ、ドコが壊れているのかイミフなコードを切り分けた状況のエビデンスを作る時には非常に便利である。

実際には<% try { %><% throw(“ココか?”); %> <%} catch(e) {consol.log(e); } %>式に

プローブ針を垂らすけど、エビデンスとしては判りにくいからね。

強いて言えば、「なんたら」「かんたら」「それから」「こうして」「こうなった」の全てにawaitで強制的にワーカースレッドを停止させる箇所が無いと意味が無いのだ。

そんな訳で、非同期で処理したいものを1つづつ、「非同期化」するしかないが、そう難しくはない。

class hoge {
    // 非同期型 同期型と同じ数だけ作成する
    asyncFunc(params) {
    return new Promise((resolve, reject) => {
        try {
            let result = syncFunc(params);
            resolve(result);
        } catch(e) {
            reject(e);
        }
    });
    }
    // 同期型
    syncFunc(params) {
        return foo;
    }
    ・・・ 
}

と非同期呼び出し口を用意するだけ、

しかし、async接頭子のメソッドがいっぱい増えるのが嫌なら

class hoge {
    // 非同期型 1つだけ作って使いまわし。※毎回 new Promise しなくていいのが嬉しい。
    asyncCall(syncFunc,params) {
    return new Promise((resolve, reject) => {
        try {
            let result = syncFunc(params);
            resolve(result);
        } catch(e) {
            reject(e);
        }
    });
    }
    // 同期型
    syncFunc1(params) {
        return foo;
    }
    ・・・ 
    // 同期型
    syncFuncN(params) {
        return foo;
    }
}

と、非同期化メソッドを用意しておくといいだろう。

引き渡すパラメータはthenチェインする前に確定してしまうから、後々トラブりそうなのが難点で、

しかも、下のコードを見て判るように、各処理に引き渡すパラメータは事前に用意することになるけど

paramを変数宣言しておいて使用すれば、各処理が動き出す前に調整は可能だし、何よりデバッグが楽だ。

ちゃんとデバッグが済んでから、試作型に実処理を埋め込めばいいだろう。

とりあえず、

// 非同期処理を準備する
let param1;
let param2;
let param3;
let param4;
let param5;
let promFunc1 = asyncFunc1(param1);
let promFunc2 = asyncFunc2(param2);
let promFunc3 = asyncFunc3(param3);
let promFunc4 = asyncFunc4(param4);
let promFunc5 = asyncFunc5(param5);
//
promFunc1.then(()=>{              /* なんたら param2を最新化 */ 
    promFunc2.then(()=>{          /* かんたら param3を最新化 */
      promFunc3.then(()=>{        /* それから param4を最新化 */
        promFunc4().then(()=>{    /* こうして param5を最新化 */
          promFunc5().then(()=>{  /* こうなった */
});});});});}).catch((e)=>{      /* どうして、そうなった? */
});

とコードすることで完全に非同期になると思う。

でも、thenチェインって云われているものは普通コレではない。

//同期っぽい書いてある非同期処理 ※パラメータは暗黙の了解で繋がっている
promFunc1(a)       /* なんたら 暗黙のparam2を最新化 */
.then(promFunc2)     /* かんたら 暗黙のparam3を最新化 */
.then(promFunc3)     /* それから 暗黙のparam4を最新化 */
.then(promFunc4)     /* こうして 暗黙のparam5を最新化 */
.then(promFunc5)     /* こうなった */
.catch((e)=>{
   /* どうして、そうなった? */
});

あるいは

//同期っぽく書いてある非同期処理
promFunc1(a).then( (b)=>{        /* なんたら */    
    let b = await promFunc2(b);  /* かんたら */
    return b;
}).then( (b)=>{   
    let c = await promFunc3(b);  /* それから */
    return c;
}).then( (c)=>{
    let d = await promFunc4(c);  /* こうして */
    return d;
}).then( (d)=>{
    let e = await promFunc5(d);   /* こうなった */
    return e;
}).catch((e)=>{
   /* どうして、そうなった? */
});

のハズだ。この書き方の最大の問題点はawaitが本当に動作してくれるかどうかだ。

awaitはドコかのPromiseオブジェクトが「履行 (fulfilled): 処理が成功して完了」になるのを待つせいで、

ワーカースレッド内で同時に使用できるのはたったの1回だけ。

ネストできないから、上のコードを参照する処理や各async内でawaitしてるとawaitした途端にエラってしまう。

ので、

awaitを使ってエレガントなコードに酔いしれることができるのは「お一人様」つまり「貴族様仕様」なのだ。

つまり、awaitのaは、「とあるドコかの何か」ではなく「お一人様」の意味なのだ。

※試験には出ないけど重要です。

流石、文化が違うよね。ボクらはネストしてるthenチェーンか綺麗になおしたらデバッグ困難なコードに立ち向かう事になる。

だから、「ボタンをクリック」した直後に一回くらいに限定した方がいい。

サーバーと通信する際に使うと、画面隅に通知機能を搭載した途端にケンカ沙汰になってしまう。

というのが、ググった結果から得られた感想。

本当にこうなっているのかコードしてみると予想が結構ハズれているような気がする。

何せ、数年経てば、仕様書上は全く変わらないのに、全く違う動作になっている世界だけに。

実際、new Promiseのコールバックは今では即実行されてしまうので、

Promiseのthenの設定を全て終えメインスレッドが完了してから動いてくれると思ったら大間違い。

Promise.thenのコードを見つけると即実行するので、全く非同期ではない。

正確には、new Promiseのコールバックの中だけ、resolveかrejectを呼ぶまで非同期になってるダケで

Promise.resolveは、非同期に見える振りをしているだけ。

非同期にしたいなら

//同期っぽい書いてある非同期処理 ※パラメータは暗黙の了解で繋がっている
promFunc1(a)       /* なんたら 暗黙のparam2を最新化 */
.then(promFunc2)     /* かんたら 暗黙のparam3を最新化 */
.then(promFunc3)     /* それから 暗黙のparam4を最新化 */
.then(promFunc4)     /* こうして 暗黙のparam5を最新化 */
.then(promFunc5)     /* こうなった */
.catch((e)=>{
   /* どうして、そうなった? */
});

の書き方以外は意味が無い。

正解を引き当てたると後々面倒なことになるのはいつもの事。(大笑

「非同期な処理」≒「後でやって欲しい処理」を書くには、

各promFuncNの中でsetTimeoutしてresolveする以外に方法は無い。

ps.2021/12/13

サンプル追加。

thenチェインする処理を関数化すると、returnした値が引き継がれないのは痛いね。

thenチェインでreturnした値は、thisにぶら下げて引き渡しているんだろう。

1つの関数の中で閉じ籠って then チェイン して

うまく動いてるけど、ゴチャゴチャしているので

リファクタリングして美しいthenチェインにすると・・・

壊れます。(痛すぎ



[JavaScript]finallyが壊れている様な気がする

イミフなスタックオーバーフローに悩まされた。

static dataDumpNest = [];
static DATADUMPNEXT_MAX = 100;
static dataDump(objectName, obj, pOptions) {
  try {
    ・・・
    Helper.dataDumpNest.push(obj);
    rc = true;
    ・・・
    return true;
    ・・・
    //  再帰呼び出し時はtrueを返す
    if (Helper.dataDumpNest.length > 1) {
      return true;
    }
    //  それ以外は result を結合し返す
    return Helper.result.join("\n");
  } catch (e) {
    throw e;
  } finally {
    Helper.dataDumpNest.pop();
  }
}

finallyで無条件でpopしているので、

重複チェックで弾かれてpushしてない時に

無駄にjoinしてしまうのが気になり

執拗にF10でトレースしていると・・・

finallyブロックの終わりで呼び出し元のメソッドに戻るべきところが、

  1. ソース画面が何行か戻ってしまう。
  2. スタックトレースが妙に長くなっていた。

という摩訶不可解な現象にぶち当たった。

どうやら、return文無しで、finallyブロックの末尾にぶち当たると、ヤバイ事が起きている。

1万個の配列を何度もjoinさせ、しかも結果は捨てているのでブチ切れさせてしまったかもね。(大笑

普通、ドコかのreturn文の後に処理するハズのfinally句なのに。

延々と待たされた挙句にスタックオーバーフローになるソースを

finally句でtryの外の変数rcをreturnする様にしてみた。

static dataDumpNest = [];
static DATADUMPNEXT_MAX = 100;
static dataDump(objectName, obj, pOptions) {
  let rc = false;
  try {
    ・・・
    Helper.dataDumpNest.push(obj);
    rc = true;
    ・・・
    rc = true;
    return rc;
    ・・・
    //  再帰呼び出し時はtrueを返す
    if (Helper.dataDumpNest.length > 1) {
      rc = true;
      return rc;
    }
    //  それ以外は result を結合し返す
    rc = Helper.result.join("\n");
    return rc;
  } catch (e) {
    throw e;
  } finally {
  if (rc != false) {
    Helper.dataDumpNest.pop();
  }
    return rc;
  }
}

と変えたら、即終わったった

setTimeoutでワーカースレッドっぽい状態なんで、

finallyが、Promiseと勘違いしてスタックを遡ってみると配列がいっぱい積んであるので

Array[ Array[1], Array[2] ] あたりが、

new Promise((resolve, reject) {
・・・
}

に、そっくりだったのかもしれない。

しかし、違うと気が付いて、throw new Error(“Don’t mind.”);

して、普通のfinally になるつもりが、ソコのfinallyでまた躓いて、無限ループしてそう。

でも、そのうち治るでしょ?

やっと、本題の文法解析に戻れそう。

ん?三国英雄たちの夜明けがフリーズしやすいのは

もしやコレなのか?



[Visual Studio Code]「フォルダを指定して検索」が動かない

JavaScriptは型が無い。とは云え、全く無視するのは辛いので。マメにJSDocなコメントを入れている。

VisualStudioCodeでは関数や変数の名前をクリックして2回(Ctl+Alt+D)すると、テンプレが書き込まれるので簡単だ。

しかし、コード中に型チェックすると typeof を羅列するより switch case で書きたい時もある。

そんな時はObject.prototype.toString()が、

[Object ${ObjectTypeName}]の様な文字列を返してくれるので、 switch case 風に処理できる。

/**
 * オブジェクトの型名を調べる
 *
 * @param {Any} obj   オブジェクト
 * @return {string}      型名
 */
const getTypeName= (obj) => {
  if (typeof (obj) === "undefined") {
    return "undefined";
  }
  var toString = Object.prototype.toString;
  // [object typeName] のハズなので、typeName部分を抽出してみる
  let typeName = toString.call(obj).match(/^\[\w+\s+(\w+)\]$/);
  return typeName[1];
}

各オブジェクトのtoStringメソッドは、一番OverWriteしまくっているメソッドなので、

ココでは確実な動作を狙って、Object.prototype. toString をCall呼び出しで参照してみた。

でも名前がgetTypeNameなのがイマイチなんでObjectTypeNameにリファクタリングしたら、

他のファイルでUndefinedになってた。

JavScriptだから仕方が無いけど。

置換機能で書き換えようとしたら・・・

(サッパリ

検索すらしない。

ググっても、それっぽい記事は無い。

試しに「検索エディタ」を開いてみた。

赤線で囲んだアイコンをクリック

するとちゃんと検索しだした。

MSCodeを再起動しても、結果は良好。

つまり、裏側でこっそり設定ファイルが出来た様だ。

※この手の自動設定の不具合は、インストーラのテスト同様に見つけにくいものだ。

昔の映画で「xx製は叩けば治る!」というセリフがあったけど、MSCodeも同じらしい。

初回ダメなら「新規xx」とかをぶったたけば、初期設定ができるかも。

しかし、今後はどうなるか予断を許さない。(と思う。



[javascript]パーサ・コンビネータって

Java パーサコンビネータ 超入門というのを見つけた。

使い方を説明してくれるのでとても助かるけど、

JavaScriptでパーサコンビネータのコンセプトを理解する(「正規表現だけに頼ってはいけない」の続き)

の方がパーサ・コンビネータの仕組みを理解でき、且つ、使わなくなったけどJavascriptの便利な手法を思い出させてくれた。

function 関数(...) {
  return [1,2,3,4, ...];
}

と配列等で容易に複数の値を変えすことができるし、そんな関数を

let [a, b, c, d, ...] = 関数(...)

と呼び出すと、すんなり配列中の a, b, c, d, … に値を入れてくれるトコが地味に嬉しい。

いつのまにかいっぱい返す事になる未来が待っていそうな気がするから new classを返すことが多いけど。

また

function token(str) {
  var len = str.length;
  return function(target, position) {
    if (target.substr(position, len) === str) {
      return [true, str, position + len];
    } else {
      return [false, null, position];
    }
  };
}

の様にreturn function {…} することで、関数ジェネレータを簡易に記述できるのは便利、

但し、呼び出す側が、

token('foobar')('foobar', 0); // => [true, 'foobar', 6]を返す

な感じになってしまうとワークスペース内のファイルの関数を全部チェックする開発環境ではなく、

sakuraエディタで チョコ チョコ叩いている場合は、【見た目文法エラー!】なのが難点。

やはり、

const func = token('foobar');
func('foobar', 0); // => [true, 'foobar', 6]を返す

と書いて関数が戻ってくる雰囲気を醸し出した方が無難な気がする。

many(token('hoge'))('hogehoge', 0); // => [true, ['hoge', 'hoge'], 8] を返す

も、token(‘hoge’)部分がmanyな場合は、あーもーな感じになりそうなんで

let parsers = [];
parsers.push(token('hoge1'));
...
parsers.push(token('hogeN'));
let text = 'hoge1hoge2...hogeN';
let myParser =seq(parsers);
myParser(text, 0); // => [true, ['hoge1', ['hoge2', ...['hogeN']...]]], 8] を返す

と1行がいっぱい膨れ上がってしまいそう。

てか、実際に’hoge1hoge2’と直書きすることは滅多に無いから

もっと、もっと膨れ上がる。

先の記事のソースは「あくまで説明しやすく表記」したものなのは明白だけど、

テストコードってこんな風に書いてたりするよね?。(笑

ps.

先の「理解する」のページのコードをまとめてみた。

簡易のテストケースもパーサーの種類ごとに1つダケ書いてみたら、結構長くなってしまった。

作りかけだからFalseしまくってるのはいいとして

Errorオブジェクトから発生原因を判りやすくしてほしいなぁ。

字句解析とか構文解析は、「,」1つの修正だけでも

見えないところがトンデモない結果になり果ててしまいがちなので、テストはガチでやった方がいいからね。

ソースの説明

  • index.html   テスト画面
  • parcom.js パーサの記事からコードをコピペしてチョコっと加工したもの
  • sample.js パーサのテストパターンを起動し、結果を表示するスクリプト
  • testparcom.js  パーサのテストパターン
  • testbase.js    テストパターンを多少楽にするための testparcom.js の基底クラス
  • libs.js オブジェクトのダンプやErrorオブジェクトから情報を引き出したりするD級パーツ群
  • sample.css テスト画面用CSS

※ん-。まだまだな感じがする。

そもそも、各パーサはサブクラス化した方が良いんじゃにのかな?

更にパーサ コンテナ クラスで括った方が・・・。

アカン。どんどん膨れ上がる一方だ。

ps.2021/12/3

BNFっぽい文法”Call = [ Call ] procedureName [ (argumentList) ] ”と書かれたテキストを

解析するコードを作成中。やっと単純な文法をクリアしたものの、2つ目の文法に進まない。

デバッグでハマりすぎ長いログをスクロールするのが大変。

  • 機能を大幅改善
    • ログ末尾のstartとendを検出しリストタグ(UL,OL,LIとか)で手軽にインデント
      • 以前見つけたTreeViewのコードは流用できた
      • FIXTED:cssは全部見直しするハメになった
      • TODO:try…catch…filannyで確実にendを出力させないと右雪崩が発生する
    • TreeView風に[+][ーで折りたためる
      • TODO: +、ー小さすぎた!
      • TODO: endの行に+を配置するのは良くない。
    • trueやfalseを色分け
      • FIXED: あるあるな後付けデグレードと既存バグ発覚
        • objDumpで処理済みのテキストを再度objDumpしてが気が付かなかった
        • replaceで単語にタグ付けする場合は二度漬け禁止のハズが・・・
          • <span> ⇒ &lt;span> 的な出来事
    • FOXED:ログが雪だまり式に増えていた
      • Case2にCase1のログが
      • Case3にCase2とCase1のログが
      • 以下、増殖
        • 各テストCaseでログクリアする
    • TODO:typeof xxx === “undefined”はしてるけど、xxx === null チェックが甘い

コードの見直しが多すぎて、メソッド単体テストが壊滅状態。

修正してみたら、半壊状態。←いまこのへん。

全文法(287行中7行)をクリアするのはまだまだ先の話。

本当に終わりが見えないなぁ(大笑

            //      syntax = [ rule ]  ;
            setSyntax("syntax", many(refSyntax("defsymbol")));
            // defsymbol: { "\n" } IDENTIFIER "=" rule
            //###setSyntax("defsymbol", seq(optEol,  identifire,  asign,  refSyntax("rule")));
            setSyntax("defsymbol", seq(optEolWs, identifire, asign, refSyntax("rule")));
            // rule: list { "|" list }
            setSyntax("rule", seq(refSyntax("list"), repeat(seq(vl, refSyntax("list")))));
            // list: { seq | block | repeat | option }  "\n" { notes }
            // TODO: repeat(...)の中にoption系が挟まると無限ループするので、何か対策案を考える
            setSyntax("list", seq(repeat(choice(refSyntax("seqList"), refSyntax("block"), refSyntax("repeat"), refSyntax("option"))), eol, opt(refSyntax("notes"))));
            // seqList = seq { seqList }
            setSyntax("seqList", seq(refSyntax("seq"), repeat(seq(/*ws,*/ refSyntax("seqList")))));
            // seq = (regExp | IDENTIFIER | STRING | INTEGER | , )
            setSyntax("seq", choice(reExFmt, identifire, string, number, comma));
            // block: "(" rule ")"
            setSyntax("block", seq(lpr, refSyntax("rule"), rpr));
            // repeat: "{" rule "}"
            setSyntax("repeat", seq(lbr, refSyntax("rule"), rbr));
            // option: "[" rule "]"
            setSyntax("option", seq(lbk, refSyntax("rule"), rbk));
            // notes: "#Notes" "Syntax" eol rule "}}" "#Notes" "End" eol
            setSyntax("notes", seq(notes, ws, syntax, eol, refSyntax("syntax"), notes, ws, end, eol));

見直すのはコレだけなのに。

  • ログの大半がホワイトスペースだから何とかしたい
    • パーサから空白を読み飛ばす字句解析結果のを参照する?
    • パーサで作成したtoken(文字と正規表現)を適切な順に並べる
      • 勝手に空白を読み飛ばすので楽なハズ

クリアしたら、

  • 残りのテストを・・・
  • パーサコンテナを作る
  • 各パーサをサブクラス化
  • コードを読む部分を作る
  • 何かの言語に変換する部分を作る

先はまだまだ長い。

ps.2021/12/6

サブクラス化したもののソースは1000行を越えた。何か間違えている様だ。

サブクラス化 の過程で

  • リテラルにはプロパティが付けられない
    • String(“hohegoge”)ではダメ。
    • new String(“hohegoge”) でOK.
    • その辺は throw Error(“hogehoge”);も同じなんだろう。
  • RegExpにgオプションを付けlastIndexプロパティに位置を指定しても文字列の最初から検索する
    • 一度素振り(検索)させ自力でlastIndexを初期化しないとダメ
    • gは空振り(null)すると、とても機嫌が悪い。
  • RegExpのinputプロパティにオリジナルの文字列のコピーが作られる
    • メモリが心配
  • Refer.call を使ってみた
    • 横に長くなる
      • 伸びた部分だけ見れば良いので見やすいと思う人もいるかも
      • 元に戻す
  • super.メソッドみたいな呼び方ができる
    • なんちゃってオーバーライド風に書いてみると、無限ループする

18行1列まで読めた。 行末の _ 結合演算子がムズイ。

ps.2021/12/7

事前にザックリと空白、改行、その他でトークン化したついでにコメント文を空白化。後は _ かな。

全文からワード単位で字句解析するようになってブラウザの動作は軽くなった気がする。

ワード単位で取り出す時に、文末が” _”なら、次の改行を無視すればいいのかな?

ps.2021/12/8

手直しをしたら余計悪化。

0回ループOKなRepeatがネストしたら無限ループしてしまうので、Sequenceで評価がTrueでもpositionが進まない時は、評価をFalseにしたけど、まだループ。

仕方が無いので、catch exceptionで強制停止。300万行とか凄い行数になってたので、1000行までに制限。

やっと途中経過が可視化できた。ログのネストを深く掘り下げると

ParserInfo (ParserInfo)で、字句解析まで見れるけど。文法解析まで見れない。

ps.2021/12/9

手直し。 ダンプの仕方を見直し。

もう、本題を忘れてダンプに力が入る。

ps.2021/12/11

手直。 ダンプの仕方を見直し。  TreeView.markingをPromiseってみた。設定できてるけど、処理が終わったと返ってこない。

ps.2021/12/13

関数のダンプが修正漏れでエラっていたを訂正。



Windows11 更新あるいはお試し

1.Windows Update

「準備ができたしたーし」

かかか、噛みました的な。

2.手動アップグレード リンク先のページから以下を選択

(1)Windows 11 インストール アシスタント

(2)Windows 11 のインストール メディアを作成する

(3)Windows 11 ディスク イメージ (ISO) をダウンロードする

(4)その他のダウンロード 企業向け

3.お試し方法

Hyper-Vで、手軽にお試しできる。

「新規」より楽そう
ISOファイルダウンロードとかは勝手にやってくれる
できた
何だこれは・・・

とりあえず

を押してみる
もう何がなんだが

やっぱりPCで動かしたいなら



[Wnidows]PowerShell

色々できる(ハズ

EXEからアイコンを取り出す方法をさがしていたら、PowerShellでもできるらしい。

※Ver6からはSystem.Drawing.Iconが無い様だ。Windows10はVer5だから動くけど。

しかし、文法が ソースっぽさとコマンドラインが混ざってる(メンドクサイ

例えば、PowerShellの窓を開き

元ネタ:https://suzuzusu.hatenablog.com/entry/2016/10/14/043726
###########################################################
# アイコンを抽出して保存
###########################################################
function ExtractionIcon( 
            $Path,      # 抽出する .exe のフルパス
            $OutFile    # 出力する .ico のフルパス
        ){

    # アセンブリロード
    Add-Type -AssemblyName System.Drawing
    Add-Type -AssemblyName System.IO

    $str1 = "ExtractionIcon :Path=`"$Path`", :OutFile=`"$OutFile`""
    $str1
    # アイコンデータ抽出
    $IconData = [System.Drawing.Icon]::ExtractAssociatedIcon( $Path )

    # 出力用ファイルストリーム
    $FS = New-Object System.IO.FileStream( $OutFile, [System.IO.FileMode]::Create )

    # 保存
    $IconData.Save( $fs )
    $fs.Close()

    # オブジェクトの始末
    $fs.Dispose()
    $IconData.Dispose()
}

と貼り付けると、

窓が開いている間だけ使える。(便利

しかし、この関数を呼び出す時はコマンドプロンプトっぽく

> ExtractionIcon "C:\Program Files (x86)\Sarad\DiCE\dice.exe" "a:\aaa\aaa.ico"

と打つ。

関数の中では、関数っぽく呼び出すのだから・・・

コマンドプロンプトから1コマンドづつ打って動作を確かめた後、

関数化する際には

「コマンドっぽい記述は関数っぽく書き直さないといけない。」

のが面倒だな。

後、Windowsでパパっと使う都合上、デスクトップに貼る場合、

Join-Path $env:UserProfile\Desktop "sample.ico"

で済ましたいがOneDriveをインストしてしまうと、アンスコしてもパスが変わってしまうから

Join-Path [System.Environment]::GetFolderPath("Desktop") "sample.ico"

と書かないと動かないPCも出てくる。

更に、コマンドラインのパラメータの区切りは空白文字なのは常識なので

コマンドのパラメータにコマンドを使うと、 どっちのパラメータなのか判らなくなる。

〇 コマンド  (コマンド パラメータ1 パラメータ2)  パラメータ3

× コマンド  コマンド パラメータ1 パラメータ2  パラメータ3

だから、パラメータにコマンドの戻り値を使うなら、PowerShellでは()で括る仕様になっている。

先のEXEからアイコンを取り出すコマンドをコマンドラインから呼び出すには

ExtractionIcon "C:\Program.....\xxx.exe" (Join-Path [System.Environment]::GetFolderPath("Desktop") "sample.ico")

となってしまう。

最後に、今のPowerShellはRestrictedで、スクリプトファイルは実行不可で、

一時的に許可するなら

> pwsh.exe -ExecutionPolicy RemoteSigned xxxx.ps1 

ps1のショートカットの場合も

powershell -ExecutionPolicy RemoteSigned -File ${元の内容}

となる。

ま、当然何でもできるから危なっかしい。

いくらPS1を実行不可にしても気の利いたショートカットを作られたら・・・

結局、MSが作ると、

大抵は使い物にならない

しかし、使い物になる様にバージョンアップすると

危なっかしい。

これは定説だな。



[Excel]Alt+F11の競合

ExcelでVBAエディタは ALT + F11 で開いていたが、

暫く振りに使ったら無反応だった。

仕様が変わったのかな?思ったら

NVIDEA GeForce Expressの中で「 ALT + F11 」をフックしていたせいだった。

普通は自分の画面上でしか 自分の ショートカットは有効にならないが

ゲームの画面をキャプチャ等をするには、

デスクトップ内で 自分の ショートカット を有効にする方法(ジャーナルだったかん?)を使うしかない。

このため「ゲーム内のオーバーレイ」で登録してある「ショートカット」は全てのアプリの 「ショートカット」 より優先されるのだ。

対処法で一番確実なのは

NVIDEA GeForce Expressで 「ゲーム内のオーバーレイ」 を無効化

もし、Excelの操作をキャプチャで使ってるなら、

  1. 隠れているインジーケータから
  2. NVIDEAを右クリックして
  3. GeForce Expressをクリック
  4. 画面右上の方の歯車のアイコンをクリック
  5. 左側の全般をクリック
  6. 画面中央の「ゲーム内のオーバーレイ」の「設定」ボタンを押下
  7. 「キーボード ショートカットリスト」を下スクロールし
  8. 「ブロードキャストライブ」のとこの「 ALT + F11 」 を探し出し、
  9. クリックしてスペースバーを押して「None」表示に切り替える。
  10. 「戻る」ボタン押下「完了」ボタン押下
  11. 「ゲーム内のオーバーレイ」状態に変わり、ちょっと何をすればいいか困る状態に陥る(かもしれないけど
  12. デスクトップの右上の「X」ボタン押下と、「ゲーム内のオーバーレイ」が解除される。

かな。



[JavaScript]dropイベント

MDNにフォルダをドロップして中身をリストアップするサンプルを見つけた。

FireFoxではうまく動くが、ChromeやEdgeでは・・・・・・・・・

code: 0
message: "A URI supplied to the API was malformed, or the resulting Data URL has exceeded the URL length limitations for Data URLs."
name: "EncodingError"

が出てしまう。

「APIに提供されたURIの形式が正しくないか、結果のデータURLがデータURLのURL長の制限を超えています。」

ってファイル名のせい?

しかし、C:¥aaaでも同じ結果だった。

原因は判らないけど、コードをアップしてみると・・・何故かうまくいく(アップ先)。

どうやら、httpなURLなパスにあるHTMLファイルをブラウザで開いている場合はOKらしい。

微妙だ。どっちかと云えば、

PCにコピったHTMLファイルでウマくいく方が安心なのに

得体のしれないのURLの画面のページに自分のPCのフォルダをドラッグするのは・・・

素で怖いw

と思う。

後、先の参考URLの注釈通りにreadEntries は、100個までしか読んでくれない。

forEachはPromiseを返さないので、非同期処理を抱えてる部分を含めて、

ローカル関数に書き換えたが forEachの最終ループで再起すると

どう見ても無限ループにしか見えない

ここは、forEachをmapにして暗黙の同期化を発動する。

ついでにmapの戻り値から readEntries が空っぽを渡たさなかった場合のみ再起するようにした。

readEntries  も非同期っぽいから、ローカル関数のままか。

フォルダに203個ファイルがあっても全部書き出してくれたから、

多分大丈夫。

メデタシ、メデタシ。(かな?

あ、HTMLのINPUTタグでwebkitdirectory を指定すると

フォルダも選択できるらしい。

こっちの方が良さそう。

でも、非標準らしい。




top