Installed 32GB Memory

f:id:quwahara:20191129011031p:plain
Device specifications

The 32GB Memory was arrived from Crest Hill, Illinois today.

I installed it into my LG Gram 13.

This is the biggest RAM for me in my life.

Also the PC mounts quad core CPU and my first quad core CPU.

I feel keenly technology advanced and the time flew by.

Tomorrow must be exciting than before!

https://www.amazon.com/dp/B07N124XDS/ref=nav_timeline_asin?_encoding=UTF8&psc=1

Jhtrans 実装所感

Template を用意し、それを参照する構造を表すデータ trMap を処理すると HTML を吐き出すようなものを試しに実装している。

所感

  • "0x0-" は捨てた方がよい
  • trMap の要素に、trMap を指定し、そこから新しく Translate をはじめられるようにしたい。 PH-Key がすぐ長くなるので、新しく Translate を開始して、Depth を浅くし、PH-Key が短くなるようにすることを目論む。
  • 特定のPL-Keyを表す別名を用意したい。例 "0x1" --> ":root-first-child" など。
  • PL-Key は深さと並び位置の組み合わせ。フルに PL-Key を並べなくても、1つ上の PL-Key とその下のPL-Key だけでユニークになる気がする。誰か証明して。

Template

    jht.putTemplateAll({

    //
    // row
    //
    "div": ["div", null, "@"],

    //
    // row
    //
    "row": ["div", {
      "class": "row"
    }, "@"],

    //
    // c-1 to c-12
    //
    "c-1": ["div", {
      "class": "c-1"
    }, "@"],
    "c-2": ["div", {
      "class": "c-2"
    }, "@"],
    "c-3": ["div", {
      "class": "c-3"
    }, "@"],
    "c-4": ["div", {
      "class": "c-4"
    }, "@"],
    "c-5": ["div", {
      "class": "c-5"
    }, "@"],
    "c-6": ["div", {
      "class": "c-6"
    }, "@"],
    "c-7": ["div", {
      "class": "c-7"
    }, "@"],
    "c-8": ["div", {
      "class": "c-8"
    }, "@"],
    "c-9": ["div", {
      "class": "c-9"
    }, "@"],
    "c-10": ["div", {
      "class": "c-10"
    }, "@"],
    "c-11": ["div", {
      "class": "c-11"
    }, "@"],
    "c-12": ["div", {
      "class": "c-12"
    }, "@"],

    "row--c-12--pad6": ["div", {
      "class": "row"
    }, [
        ["div", {
          "class": "c-12"
        }, [
            ["div", {
              "class": "pad6"
            }, "@"]
          ]]
      ]
    ],

    //
    // lablel
    //
    "label": ["label", null, "@"],

    //
    // inputs
    //
    "i-text": ["input", {
      "type": "text"
    }, ""],
    "i-password": ["input", {
      "type": "password"
    }, ""],

    //
    // buttons
    //
    "b-button": ["button", {
      "type": "button"
    }, "@"],
  });

trMap

  const trMap = {
    "0x0-1x0": [
      "#row",
      "#row",
      "#row--c-12",
    ],
    "0x0-1x0-2x0": [
      "#c-3",
      "#c-6",
      "#c-3",
    ],
    "0x0-1x0-2x1-3x0": [
      "#row--c-12--pad6",
      "#row--c-12--pad6",
      "#row--c-12--pad6",
    ],
    "0x0-1x0-2x1-3x0-4x0-5x0-6x0": [
      "#label",
      "#i-text",
    ],
    "0x0-1x0-2x1-3x0-4x0-5x0-6x0-7x0": "Username",
    "0x0-1x0-2x1-3x1-4x0-5x0-6x0": [
      "#label",
      "#i-password",
    ],
    "0x0-1x0-2x1-3x1-4x0-5x0-6x0-7x0": "Password",
    "0x0-1x0-2x1-3x2-4x0-5x0-6x0": [
      "#c-6",
      "#c-6",
    ],
    "0x0-1x0-2x1-3x2-4x0-5x0-6x0-7x0": "#b-button",
    "0x0-1x0-2x1-3x2-4x0-5x0-6x0-7x0-8x0": "Login",
    "0x0-1x0-2x1-3x2-4x0-5x0-6x1-7x0": "#b-button",
    "0x0-1x0-2x1-3x2-4x0-5x0-6x1-7x0-8x0": "Cancel",

  };

HTML

<div class="jh-0x0">
    <div class="row jh-0x0-1x0">
        <div class="c-3 jh-0x0-1x0-2x0">0x0-1x0-2x0-3x0</div>
        <div class="c-6 jh-0x0-1x0-2x1">
            <div class="row jh-0x0-1x0-2x1-3x0">
                <div class="c-12 jh-0x0-1x0-2x1-3x0-4x0">
                    <div class="pad6 jh-0x0-1x0-2x1-3x0-4x0-5x0"><label
                            class="jh-0x0-1x0-2x1-3x0-4x0-5x0-6x0">Username</label><input type="text"
                            class="jh-0x0-1x0-2x1-3x0-4x0-5x0-6x1"></div>
                </div>
            </div>
            <div class="row jh-0x0-1x0-2x1-3x1">
                <div class="c-12 jh-0x0-1x0-2x1-3x1-4x0">
                    <div class="pad6 jh-0x0-1x0-2x1-3x1-4x0-5x0"><label
                            class="jh-0x0-1x0-2x1-3x1-4x0-5x0-6x0">Password</label><input type="password"
                            class="jh-0x0-1x0-2x1-3x1-4x0-5x0-6x1"></div>
                </div>
            </div>
            <div class="row jh-0x0-1x0-2x1-3x2">
                <div class="c-12 jh-0x0-1x0-2x1-3x2-4x0">
                    <div class="pad6 jh-0x0-1x0-2x1-3x2-4x0-5x0">
                        <div class="c-6 jh-0x0-1x0-2x1-3x2-4x0-5x0-6x0"><button type="button"
                                class="jh-0x0-1x0-2x1-3x2-4x0-5x0-6x0-7x0">Login</button></div>
                        <div class="c-6 jh-0x0-1x0-2x1-3x2-4x0-5x0-6x1"><button type="button"
                                class="jh-0x0-1x0-2x1-3x2-4x0-5x0-6x1-7x0">Cancel</button></div>
                    </div>
                </div>
            </div>
        </div>
        <div class="c-3 jh-0x0-1x0-2x2">0x0-1x0-2x2-3x0</div>
    </div>
    <div class="row jh-0x0-1x1">0x0-1x1-2x0</div>#row--c-12
</div>

お試しで実装した JSON から HTML へのTranslatorの 構成要素を整理する

動的 Element 生成を実装するときの状況例を明文化する - quwaharaの日記で整理した項目と、 Translatorの構成要素がどの程度適合しているか確認するため、 Translatorの構成要素を整理したい。

Translatorのデータ構造

TranslatorはテンプレートになるElementを保持するデータ構造を持っている。
データ構造はKey-value形式のマップだ。
Key は String、Value は Element になる。
そのデータ構造をテンプレートマップと呼ぶことにする。
テンプレートマップのKeyをテンプレートKeyと呼ぶことにする。

Translatorは Translate を実行するとき、 Translate の設計図になるデータ構造を引数にとる。
データ構造はKey-value形式のマップだ。
Key は String、Value については後述する。
そのデータ構造をトランスレーションマップと呼ぶことにする。
トランスレーションマップのKeyをトランスレーションKeyと呼ぶことにする。

Translatorの Key

Translatorは変換のために、要素を関連付けする Key がある。
データ構造の章ですでに、テンプレートKeyとトランスレーションKeyが出た。
テンプレートはHTMLのElementになっている。
テンプレートの用途に、テンプレートのあるElementのChild elementへ、 別なテンプレートを埋め込みたいことがある。
それを実現するために、埋め込みたい位置を示すためのKeyがある。
そのKeyをプレースホルダーKeyと呼ぶことにする。 プレースホルダーKeyと識別するために、プレースホルダーKeyは@で始まる。
変換の基本的な動きは、プレースホルダーKeyと一致する、トランスレーションKeyがあったら、 トランスレーションKeyのValueを、プレースホルダーKeyがある位置へ、埋め込む。
プレースホルダーKeyと一致する、トランスレーションKeyがなかったらなにもしない。
プレースホルダーKeyはそのテンプレートの要素の下に残ったままになる。
この動作は、変換後のテンプレートを再度、テンプレートとして使うことを想定している。

また埋め込みたい位置に、テンプレートKeyも指定できる。
テンプレートKeyと識別するために、テンプレートKeyは#で始まる。   テンプレートKeyの変換は、埋め込まれていたテンプレートKeyでテンプレートマップに一致するKeyがないか探す。
一致するKeyがあれば、そのKeyがさす Value の Element をテンプレートKeyがあった位置へ埋め込む。
埋め込まれた Element もプレースホルダーKeyやテンプレートKeyが埋め込まれていないかの、走査の対象になる。
一致がなかったら何もしない。

変換時のプレースホルダーKeyの暗黙の別名

プレースホルダーKeyは、変換を行うとき暗黙の別名を付けられる。
その暗黙の別名ををプレースホルダーロケーションKey(PL-Key)と呼ぶことにする。
PL-Keyは、プレースホルダーKeyが重複することが想定されるので、 変換時に処理が付ける連番で、プレースホルダーKeyを唯一に指定できるようにするためだ。
変換はトランスレーションマップの指定の仕方で、再帰的に呼び出されることがある。
PL-Keyは再帰の回数と、テンプレート内でのプレースホルダーKeyの出現順を '-' で繋いで表す。
回数と出現順はともに '0'始まりだ。
例えば、最初の変換の呼び出しの、最初に現れたプレースホルダーKeyの PL-Key は '0-0' になる。
再帰1段目で、3番目に現れるプレースホルダーKeyの PL-Key は '1-2' になる。

トランスレーションマップのValue

トランスレーションマップのValue に指定できる値は次のものがある。
それぞれのValueに指定した値は、トランスレーションKeyが一致するプレースホルダーKeyの位置へ、 埋め込まれる。
単純な文字列はその文字列が埋め込まれる。
ElementはそのElementが埋め込まれる。
Elementは木構造を下る操作をして、プレースホルダーKeyがあれば、変換の対象になる。
テンプレートKeyは、そのテンプレートが埋め込まれる。
もし見つからなかったら、ValueにあったテンプレートKeyそのものが埋め込まれる。
埋め込まれたテンプレートは再帰的に、変換の対象になる。
トランスレーションKeyは、そのトランスレーションKeyを使って、 再帰的にトランスレーションマップを検索し、変換する。
変換結果もまた、再帰的に変換の対象になる。
もし見つからなかったら、ValueにあったトランスレーションKeyそのものが埋め込まれる。
配列は配列の要素の並びが、Elementの兄弟として順に埋め込まれる。
この並び順がPL-Keyの出現順にあたる。

キーワードの整理

ここまでの振り返りで出現したキーワードを箇条書きに整理する。

原始的な要素

  • 関連するKeyがない
  • 単純な文字列
  • Element
  • 配列

データ構造

  • テンプレートマップ
  • トランスレーションマップ

データ構造構成要素

処理中の文脈であらわれる情報

展望

この整理と実装を照らし合わせたり、状況例と照らし合わせたりしながら、実装をすすめたい。

動的 Element 生成を実装するときの状況例を明文化する

手間の観察が必要だ

何べんも行ってきた作業だが、 動的 Element 生成を実装するプログラムは、書いていてとても手間がかかる。
とてもしんどい。
その手間をテンプレートエンジンなどを、導入することで減らしたい。

仮にそのようなテンプレートエンジンを実装することにしたとする。
テンプレートエンジンを実装するにあたり、 動的 Element 生成のプログラミングでは、 実際にはどのような実装をしているか、よく観察する必要がある。
どのような実装をしていて、どのように手間なのかを理解するためだ。
どのように実装しているか、業務で行った作業をふりかえり観察してみよう。

作業をふりかえる

動的 Element を生成するために、 クローン元にする Tag を あらかじめ HTML で非表示の Element の下にレンダリングした。
その Tag はHTML ページが初期表示されたときにすでに存在している。
変更不可能なグローバル変数的に、その Tag はいつでも参照できる状態にあることになる。

状態が変わって、動的に Element を生成することになったとする。
例えば、ドロップダウンリストを選択し、その選択内容にあわせて、何かを表示するような場合を想定している。
状態が変わることを、検知するためにイベントをハンドルする関数を登録する。
そのハンドルする関数内で次のようなことを行う。

まず動的生成を行った Element を全て削除する処理を実装した。
以降の処理で生成した Element を追加するにあたり、 先にイベントが起きていて、Element が生成してあったら、それは一旦なかった状態にしなければならないからだ。

次にどのような状態になったかを確認する。
ある状態では、Element生成する必要があるが、ある状態では必要がないという、ビジネス的要件があった。
そのための確認だ。

確認した結果、Elementを生成しなければならない場合だったとする。
非表示 の Element の下にある、クローン元の Element を、querySelector() か jQuery などで検索し取得する。
取得できた Element をクローンする。
クローンした Element へ、その Element 固有に与えなければならない情報や、id、class、属性などを指定する。
この Element を情報設定済 Element と呼ぶことにする。

今回の作業では、そのクローンした要素を、ページ中の1から数か所以上へ配置するようにしなければならなかった。
そのため、情報設定済 Element を配置先の数だけ、クローンする。

次に配置先の Element を特定する。 これも querySelector() か jQuery などで検索し取得する。
取得した配置先 Element の child node へ、情報設定済 Element をさらにクローンして追加する。
これを1から数か所に対して行う。

最後に配置先へ、追加したことによって、さらに状態が変わるので、その状態を確認し、画面表示に反映させる。
例えば、Element の数を画面に何件と表示しているような場合だ。
もともと2件と表示していたものを、追加したことで、5件と書き直すようなことをする。

ここまでで動的 Element 生成で行った実装の一巡となる。
この一巡の実装を、個別の状態に対して、全部面倒をみるように実装しなければならないわけだ。

ふりかえりの整理

整理のために、ふりかえりの中で表れた作業を箇条書きに抜き出してみよう。

  • クローン元 Tag を非表示で準備
  • イベントハンドリング設定
  • 生成済み Element を全削除
  • クローン元 非表示 Tag 取得
  • 取得 Tag をクローン
  • クローン済み Tag へ情報設定。それを情報設定済 Element とする
  • 配置先 Element を取得
  • 情報設定済 Element をクローン
  • クローンした情報設定済 Element を配置先 Element へ追加
  • 追加完了後の状態を画面へ反映

整理を省察する

さて私の状況で手間を減らすために、テンプレートエンジンを実装するとしたときに、 箇条書きにあげた事項を、端的記述で表現して指定できることが、 テンプレートエンジンに求められるわけだ。
そのような記述を設計し、処理できる仕組みを考えることは大変な仕事だ。

2019-11-13

こちらの発想を
HTMLをJSON で表現できる下のような書式を考えてみたが - quwaharaの日記

お試しで実装している
GitHub - quwahara/jhtrans: Translate JavaScript array to HTML DOM object. Templating and replace the placeholder with a template.

テンプレート構文が思いつき過ぎるので、見直して整理したい

Usage やドキュメントを残したい

npm モジュール作成入門してみた

npm モジュール作成してみたいとおもい

こちらの記事を実践してみた
本当にやさしいnpmライブラリ開発入門 - Qiita

前提

  • npm がインストールされている
  • npmjs.com のアカウントはある

作業記録

# npm にログイン 

mitsuaki@SURFACE-GO:~$ npm login
Username: quwahara
Password:
Email: (this IS public) quwahara@gmail.com
mitsuaki@SURFACE-GO:~$ npm whoami
quwahara

# プロジェクトディレクトリ作成

mitsuaki@SURFACE-GO:~$ cd git
mitsuaki@SURFACE-GO:~/git$
mitsuaki@SURFACE-GO:~/git$ mkdir jhtrans
mitsuaki@SURFACE-GO:~/git$ cd jhtrans/

# プロジェクトディレクトリ初期化

mitsuaki@SURFACE-GO:~/git/jhtrans$ npm init .
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (jhtrans)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC) MIT
About to write to /mnt/c/Users/mitsuaki/git/jhtrans/package.json:

{
  "name": "jhtrans",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}


Is this ok? (yes) yes

# 中身をけずる

mitsuaki@SURFACE-GO:~/git/jhtrans$ vim package.json
mitsuaki@SURFACE-GO:~/git/jhtrans$ cat package.json
{
  "name": "jhtrans",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}

# 公開する

mitsuaki@SURFACE-GO:~/git/jhtrans$ npm publish
+ jhtrans@1.0.0


# 公開したモジュールを試してみる

# テストプロジェクトディレクトリ作成

mitsuaki@SURFACE-GO:~/git/jhtrans$ cd ..
mitsuaki@SURFACE-GO:~/git$ mkdir jhtrans-test
mitsuaki@SURFACE-GO:~/git$ cd jhtrans-test/

# テストプロジェクトディレクトリ初期化

mitsuaki@SURFACE-GO:~/git/jhtrans-test$ npm init .
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (jhtrans-test)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC) MIT
About to write to /mnt/c/Users/mitsuaki/git/jhtrans-test/package.json:

{
  "name": "jhtrans-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "MIT"
}


Is this ok? (yes) yes

# 作成したモジュールをテストプロジェクトへインストール

mitsuaki@SURFACE-GO:~/git/jhtrans-test$ npm install --save jhtrans
jhtrans-test@1.0.0 /mnt/c/Users/mitsuaki/git/jhtrans-test
└── jhtrans@1.0.0

npm WARN jhtrans-test@1.0.0 No description
npm WARN jhtrans-test@1.0.0 No repository field.

# テスト用実行ファイル作成

mitsuaki@SURFACE-GO:~/git/jhtrans-test$ touch test.js
mitsuaki@SURFACE-GO:~/git/jhtrans-test$ vim test.js
mitsuaki@SURFACE-GO:~/git/jhtrans-test$ cat test.js
const jhtrans = require("jhtrans");

jhtrans();

# 実行。モジュールがロードされた

mitsuaki@SURFACE-GO:~/git/jhtrans-test$ node test.js
Hello World

作成したお試しプロジェクトのページ
https://www.npmjs.com/package/jhtrans

  • 2019-12-14 追記

公開後の更新

# Login

quwahara@QWH-LG:~/git/jhtrans$ npm login
Username: quwahara
Password:
Email: (this IS public) quwahara@gmail.com

# Make sure logged in

quwahara@QWH-LG:~/git/jhtrans$ npm whoami
quwahara

# Update version number

quwahara@QWH-LG:~/git/jhtrans$ npm version minor
v1.1.0

# Publish the updates
quwahara@QWH-LG:~/git/jhtrans$ npm publish
+ jhtrans@1.1.0

参考記事
npmでパッケージを公開してみた手順の記録 - Qiita