2022/02/28

Windows10にインストールしているアプリたち(2022年)

Windows 環境を作り直したついでに、インストールしているアプリたちをリストにしておこう。

 

最終更新日:2022/03/06


Chocolatey

Chocolatey Software | Chocolatey - The package manager for Windows
https://chocolatey.org/

ちょこらてい?

Ubuntu でいうところの apt みたいなものだ。
winget や scoop とかいろいろあると思うのだが比較したことはない。最初に気付いたアプリがそれだったというところだ。

GUI はそれを GUIで見せてくれるアプリだ。
便利ではあるのだが、これをインストールするといくつか追加でインストールされるものが出てくるので、ちょっと哀しい気持ちになる。なんで AutoHotKey が必要になるんだろうね?

ノートPCで使っていた設定を export して持って来ることができたのはよかったのだが、一覧の取得が今ひとつだったりする。ノートPC の方では普通に取れているので、いきなり import したのが何か良くなかったのか?

インストーラが、ものによってはフル設定でインストールされるのか、要らない設定でインストールされてしまうこともある。VLC media player でコンテキスト設定は不要だったのだけど、それを外す方法が分からなかったりとか。

インストールを Chocolatey で行って、アンインストールを Windows から行うと、 choco のリストには残ったままになってしまった。
これはまだ対処の仕方を調べていない。

 

それでも、あちこちからダウンロードとインストールを繰り返すことを考えると非常に楽である。


C電卓

C電卓
http://millgran.fc2web.com/soft.html#cCalc

10進数、16進数、2進数で表示してくれる電卓アプリ。
Windows のストアアプリにある電卓でもプログラマー用はあるのだが、私の感覚にちょっと合わなかったのだ。


Executor

Executor
https://executor.dk/

ランチャーだ。
コマンド入力タイプのランチャーだ。

bluewind をずっと使っていたのだが、メンテナンスされなくなったので乗り換えた形だ。

なんだろうね、なんでメニューがあるのにわざわざランチャーを使うのだろうね。
私にもまだ答えは出ないのだが、不思議なことにメニューを使うアプリとランチャーを使うアプリがなぜか棲み分けされている。


TeraTerm
Windows Terminal

Tera Term Open Source Project
https://ttssh2.osdn.jp/index.html.ja

Windows Terminal を入手 - Microsoft Store ja-JP
https://www.microsoft.com/ja-jp/p/windows-terminal/9n0dx20hk701?SilentAuth=1&wa=wsignin1.0&activetab=pivot:overviewtab

並べるようなものでは無いかもしれんが、Terminal ということでまとめてみた。

SSH するなら TeraTerm、コマンドラインなら Windows Terminal というところか。
TeraTerm が cmd.exe を扱えたなら Windows Terminal は使わなかっただろう。

 

私の環境では WSL は使っておらず、Linux系のアプリ開発は VirtualBox で行っている。
正直なところ、Linux環境をメインにして VirtualBox などに Windows をインストールした方がメリットが大きいような木はするのだが、踏み出せないところだ。

Windows のコマンドラインを使うのも、だいたい Android で adb を使いたいだけだったり、 npm を使いたいだけだったりするので、実はそれほどコマンドラインのコンソールを使いたいことはない(開発以外では)。

Windows Terminal はコンテキストメニューに「このフォルダから開く」が追加されるので、それだけで使っている気がする。


AutoHotKey と PowerToys

AutoHotkey
https://www.autohotkey.com/

Microsoft PowerToys | Microsoft Docs
https://docs.microsoft.com/ja-jp/windows/powertoys/

なぜこの2アプリが並ぶかというと、ショートカットキーの割り当て関係だからだ。

Windows のショートカットキー割り当てとしては、レジストリを変更するタイプが昔はほとんどだった。
しかし最近はアプリレベルで差し替えるタイプも増えていて、それがこの 2つだと思っている。

 

ただ、どちらも完全に置き換えはできない。
今のところ AutoHotKey を使って、PowerToys のキー割り当て機能は無効にしている。

単発のキーはどちらもできるのだ。
問題は長押しというか、押しっぱなしにしたとき。
私はカーソル移動だけは Emacs っぽくなっていて、

Ctrl+ P : Previous で ↑
Ctrl+ N : Next で ↓
Ctrl+ F : Forwar で →
Ctrl+ B : Back で ←
Ctrl+ H : backspace

という割り当てを使っている。
カーソル移動なのでしばしば長押しにするのだが、たとえば Ctrl+N を長押ししていると、たまに Ctrl がはずれて n が入力されたりするのだ。
Intellij のように重たいエディタを使っていると起きやすいのだが、そうでなくても起きる。


PDIC

PDIC/Unicode Release
http://pdic.la.coocan.jp/unicode/

かなり昔から使っている。
Nifty Serve というサービスがあったのだが、そこで電子辞書ファイルがダウンロードできて、それがこの形式だったのだ。
当時は数日掛けてダウンロードしたよなぁ、と懐かしい気分になる。

今やオンラインでの翻訳サービスが無料で使えるので使わなくて済みそうなものだが、無料版だとお仕事での翻訳(サイトを日本語で読みたいとかではなく、業務で外部に出せない内容を翻訳したいときなど)で使うわけにはいかないので、ちょっとした単語検索によかったりする。


TTClock

TTClock - Chihiro's Page
http://chihiro718.jpn.org/software/TTClock/index.html

カスタマイズしてもしなくてもよさそうな、タスクトレイに表示されている時計のカスタマイズアプリ。
私はこんな感じで表示させている。

image

年表示はまだよいのだけど、曜日と秒数がほしい。
昔は曜日なんて必要としてなかったけれど、家にいる時間が長いと曜日も分からなくなってきてね。。。

ポップアップで令和表示してくれると助かるときもあるのだが、まあそっちはなくてもだいたいなんとかなる。
元号での表示がいるのって、いまやお役所くらいだしね。


Windows Firewall Control

Windows Firewall Control
https://www.binisoft.org/wfc.php

Windows標準の Firewall 設定を管理するツール。
最初は binisoft さんが出していたが、Malwarebytes社のシリーズの一つになったのかな?

この手のアプリをインストールしたことがある人はわかると思うが、通信を許可制にすると問題が起きることが多い。初めて通信するアプリの場合はユーザにどうするか確認してくれるのだが、その確認待ちの間に通信失敗と判断してアプリがエラーになるのだ。
たまに聞いてこずに遮断されることもあり、そういう場合は裏でエラーになったことにも気付かない、みたいなこともある。

通信を許可したアプリであってもアプリのアップデートが行われることで再設定が必要になったり、アップデートするアプリをダウンロードするために許可しないといけなかったり。DropBox なんかがそうで、これに気付かないとアップデートされないのだ。

ユーザに聞かずに通す設定もあるのだが、それだとそもそも意味がない気がするので、PC を入れ替えてアプリをたくさんインストールするときはそういう Learning モードにして、落ち着いてきたら確認するモードに切り替えたりしている。

 

そんな面倒しかないツールを使うのは、やはりよくわからないアプリを通してしまうことが怖いからだ。
よくわからないアプリなので気付かないこともあると思うし、そもそも通信しないアプリがあまり多くないので結局許可しないといけなかったりするのだが、いつでも禁止にできると思うと心が安らぐ(?)のだ。

そういう意味では、Learning モードで自動登録にしておいて、あとから遮断していくというやり方がよかったかもしれない。

 


FileMenu Tools
Easy Context Menu

FileMenu Tools
https://www.lopesoft.com/index.php/en/download/filemenu-tools

Easy Context menu v1.6
https://www.sordum.org/7615/easy-context-menu-v1-6/

コンテキストメニュー関連。

似たようなことができる二人なのだが、Easy Context Menu の方がコンテキストメニューを減らすのには向いていると思うし、FileMenu Tools は SendTo が変更できる。

あと、Easy Context Menu はショートカットを作ったときの名前に「- ショートカット」と後ろに付くのを止めるオプションもある。地味に便利。 choco install ecm なのは探しにくいと思った。

2022/02/27

Windows10とnvm

JavaScript を使うことがある。主に node.js で。

node.js を Windows で使う場合、node.js のインストーラをダウンロードしてインストールするだろう。
しかし、環境によって node.js のバージョンを指定されることがある。
Java で jdk8 だの jdk11 だのの選択があるのと同じようなものだ。
個人で開発するときならまだよいのだが、プロジェクトでやるときには同じバージョンをインストールしていないと面倒なことになりかねない。

 

Linux で作業するときには nvm を使っていた。

nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
https://github.com/nvm-sh/nvm

POSIXコンパチブルと書いてあるように、Windows だと使えない。
似たようなものとして nvm-windows がある。

coreybutler/nvm-windows: A node.js version management utility for Windows. Ironically written in Go.
https://github.com/coreybutler/nvm-windows

GitHub からバイナリをダウンロードしてインストールすればよいのだが、Chocolatey で環境を作るようにしているのでそちらでインストールを今までしていた。
ただ、これを書いている時点(2022/02/27)で GitHub でのバージョンは 1.1.9 なのだが、Chocolatey の方は 1.1.51.1.7 だった。
なので、比較的最近まで 1.1.7 をインストールして使っていた。

 

最近まで 1つの node.js バージョン(v14系)しか必要としていなかったのだが、v16系を使う必要が出てきた。
ようやく nvm が nvm っぽいことをするときがやってきたのだ。
v16.14.0 をインストールすることはできたのだが、 npm i するとエラーになるのだ。

エラーメッセージがなんだったかもう忘れてしまったのだが、1.1.9 をインストールするとよいという回答が見つかったので GitHub 版にしたらエラーが出なくなった。

その後 1.1.7 に入れ替えても動いたのだが、ようわからんので 1.1.9 のままにしている。
おそらく Chocolatey の nvmは chocolatey-nvm-windows が使われているのだと思う。

なら chocolatey の nvm でバージョンを 1.1.9 と指定したらいけるんじゃないの?と試してみたのだが、nvm 1.1.5 の方でバージョンを指定しても 1.1.7 がインストールされてしまった。ダメか。


node.js を普通にインストーラーでインストールすると、 Program Files\node.js というディレクトリを作ってインストールされる。
nvm 1.1.7 を使うと Program Files\node.js はショートカットというかたぶんシンボリックリンクになって、本体が ProgramData\node.js に置かれるようになっていたと思う。

 

nvm 1.1.9 では AppData\Roaming\nvm にインストールされた。
しかし「nvm use」をそのまま実行するとエラーになる。

>nvm use 16.14.0
exit status 1: �A�N�Z�X�����ۂ����܂����B

読めないのだ・・・。

管理者権限を持った状態で nvm use すると動作する。
そのときに Program Files\node.js にシンボリックリンクが張られた。

やっぱりオリジナルが Program Files\node.js にインストールするようになっているので避けられないのだろうか。
これはこれで面倒だ。


Microsoft のページに代替のマネージャーが載っていた。

代替のバージョン マネージャー
https://docs.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows#alternative-version-managers

vscode とも連携できるようなので nvs をインストールしてみた。
Chocolatey からもできる。それに Windows 以外でも使える。

jasongin/nvs: Node Version Switcher - A cross-platform tool for switching between versions and forks of Node.js
https://github.com/jasongin/nvs

コマンドは nvm と同じような感じだが、 nvs add を使うのがよいのかな。

>nvs add 16.14.0
Downloading [#############################################################] 100%
Extracting  [#############################################################] 100%

>nvs use 16.14.0
PATH += %LOCALAPPDATA%\nvs\node\16.14.0\x64

>node --version
v16.14.0

ほう。
nvs use はその場で PATH に追加するだけなので権限は必要にならなかった。

 

それになんと、ディレクトリごとに自動で切り替える機能もある。
bash と powershell 向けと書いてあるが・・・あれ、cmd.exe では使えないのだろうか。

>nvs auto on
Automatic switching is not supported from a Windows Command Prompt.
Use PowerShell instead.

ダメか。
なんか powershell は苦手なのだが、node.js で使うだけだから我慢しよう。
文字色がダメなんだと思う。「node --version」だとこうなるのだ。

image

背景が真っ黒なら、まだなんとかなるか。

image

色をカスタマイズしたいと言うよりは、色分けを止めてほしいだけなのだが、見つからなかった。
それに、vscode を起動して自動的に Terminal が希望したディレクトリを開いた場合には auto が効かないようだったので無理して powershell を使う必要もなさそうだ。

 

手動で行う場合は、.node-version というファイルを作ってバージョン名を書いておく。
そして nvs use と打つと設定してくれる。
.nvmrc でもよいように書いてあったのだが、そちらだと動かなかった。 cmd.exe だったからか?
まあいいや。

Linux でやるときには nvm と direnv を組み合わせていたのだけど、 nvs ならこれだけで切り替えられるので便利そうだ。

 

あとはまあ、無意識のうちに nvm と打ち込んでしまうのが難点というかまだ慣れていないというかだな。

2022/02/26

速くなったPC (2022年)

数回に掛けて記事にしたデスクトップPCの置き換え作業。

hiro99ma blog: PCを作り替えたい(2022年)
https://blog.hirokuma.work/2022/02/pc2022.html

 

hiro99ma blog: 6年くらい経つとマザーボードを交換して起動ディスクを認識しないのかもしれない
https://blog.hirokuma.work/2022/02/6.html

 

hiro99ma blog: PCの入替はやはり大変だ(2022年)
https://blog.hirokuma.work/2022/02/pc2022_23.html

問題がなければ今回の記事で終わりだ。


まず、光るマザーボード&メモリについて。

私はてっきり光るのは「ゲーミング」というものだけだと思っていた。
CPUクーラーにも LED有無があるくらいだし、何も書いていないなら光らないだろう、そう思っていたのだ。
だって、マザーボードの名前が「Steel Legend」ですよ。お堅い名前ですよ。

・・・現実は非情であった。

image

光るというか、ぐりぐり光っている。ゲーミングの光り方だ。
イルミネーションだ!

写真には収まっていないがメモリも光っている。
装着前は「最近のメモリはヒートシンクもしっかりしてるのねー」なんて思って眺めていたのだが、その部分は LEDを光らせるためにあったのね。

 

イルミネーションだが、マザーボードの方は UEFI の設定で消すことができた。
まさか Advance の中の方にあったとは・・・。もっと表の方にあるかと思っていたよ。
メモリはユーティリティをインストールすれば制御できると思うが、まだやってない。

 

なんでわざわざ消すかというと、マザーボードに通電しているだけ、本体が起動していない状態でも光り続けるからだ。
組み立てた当日はケースのカバーを開けたままだったので、夜中に部屋がキラキラしていたものだ。
カバーをすればほとんど気付かない。

なら消さんでもいいやん、となりそうだが、見えないところで光ってもらうのが何だか申し訳ない気持ちになってきてね・・・。
ケースのカバーはもしかしたら透明な方がよいのでは?みたいな思考になってしまいそうな気がしたので、その世界に走らないように歯止めをしたのだ。

 

正直なところ、光る前までは否定的だったのだけど、実際光ってみると悪くないと思うようになった。
光る=ゲーミング=ゲームをする人向け、というイメージだったが、よく考えればゲーム中はかなり集中しているだろうから見ている暇はない。見るなら休憩中とかじゃなかろうか。何度やってもクリアできないときとか。

そうであれば、ゲームしていない人だって眺めていてよいはずだ。
むしろ休憩を取りにくいオフィスなんかでこそキラキラしているべきではないだろうか。
みんなの PCがキラキラしているオフィス。
キラキラ~キラキラ~

いや、キラキラは少ない人数で楽しむのがよいのかもしれない。


さて、前回組み立ての時にいろいろトラブルはあったものの、あれから問題はない。
いろいろ新規インストールすることになって面倒はある、多々あるのだが、面倒であって問題ではないのだ。

 

忘れていけないのは、そう、 PC が速くなったのだ。
そのために苦労した(+お金)のだ。

Cinebench というベンチマークアプリで計測したのだが、変更前が 3200 くらい、変更後が 13600 くらい。
桁が違いますわー。
そういえば前回のマシンはオーバークロックしてみてもよかったかな、と今さら思った。忘れていた。

ちなみに、ノートPC は 1700 くらいだ。
前のデスクトップの半分くらいの速度で動いているというわけではない。体感的にも。
なので、今年はこのノートPC のままでいてもよいかもしれない。


Android Studio のビルドも劇的に・・・とは言えないかもしれないが、短くなった。
Unity も試してみると良いのだろうが、もともとデスクトップPC では動かしていないので比較できない。ただこのノートPC でやるようなスペックじゃないだろうということはわかってきた。

以前は「終わりましたか?終わりましたか?」と上司に伺いを立てるような気分で待っていたが、今はそこそこ早く処理が終わるので「終わったか、なら待っておれ」みたいな心の余裕ができるようになった。まだキャッシュがなかったりしてダウンロードの時間がかかったりするものの、理由があって理不尽なわけではないので待つことができる。

 

そうね、問題といえるものではないが、以前使っていたパーツ類をどうしようかという残件がある。
なんたって、今週までは普通に使えていたのだ。いくらスペックの桁が違ったとしても、そこまで悪いものではない。
罪悪感・・・というと大げさだが、そんな気持ちだ。

かといって、また戻りたいかと言われると無理だ。
ああそうさ。私は自分勝手な生き物さっ。
そう偽悪的につぶやいて酒を飲むのであった。

2022/02/23

PCの入替はやはり大変だ(2022年)

PC を入れ替えるのは予定通りだったのだが、Windwos10 の起動ドライブを認識しなくなるのは予定外だった。

まあ、Windows の入れ直しと言っても、当面の開発なら Android Studio と VirtualBox があればなんとかなるね・・・というのが甘い考えだったことを認識して早数時間。

 

細かいところがいつもと違うのが非常にストレスになるので、そこに時間がかかる。
デフォルトで扱えるようになっているとこのコストが下がるのだが、もうダメだ。

バックアップから元に戻すならそこまで面倒ではないのだが、ゴミが残っている、という気持ちを持ったまま数年間すごすのも嫌なものだ。


失敗談の方が興味あると思うので、書いておこう。

  • DIMM が 4つあるうち、一番 CPUに近いところがクーラーとぶつかる
    • CPU に近い方から、A1, A2, B1, B2 となっていて、A1 が使えなくなった
    • A1-B1 で組、 A2-B2 で組ということなので、A2-B2 を使うようにした
      • これが次の悲劇を生む
  • 立ち上がらない
    • ASRock のマザーボードは Dr.Debug という 7セグの表示がある
    • 0d=メモリ関係ということだった
    • DIMM を挿し直してもダメ
    • A1-B1 に挿し直すことにする
      • CPUクーラーが干渉するので、取り外して 180度回転させれば良いだろう
      • あれ? CPUクーラーが CPUからはずれないぞ??
      • がんばって外すと、CPU ごと抜けた!
        • 幸いなことにピンは折れたり曲がったりしてなかった
      • CPU と CPUクーラーを引き剥がすのが大変だった
        • CPU のピンを触らないように、しかしかなり力を入れて CPU を回転
        • 少しずつ動いたので、回転と同時に移動させる
        • そうすることでグリスの影響を薄くしていくと、ようやくはがれた
        • 再度 CPUを挿して、グリスも継ぎ足してクーラーを付け直した
    • A1-B1 に挿し直すと起動した
      • でも、それってこれ以上増設できないと言うことになるのでは・・・?
  • 起動ドライブを認識してくれなかった
    • たぶん Legacy BIOS 向けになっていたからだろう
    • 別 PC で GPT に変換したけど認識してくれなかった。まだ何かあったのか。
    • あきらめて新規インストールした
  • 今まで HDMI と DVI でデュアルモニタにしていたのだが、DVI ポートがなかった
    • DisplayPort があったので、DisplayPort ケーブルを買いにいった
    • 1.4 対応だったので 1.4 のケーブルにしたのだが、1.2 のに比べると値段が倍くらい高い
    • PC とモニタの距離はそんなに離れてないと思って 1メートルのケーブルにしたが短かった...
    • ふだん、メインモニタが正面、サブモニタが右という並びにしているが、メインモニタ--PC 間では遠かったのでサブモニタにすることでかろうじて届くようになった
    • しかし、PC が DisplayPort の方をメイン出力にするので、何かあるとサブモニタの方に出力されるのがもどかしい。Windows のプライマリモニタを設定するとだいたいいけるのだけど、たまになんかある。
  • HDMI の方がなぜか 640x480 でしか認識してくれない
    • 本当はサブもメインも 1920x1080
    • 確かにモニタはそんなに新しくないのだが、一応はプラグアンドプレイ対応している
    • にもかかわらず 640x480 にしかならない
    • Radeon 関係でインストールしたアプリの中に解像度を作り出す機能があったので、それで対応した

 

いろいろありすぎだ。
おかげでインストールするものが全然終わらない。
本当に大変ですわ。

6年くらい経つとマザーボードを交換して起動ディスクを認識しないのかもしれない

パソコンの部品が届いた。

hiro99ma blog: PCを作り替えたい(2022年)
https://blog.hirokuma.work/2022/02/pc2022.html

せっせと組み立て、BIOS ... 今は UEFI というのか、その設定画面まで表示された。
あとは今まで使っていた Windows10 の起動ディスクを指定して立ち上げるだけ、と思っていたのだが、ドライブは認識しているもののどれもこれも起動ディスクとして扱われないようなのだ。唯一 DVDドライブが出てきた。

 

あれー、なんでー、といろいろ調べていると CSM なるものがあるそうだった。

【サポート情報】最新世代のマザーボードでのLegacy BOOTには注意しよう - ツクモ東京地区 店舗BLOG
https://blog.tsukumo.co.jp/tokyo/2020/09/legacy_boot.html

今回は B550チップセットのマザーボードにしたのだが、設定を見ると確かに CSM は無効になっていた。
じゃあ有効にしたらいいやんと思ったのだが、どうも項目が見当たらない。
Ryzen7 5700G なので、ここに書いてある「CPU内蔵グラフィックスを使用する場合~」のことが該当して有効にできないということだろうか。

 

あきらめた私は、Windows10 を新規インストールすることにした。
新しい酒は新しい革袋に、というわけではないけど、6年もあるとあれこれインストールしてはアンインストールしてを繰り返しているので、大量にゴミが残っていると思う。

そうだ、これは無駄な時間ではないのだ、きれいにするための必要な時間なのだ!

chocolatey を使ってインストールしているなら、export するとまとめてインストールできるそうだ。

Chocolatey Software Docs | Export
https://docs.chocolatey.org/en-us/chocolatey-gui/user-interface/main-window/actions/export

まあ、前環境で export してなかったけどね!!
ノートPC のがあるから多少はましだろう。

2022/02/20

docker いろいろ消したい

訳がわからなくなったり、全部無かったことにしたかったり、空き容量が足りなくて削除したくなったり、そんな気分になることがあると思う。

docker rm `docker ps -qa`
docker rmi `docker images -qa`
docker network rm `docker network ls -q`
docker volume rm `docker volume ls -q`

このくらいやれば、だいたい消えるんじゃなかろうか。

 

これは関係ないが、docker ps は横に長く出過ぎて見づらいことがある。
私のところでは Images のところが長いことが多いので、 --format で Images などを出さない docker ps を登録した。

docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Command}}\t{{.Ports}}"

これで「CONTAINER ID, NAMES, STATUS, COMMAND, PORTS」だけになる。

2022/02/19

PCを作り替えたい(2022年)

うちにはデスクトップPCとノートPCがある。
デスクトップPCは2016年の4月に部品を買って作った記録が残っていた。
そろそろ新しくしても良い季節ではないだろうか。


2016年の構成はこうだ。

  • CPU: Intel Core i5 6500BOX (3.20GHz/6M/C4/T4)
  • マザーボード: ASRock Z170 Extreme4(Z170 1151 ATX)
  • メモリ: DDR4-1700 8GBx2
  • 電源: ATX 550W
  • SSD: 240GB

ケースと電源は使い回してよいんじゃなかろうか。
これの1世代前のPCが残っていて、そのときはケースを買い直しているため、今は2つケースがあるのだ。
廃棄してしまえばよいと思いつつ、なんかこう踏ん切りが付かず物置として使われている(ケースの上が平たいので)。
ここでケースをまた買うと、たぶん捨てるのが面倒で増えるだけになってしまうと思う。

 

この構成だと Windows11 には対応していない。
TPM もないし CPU も対応外だ。
まあ、今の時期に買えばそういう心配はないだろうし、きっと Windows11 ready みたいな表記もあるんじゃなかろうか。

 

電源が心配な気もするが、まあなんとかなるんじゃないの?

 

SSD はちょっと気にしている。
メインの SSD は 2016年に買ったものだが、それ以外に HDD が 2つくらいと SSD が 2つくらい使っている。
フルバックアップ用に外付けUSB のもある。

HDD は Windowsの「ファイルの履歴」で割り当てているのと、ほとんど使わなくなったけど捨てて困るかもしれないデータを押し込めるのに使っている。使ってないけど余らせるのももったいないので接続しているという状況だ。
ファイルの履歴も、設定しているのを忘れているくらいには使っていない。パフォーマンスが落ちないなら有効に戻しても良いけど、開発で使っている限りでは git やクラウドに保存している方しか思いつかないので、昔ほど重要ではない。

サイズが異なる SSD にシステムを移動できるなら、2016年の SSD からコピーして使いたいというくらいかな。
Windows をインストールし直したい気持ちはものすごくあるのだが、また環境を作り直すというのも精神的につらい。


まずは CPU を決めねば。

ここ 2世代ほど Intel だったので、今回は AMD にしようか。
以前は Android Studio でエミュレータが高速に動かすには HAXM が~なんて考えていたけど、実機で動かすならどうでもよい話だ。

あと、最近思ったのは、意外と私がやってる作業って CPUパワーが必要なんじゃなかろうか?ということだ。
大したことをやってないからそこそこのパワーで良かろうと思っていたのだけど、コンパイルも並列でやったりしてようやく「普通」な時間で行えるようになっている

 

というところで考えると、Ryzen7 5700G とかだろうか。

AMD Ryzen™ 7 5700G | AMD
https://www.amd.com/ja/products/apu/amd-ryzen-7-5700g

AMD Ryzen 7 5700G BOX |パソコン通販のドスパラ【公式】
https://www.dospara.co.jp/5shopping/detail_parts.php?bg=1&br=10&sbr=1299&mkr=25&ic=474643&lf=0

ドスパラで 46,300円かー。
あ、グラフィックボードは買い足すつもりがないので G が付いたやつにしている。
これより 1つ下がると Ryzen5 5600G なのかな。

AMD Ryzen™ 5 5600G | AMD​
https://www.amd.com/ja/products/apu/amd-ryzen-5-5600g

AMD Ryzen 5 5600G BOX |パソコン通販のドスパラ【公式】
https://www.dospara.co.jp/5shopping/detail_parts.php?bg=1&br=10&sbr=1299&mkr=25&ic=474644&lf=0

33,300円と 13,000円お安い。
ただまあ、これも 5年くらい使うんだろうからケチらない方がよいだろう。


マザーボードというものもあるが、AMD の Ryzen だと選択肢が Socket AM4 しかないので探しやすい。
まあ、数はたくさんあるんだけど少なくとも動かないことはないだろう。

チップセットは B550 と X570 というのが並んでいる。
数字が大きい X570 の方が新しいかと思いきや、 B550 の方が新しいようだ。

ソケットAM4チップセット | AMD
https://www.amd.com/ja/products/chipsets-am4

Ryzen 5000シリーズはどちらでもよいそうだ。

よくわからんが・・・ B550 でよいのではなかろうか。新しい方だし。
でも X570 の方が全体的に値段が高めなので性能も高めなのだろうか。
たぶんどれを選んだとしても、あとから違いに気付くとは思えない私であった。。。

なので、わかりやすくインターフェースだけで考える。
Type-C はほしいかな。できれば背面に。
あとは SSD の M2 も使ってみたい。「M.2」と間にドットが入るのか。

M.2 SSD はなんとかなりそうだが、Type-C の方があまりなさそうだ。
今使ってる ASRock のは Type-C が付いているようなので、それでよいかな。

どれを選んだとしても、メモリは DDR4 なのは同じだけど PC1700 はサポートしていないようだ。
だからメモリも一緒に買うことになる。
M.2 SSD を使うならそれもだ。
あああ、お金がかかることだよ。

B550 の ASRock というところまで絞ったところ、Steel Legend と PG Riptide との 2つがあてはまった。
もう違いが分からないけど、Steel Legend は耐久性を考慮しているようなので、長いこと使うつもりならこっちにしておくのが無難なのかな。
むかし、マザーボードのコンデンサから液漏れして買い替えたことがあるので、耐久性は気になるのだ。


あとは適当に選ぼうと思ったが、M.2 SSD は買ったことがないので値段を見ておこう。

SSD、ソリッドステートドライブ、ハイブリッドハードドライブ-ドスパラ
https://www.dospara.co.jp/5pc_parts/shopping/br115/

同じサイズと仕様っぽく見えても値段がいろいろある・・・。

1TB くらいなら、書込速度が 5000MB/s くらいだと 2万円付近というのが相場のようだ。PCIe 4.0 だとその速度が出せて、 PCIe 3.0 だと 3000MB/s くらいになるようだ。
500GB ならその半分かというと、どうもこのサイズだと 5000MB/s というのが出てこない。

 

B550 はそもそも PCIe 4.0 に対応しているんだろうか?

  • 1 x Hyper M.2 Socket (M2_1)
  • 1 x M.2 Socket (M2_2)

うーん、M2_1 の方は 64 Gb/s or 32Gb/s、M2_2 の方は 16Gb/s という読み方で良いのかな?
Gen4x4 とか Gen3x2 とかがそういうもののように書いてある。

PCIe 4.0 のほうは大体 5000MB/s だが、PCIe 3.0 はまちまち。
500GB くらいあれば事足りるのだが、それは今だけかもしれないから 1TB にするべきか・・・。
ここでケチってもなあ、でもストレージって消耗品だからなあ、でも途中で別のにコピーしたりする手間は嫌だなあ・・・

金額と手間の間で悩む私であった。

 

メモリは、32GB でほどほどならよいかな。
G.Skill という会社のは初めてだが、そんなに悪いものでもないだろう。
同じ G.Skill社の DDR4-3600 でも、

の3つが並んでいてあせった。
たぶん 19, 16, 18 はレイテンシーだから 16 のが一番高いのだろう。そこまで気にしないので一番安い 19 のでよかったのだけど、QVLページに AMD が載っていないので 3番目のにしよう。


では。

くぅ、消費税も加えると 11.5万円くらいか・・・。
あ、価格が税込みだった。10.4万円くらいだ。

ノートPC を購入すると思えば安いものだが、しばらくするとノートPCも買わねばならんだろう。
いや、いつも同じ時期に両方とも買い替えるから、どちらも同じようなスペックになって、同じような時期に買い替えないといけなくなってしまうのだ。

よし、当面はノートPC の買い換えは止めておこう。後のことは分からんが、今のところは止めておこう。

2022/02/14

LXQtのメニューカスタマイズメモ

メモです。個人メモです。

Lubuntu 20.04 で LXQt を使っている。メニューをカスタマイズした。

image


大元のファイル?

/etc/xdg/menus/lxqt-applications.menu

個人用?

$HOME/.config/menus/lxqt-applications.menu

Configure "Applicationi menu" で指定するファイル

image

image

$HOME/lxqt-applications.menu というファイルはないので自作したと思われる(記憶にない)。
/etc の lxqt-applications.menu をコピーしてきたようだ。

 

.config の menu ファイルは /etc の menu ファイルを Include した上で設定をしているようなので、 /etc の方を編集したくないからコピーして持ってきたのだろう。

$HOME/.local/share/applications にランチャーの設定ファイルを置くと反映してくれたようだ。

2022/02/13

[golang] testing

コードを書いたら極力テストは行うべきだ(戒め)。
というわけで、golang のテストを調べる。

過去の私もいくらかテストについては調べていたようだ。

hiro99ma blog: [golang]本体無しでテストをしたい (1)
https://blog.hirokuma.work/2020/03/golang-1.html

しかし、もう記憶にない。

最近は fuzzing というのもあるようだが、golang v1.18 以降らしいので扱わない。


まず、コード以外のルールから。

  • ファイル名は _test.go で終わるようにする
    • そうすると go build の対象にはならず go test の対象になる
  • "testing" を import する
  • 関数名は "Test" で始まるようにする
    • そうするとテスト関数という扱いになる
  • 関数名で "Test" の次は大文字で始める

関数名はともかく、ファイル名は気をつけねば。テスト用じゃないのに _test.go と付けてしまうことがあり得なくもないからだ。golang って大文字小文字ルールもそうだけど、名前で決められていることがしばしばあるからあせるね。

あれ、golang の関数名は UTF-8 を使えるのだろうか?
使える場合、日本語なんかは大文字扱いされるのだろうか?

 

main.go

01: package main
02: 
03: import (
04:     "fmt"
05: )
06: func よしお() string {
07:     return "よしお"
08: }
09: 
10: func main() {
11:     fmt.Printf("%s\n", よしお())
12: }

main_test.go

01: package main
02: 
03: import "testing"
04: 
05: func Testよしお(t *testing.T) {
06:     yoshio := よしお()
07:     if yoshio != "よしお" {
08:         t.Error(`not yoshio`)
09:     }
10: }

$ go test -v
=== RUN   Testよしお
--- PASS: Testよしお (0.00s)
PASS
ok      github.com/hirokuma/go-test1    0.012s

よいらしい。
t.Error() の中がバッククォートになっているが、これは本でそう書いてあったからだ。別にバッククォートである必要はない。
JavaScript だとバッククォートなら ${xxx} みたいにして変数を展開できるが、golang だと bash のヒアドキュメントみたいにそのまま展開されるというだけのようだ。 raw string literal というらしい。

 

ちなみに、Test の次を小文字にするとテスト関数と見なされず実行されなかった。
一時的に実行したくない場合なんかによいかもしれぬ。

 

あと、本に書いてあることで興味があるのはカバレッジだろうか。
ただ載っているとおり -run=Coverage だとテストが実行されなかった。

$ go test -v -run=Coverage -coverprofile=c.out
testing: warning: no tests to run
PASS
coverage: 0.0% of statements
ok      github.com/hirokuma/go-test1    0.003s

-cover だと実行された。

$ go test -v -cover -coverprofile=c.out
=== RUN   Testよしお
--- PASS: Testよしお (0.00s)
PASS
coverage: 50.0% of statements
ok      github.com/hirokuma/go-test1    0.003s

結果は、載っているとおりに実行するとブラウザが立ち上がった。

go tool cover -html=c.out

image

まあ、main関数は仕方ない。

と思ったが、main関数もテストできるのか。

Test the main function in Go | GO.into Development
https://mj-go.in/golang/test-the-main-function-in-go

main関数は特別なものだと思っていたが、go test なら普通に呼び出せるのか。

func TestMain(t *testing.T) {
    main()
}

普通に呼べた。

image

 

go test できれいにテストを回したいなら、実装の方も多少はテストを意識して実装する必要があるだろう。
めんどくさいという気もするが、その方が実装も小さい単位になってメンテナンスしやすくなることも多い。そこまで悪くない話だと思っている。
main関数も、中に全部書いてしまうのではなく本体は別関数にして戻り値をテストしやすくする、みたいな。

私はそこら辺が苦手な気がする。
なんというか、見える範囲に揃っていないとよくわからなくなるというか。
コース料理よりも丼にいろいろ載っている方がうれしいというか。
誰に言い訳してるんだ、私は。


私が作ったことがある golang のテストは、RC-S370/S のエンコードくらいだった。

go_pasori370/msg_test.go at master · hirokuma/go_pasori370
https://github.com/hirokuma/go_pasori370/blob/master/dev/msg_test.go

よく見ると t.Fatail を使っているな。
t.Error は継続し、t.Fatal は止めるようだ。
私は途中で止めてしまいたいのだが、一通り全部通してみたいと考える方が普通なのかもしれないがどうなんだろう?

なるほど、最初のエラーで止めるオプションがあるのか。

unit testing - Stop on first test failure with `go test` - Stack Overflow
https://stackoverflow.com/questions/32046192/stop-on-first-test-failure-with-go-test

Testよしお() で失敗するようにして試してみよう。

まずは普通に実行すると、Testよしお() も TestMain() も実行されている。

$ go test -v
=== RUN   Testよしお
    main_test.go:8: not yoshio
--- FAIL: Testよしお (0.00s)
=== RUN   TestMain
よしお
--- PASS: TestMain (0.00s)
FAIL
exit status 1
FAIL    github.com/hirokuma/go-test1    0.014s

これを -failfast オプションを付けると、 TestMain() は実行されていない。

$ go test -v -failfast
=== RUN   Testよしお
    main_test.go:8: not yoshio
--- FAIL: Testよしお (0.00s)
FAIL
exit status 1
FAIL    github.com/hirokuma/go-test1    0.003s

開発後半になって、テスト実行にものすごく時間がかかるようになった場合なんかによいのかもしれない。


直接 go test とは関係ないのだが、どこでエラーが起きたかの根源を知りたいことは多い。
error を返すようにしたとして、"InvalidParam: -20 < 0" とか返されたとしても困るのだ。
コマンドを実行してエラー、とかなら因果関係がわかりやすいのだが、サーバー的なプログラムでログの中にエラーが残っていたとしても追跡できなくては意味が無い。

がんばって fmt.Errorf() なんかで書いていくのだけど、まあ面倒だ。
エラーにした理由はもちろん、自分のパッケージ名や関数名を書かないと誰だか分からないからだ。
そしてそれをログにも出すのか return するだけなのかも結構悩む。その関数が A からも B からも呼ばれるようであれば自分の情報を返すだけではなく、呼び出し元の方でも何かやってもらわないと追えないからだ。ログに出せば間違いはないのかもしれないが、ログがたくさん出るというのもあまりうれしくない。

 

今までどうしてきたかというと、組み込み開発だとそもそもログを出せる状況にないことがほとんどだったし、文字で出せないからビットのパターンで表したりとかしてたしね。エラーになっても仕方ないのでそもそもリセット掛けて再起動するし。
そんなわけで、私のエラー処理は初心者レベルだと認識している。
精進がいりますな。

[golang] interfaceの勉強

go.mod をだいたいわかったつもりでいたけど、go mod tidy してモジュールが見つかりませんと言われると自信がなくなりますな。
はい、忘れるために別の勉強をしましょう。


interface は class とセットで存在するイメージだったのだが、golang には class はない。予約語にもない(どうでもいい話だが、予約語は英語だと"keywords"なので検索しづらい)。
とはいえ、C++ では class と struct が姉妹みたいなものなので違和感はない。

 

プログラミング言語Goの例であげられているのは io パッケージの Writer
短いので貼り付けよう。

type Writer interface {
	Write(p []byte) (n int, err error)
}

Write という名前で、引数として []byte を持ち、戻り値が (int, error) という構成になっていればよいということになる。
ただ、

func Write(p []byte) (n int, err error) {
  return 0, nil
}

みたいな「関数」だとダメだというか、意味が無いと思う。

func (x SomeStruct) Write(p []byte) (n int, err error) {
  return 0, nil
}

のように「メソッド」になっていないとありがたみがないだろう。
メソッドになっているから、複数のメソッドがあるけど interface が同じだから呼び出すことができる、という使い方になるだろう。

 

他の言語では、interface が先にあって、その interface を持つ class を実装することを明示的に書くことが多いと思うが、Go言語は明示的に書かないようになっている。
コードの検索をするときには探しづらいのだが、実装しているときにはあれこれ書かなくて良いので便利なのかもしれない。

明示的に書かなくて良いので、全然 interface を考えずに実装していたメソッドを interface になっているようなつもりで呼ぶことができる。本では「暗黙的に満足される」と書いてある。

 

あとは、宣言した interface 型を組み合わせたり含んだりする interface を作ることもできるということと、中身に何も書かない空インターフェース(empty interface)も作ることができるというくらいか。


というだけにしては本のページが多いので、何か気をつけることがあるのだろう。

 

まず、 empty interface。
これは C言語の voidポインタみたいな感じで何も要求しない interfaceだ。

package main

import (
    "fmt"
)

type dummy1 struct {}
func (d *dummy1) Print(param interface{}) {
    fmt.Printf("dummy1 int: %d\n", param)
}

type dummy2 struct {}
func (d *dummy2) Print(param interface{}) {
    fmt.Printf("dummy2 string: %s\n", param)
}

type dummys interface {
    Print(param interface{})
}

func main() {
    d1 := &dummy1{}
    d2 := &dummy2{}
    d  := []dummys{d1, d2}
    d[0].Print(123)
    d[1].Print("abc")
}

最初は dummy1.Print は param int、dummy2.Print は param string にして「interface{} を引数にしておけばなんでもいけます」みたいな例にしようとしたのだが、それだとコンパイルエラーになった。
interface の中の interface{} は、そのまま interface{} として実装されないといけないようだ。まあ当たり前か。

 

あとは使い方の注意点や型アサーションのことや助言などが書かれている。


empty interface が int や string のような基本型もとれるということは、最初に書いたようなただの関数であっても interface を使って活用させる方法があったりするのだろうか?

でも、あったとしてもあんまりわかりやすいことにはならない気がするので、気にしないことにしよう。

2022/02/12

Android Studioが軽くならないだろうか(WindowsでReact Native)

会社で、私と同僚が同じ Android Studio のプロジェクトを操作しているのだが、どうも同僚の方が動作が速いようだ。
どうも、というレベルではなく、あからさまに違う。
私は Windows10、同僚は MacOS。

まあ、マシンスペックは私の方が低いのである程度は仕方ないのだが、分単位で違うほどの差はないと思っている。
軽くならないだろうか。

ちなみに、素の Android 開発ではなく React Native を使っている。


まずは Microsoft のこちら。2022年2月12日更新だから最近だ。

Android 用の Windows Defender の例外を追加する | Microsoft Docs
https://docs.microsoft.com/ja-jp/windows/android/defender-settings

そこからも参照されている Android のこちら。

Android Studio の設定  |  Android デベロッパー  |  Android Developers
https://developer.android.com/studio/intro/studio-config#antivirus-impact

あとは JetBrains のこちら。

Slow startup on Windows: splash screen appears in more than 20 seconds – IDEs Support (IntelliJ Platform) | JetBrains
https://intellij-support.jetbrains.com/hc/en-us/articles/360005028939-Slow-startup-on-Windows-splash-screen-appears-in-more-than-20-seconds

いずれも Windows 標準のウイルスチェックから除外する方法だ。
プロジェクトは別のディレクトリでやってるし、私のところでは存在しないディレクトリもあったのでこんな感じになった。
Android Studio はバージョンごとのディレクトリにせず、せめて AndroidStudio ディレクトリを作ってその下に置いてほしかったものだ。

image

 

これでビルドしてみたのだが、うーん。。。

そもそもどこに時間がかかっているのか見ていなかったのだが、ビルドのボタンを押して終わるまでに 55 秒かかっていて(新規ではないビルド)、50秒くらいは何もログが出ないのだ。
タスクマネージャーで見ると node.exe ががんばっている。
ということは、gradle とか Java とかの前の段階で時間がかかっているのか?


同じ要領で node.exe を除外対象に追加した。
そうすると 55 秒 →50 秒に短縮された。
ならば少なくとも最初に時間がかかっているのに node.exe が影響しているようだ。

普通の Android なら node.exe は使わないと思うので、React Native ならではの事情だろうか?
以前作った QRコードアプリで試してみると、うん、node.exe は起動されず java.exe が動いている。
それにビルド自体も 3 秒くらいで終わった。
React Native でのビルドが遅いということで間違いなかろう。

 

Windowsの「リアルタイム保護」をオフにしてみたが、速度は変わらなかった。
npm のキャッシュディレクトリみたいなものがあるのかと思ったが、グローバルでインストールしているものが無いので影響が無いのかもしれない。あるいはリアルタイム保護だけではないとか。


他のアプリを終了させて↑と時間が変わってきた。
今は 39 秒くらいで、node.exe が働いているのが 34 秒くらい。

これを Android Studio の Build タブに出ていた「Build Analyzer」で見てみると、ビルドは 22 秒だったことになっている。
そのうち 17.5 秒が Build configuration という時間だったようで、これが最適化できるらしい。

Configuration cache
https://docs.gradle.org/current/userguide/configuration_cache.html

Android Studio ではなく gradle なのか。
それはよいとして、メッセージに「Android Gradle plugin supports Configuration cache from 7.0.0. Current version is 4.2.2.」と出てきた。
AGP ってやつね。

image

じゃあ上げれば良いかというと、だいたいそうはいかんのだ。
Android Studio もプロジェクトを起動して Gradle Plugin のバージョンが最新じゃなかったら通知してくるのだけど、それは罠だ。
プロジェクトを作ったときのバージョンから言われたとおりに変更すると、だいたいろくなことがない。

試しに 7.0.0 にしてみたら・・・ほら、やっぱりダメだ。
React Native のバージョンでいろいろ決まっているので AGP のバージョンだけ変えるなんてことは難しいのだ。

17.5 秒短くなった世界を見てみたかったが、私の環境では無理そうだ。
まあ、夢は少し残してあるということにしておこう。


React Native と Winwdows の観点で調べ出すと、またいろいろ出てきた。

React native run android terribly slow · Issue #27898 · facebook/react-native
https://github.com/facebook/react-native/issues/27898

React Native 0.63.3 is extremely slow · Issue #30403 · facebook/react-native
https://github.com/facebook/react-native/issues/30403

前者は Windows で後者は Mac だった。
うーん、React Native のバージョンで違いが出てると言うこともあり得るのか。

効果があるのか分からないが、 .gradle\gradle.properties に設定をした。
vfs.watch は Issues から、 UseParallelGC は Android Studio でビルドした内容からだ。

org.gradle.vfs.watch=false
org.gradle.jvmargs=-XX:+UseParallelGC

 

私の環境も、さっきは 50 秒だの 39 秒だの書いているが、あれは何も変更していない状態でビルドボタンを押しただけの場合だ。リビルドすると 5 分くらいかかる。
5 分くらいかかる中で 20 秒くらい縮まってもあまりありがたみがない。

React Native だから開発の本体は JavaScript 側でやるため、実はそんなに Android Studio を触ることはない。 Android Studio を使うのはネイティブじゃないとできないことをやったりする場合くらいだ。
そして、私の担当はそういう箇所である。

 

私の事情は良いのだ。
React Native を Android で使っていても Android Studio というか gradle ビルドというかをしばしば行わないといけない人がいると言うことさえわかってもらえば良いのだ。

2022/02/06

Unityは勉強しないとよくわからない

初めて Quest2 での開発をチュートリアルを見ながらやったとき、ものすごく大変だった。

hiro99ma blog: VRゴーグルを買いました
https://blog.hirokuma.work/2022/01/vr.html

ダウンロードやビルドに時間がかかるのは待っていればまだ我慢できるのだが、設定項目が多すぎる。
チュートリアルの内容が Quest2 の一般的な設定だとは限らないのだが、少なくとも Android の設定などは変わらないはずだ。

なので、自分用のプロジェクトテンプレートを作っておきたい。


参考にするのはこちら。

TKSGのゲーム作成部屋ブログ: Unityで自作のテンプレートを作成した話
https://tksg-game.blogspot.com/2022/01/unity_15.html

tar で展開して置き換えるだけ・・・と思って読んでいたのだが、かなりめんどくさそうだった。
本家のドキュメントへのリンクも載せておこうかと思ったが、出てこなかった。
日本語にしてくれて感謝である。

 

その前に、元になるアプリを作らねば。


テンプレートにするのだから、もう少しVRっぽい中身にしておきたい。
「初めてのアプリ作成」の次が「コア開発ブロック」なので、そこを見ていけば良いのだろうか。

パッケージコンポーネントについて | Oculus開発者
https://developer.oculus.com/documentation/unity/unity-utilities-overview/

OVRCameraRigを使用してカメラリグを追加する | Oculus開発者
https://developer.oculus.com/documentation/unity/unity-add-camera-rig/

OVRCameraRig というものを追加するときに Main Camera というものを削除するそうだ。
どれかわからんかったのだが、Camera Offset みたいなグループの下にあった。
両方追加すると画面が真っ暗で何も出てこなかった。

 

カメラと手に持つコントローラの位置関係がよくわからん。
仕事で作る人はすごいわ・・・。

床を作ると水平線が見えるような感じになるのだが、メガネ屋さんで視力検査するあれを思い出してしまう。
気球とかが浮かんでいるあれだ。
カメラを片目ごとに設定できたりもするようなので、うまく作ると乱視でうまく画像が見えてない私でも一致するようにできるのかもしれない。

そんなこんなして、ボールが浮かんでいるだけのアプリができましたとさ。

image

うーん、Unity は勉強しないと使い方がさっぱり分からんね。


では、あとはサイトの人のやり方をまねすれば良い。。。
と甘く考えていた。

今回作ったプロジェクトは「VR」というテンプレートを使ったのだが、それがフォルダにない。

image

あ、前のバージョンで作った後に Unitiy Editor のバージョンを上げたからダウンロードされていないだけか。

ダウンロードしたテンプレートは %APPDATA%\UnityHub\Template の中にあるようだ。
あせった。

まねして tgz を作って、同じく %APPDATA% の方に置いたのだがどうやっても読み込んでくれない。
Program Files 側に置くと読んでくれたので、ネットからダウンロードするテンプレートについては何か管理方法があるのだろう。残念。

 

作った後で思ったけど、プロジェクトをまるまるコピーしてもよかったんじゃないかと思った。
ただ、コピーだと時間の短縮にはなるかもしれんが、プロジェクトのサイズがネックだ。コピーする時間がかかるかもしれんね。

Unityは毎月アップデートがあるのか

Unity Hub を起動するとアップデートがあるようなことをいわれた。
先週インストールしたばかりなのにと思ったら、どうも毎月アップデートされるようだ。

https://unity3d.com/get-unity/download/archive

image

しかもアップデートといってもインストールの追加なのだ。
なので非常に時間がかかる。
そしてインストール後にプロジェクトを開くとバージョンアップの動作が行われるので、またここでも時間がかかる。

あんまり頻繁にアップデートするようなツールではないのかな?
しかしリリースノートにはけっこう書いてある。

What's new in Unity 2020.3.27 - Unity
https://unity3d.com/unity/whats-new/2020.3.27

基本的にはアップデートした方がよいのだろうけど、Known Issues とかの内容によりけりなのかな。
新たにインストールされているところを見ると、バージョンで挙動が気になることがあるのかもしれない。

 

Oculus Developer もアップデートされたようだが、これは Oculus Developer Hub のことかな?
起動したらアップデート通知が出ていたので実行したが v37 という数字ではなかったと思う。
Unity の Store からインストール?していた Oculus Integration は v37 になるアップデートがあった。

Oculus Developer Release Notes: v37
https://developer.oculus.com/blog/oculus-developer-release-notes-v37/

これもまた毎月行われるのだろうか・・・。


今日はだらだらと復習するだけなので、特に進捗は無い。

作ったプロジェクトのサイズを見ると 1つで 1GB 以上あった。 Avatar2 を使ったプロジェクトなんか 3GB 近くあったように思うので削除してしまった。

ストレージが足りないだけなら外付けにしようかと思ったのだけど、パワーも足りてないので PCの買い換えを考えてしまいますな。

[golang] errorをどうするとよいのか

処理をしていて期待にそぐわないことになるならエラーを返すだろう。
golang もそうだ。

 

golang には error 型というものがある。
「プログラミング言語Go」の p.226 も error インターフェースの節が振られている。

type error interface {
	Error() string
}

あれ、string 型なのが決まってるし、それ以外の型はないのかい??

使い方としては、 errors を importしておいて、 errors.New("もじれつ") でオブジェクトというかインスタンスというかを作るようだ。


文字列というのは非常に扱いづらいと思うのだ。
特にエラーとなると、それを受け取った方がエラーの種類に応じて動作を変えたいだろう。
その判定が文字列だとすると、エラーの内容を親切にしただけで今までのプログラムが動かなくなる可能性もある。
数字であれば、エラー値を変更しなければ判定文は動作するだろう。

 

よく見るのは、戻り値をタプルにして 2番目の戻り値が非nilだったらエラー、というパターンだ。 OK か NG かだけだたらタプルじゃなくて普通に結果を返すだけだろうが、まあそんな感じだ。
しかし、エラーハンドリングを文字列でやるというのもなんだか怖い。さっきも書いたが文字列の内容を書き換えただけで困ることになるからだ。

まあ、エラー処理についてはただ 1つだけの正解というものはなくて、エラー戦略をどうするかだと思っている。
じゃあその戦略をどうするかっていうことになるのだけど、そこは言語の得意・不得意もあるし、アプリの種類にもよるしで決定しづらい。


Go言語は try-catch がないので大局としては C言語と同じようなことになるんじゃなかろうか。
C言語では戻り値が1つしかないので、0を戻すと正常、trueを戻すと正常、NULL以外だと正常、などといろいろなパターンがあり、言語として決められたルールはなかった。
だいたい、0 が「偽」として扱われるのに 0 が正常というのはときどき扱いが悪かったのだけど、標準ライブラリはそうなっていることが多いので悩んだものだ。

 

よく Go言語の戻り値などで使用されている error はこちら。

https://go.dev/ref/spec#Errors

ただ、これは明示的な本体があるものではなく、 Error() という string を返す関数を持つという interface が用意されているだけだ。冒頭で書いたやつですな。

チュートリアルでは errors.New() で error を作っている例が出ていた。

Return and handle an error - The Go Programming Language
https://go.dev/doc/tutorial/handle-errors

固定文字列ならこれでよいのだけど、文字列を作りたい場合は fmt.Errorf() を使うとよい。

自分の error を作りたいなら、適当な構造体を用意して Error() を持たせるとよさそうだ。

01: package main
02: 
03: import (
04:     "errors"
05:     "fmt"
06: )
07: 
08: type MyError struct {}
09: func (e *MyError) Error() string {
10:     return "my error"
11: }
12: 
13: func func1() error {
14:     return errors.New("my error")
15: }
16: 
17: func func2() error {
18:     return &MyError{}
19: }
20: 
21: func main() {
22:     err1 := func1()
23:     err2 := func2()
24: 
25:     if err1 == err2 {
26:         fmt.Printf("same!\n")
27:     } else {
28:         fmt.Printf("not same!!\n")
29:     }
30: }

MyError 型を作った。
Error() で返す文字列は同じでもオブジェクトが異なるので else のルートを通る。
そりゃそうだ。

 

では文字列で比較するしかないかというとそうではなく、型アサーションでチェックするというやり方があるそうだ。
下の例ではどちらも Error() があるので error 型であるというのは一致するのだが、MyError 型かどうかで不一致になる。

01: package main
02: 
03: import (
04:     "errors"
05:     "fmt"
06: )
07: 
08: type MyError struct {}
09: func (e *MyError) Error() string {
10:     return "my error"
11: }
12: 
13: func func1() error {
14:     return errors.New("my error")
15: }
16: 
17: func func2() error {
18:     return &MyError{}
19: }
20: 
21: func main() {
22:     err1 := func1()
23:     err2 := func2()
24: 
25:     if _, ok := err1.(error); ok {
26:         fmt.Printf("err1 is 'error'\n")
27:     } else {
28:         fmt.Printf("err1 is not 'error'\n")
29:     }
30:     if _, ok := err1.(*MyError); ok {
31:         fmt.Printf("err1 is 'MyError'\n")
32:     } else {
33:         fmt.Printf("err1 is not 'MyError'\n")
34:     }
35: 
36:     if _, ok := err2.(error); ok {
37:         fmt.Printf("err2 is 'error'\n")
38:     } else {
39:         fmt.Printf("err2 is not 'error'\n")
40:     }
41:     if _, ok := err2.(*MyError); ok {
42:         fmt.Printf("err2 is 'MyError'\n")
43:     } else {
44:         fmt.Printf("err2 is not 'MyError'\n")
45:     }
46: }

err1 is 'error'
err1 is not 'MyError'
err2 is 'error'
err2 is 'MyError'

 

標準パッケージの os はエラーの種類が多そうだけど、それぞれ type を定義しているのだろうか?

https://cs.opensource.google/go/go/+/refs/tags/go1.17.6:src/os/error.go

固定のエラーは var でやっているようだ。
ErrInvalidfs.ErrInvalid で、fs.ErrInvalid は errInvalid()oserror.ErrInvalid を return していて、最終的には errors.New() になっている。遠い。
このタイプは type が定義されていないが var で与えられているから os.ErrInvalid と比較すればよいだろう。
型アサーションを使っての比較は fmt.Errorf() を使いたいようなエラーの場合だけだろうか?

エラーが比較するタイプなのか型アサーションでチェックするのかは実装を見ないと分からない。
まあ説明文はあるかもしれないが、あんまり実装側が考えたいところではないだろう。
osパッケージの場合にはヘルパー関数が用意されている。

他にもあるのかもしれんが同じページで Is の関数はこれらだった。
IsTimeout() 以外は underlyingError() が呼ばれていて、switch文で型アサーションをしていた。そんな書き方ができるのか。型switch文というものらしい。

01: package main
02: 
03: import (
04:     "errors"
05:     "fmt"
06: )
07: 
08: type MyError struct {}
09: func (e *MyError) Error() string {
10:     return "my error"
11: }
12: 
13: func check(target interface{}) string {
14:     switch target.(type) {
15:     case *MyError:
16:         return "MyError"
17:     case error:
18:         return "error"
19:     default:
20:         return "unknown"
21:     }
22: }
23: 
24: func func1() error {
25:     return errors.New("my error")
26: }
27: 
28: func func2() error {
29:     return &MyError{}
30: }
31: 
32: func main() {
33:     err1 := func1()
34:     err2 := func2()
35: 
36:     fmt.Printf("err1 is '%s'\n", check(err1))
37:     fmt.Printf("err2 is '%s'\n", check(err2))
38: }

err1 is 'error'
err2 is 'MyError'

便利だね。


で、ここからは私の都合だ。

gomobile というもので Android のライブラリを作っているのだが、制約がいろいろある。
書いてある場所を探せなかったのだが、引数や戻り値で使用できる型がある程度決まっているし、戻り値は 1つか2つ、2つの場合でも 2番目は error のみとなっている。
error を返した場合は Android側でも exception として扱ってくれるようだ。

で、だ。
Android 側に行ってしまうともう型アサーションなんかは使えないし、もちろんオブジェクトの比較もできないだろう。
となると、やっぱり文字列で判定するしかないという状況なのだ。

見つけた。 gobind の方だった。

Type restrictions
https://pkg.go.dev/golang.org/x/mobile/cmd/gobind#hdr-Type_restrictions

error がどういう扱いになるかは書かれていなかった。
じゃあもう文字列で考えるしかないだろう。

 

うん、この考察は一般には関係ないことだった。
異なるプラットフォームを行き来する場合には便利な機能が使えないこともあるよ、ということで。

[golang] 制御文(C言語の人から)

最近 golangを使うことが多い。
比較的 C言語に近いのだが、同じではないので調べ調べというところだ。

「プログラミング言語Go」を買ったのだけど、制御文についてはまとまった章で説明されていないので困っている。
自分でまとめておこう。


更新日:2022/02/06

 

if : ある

 

プログラミング言語Go: p.24, 238, 10, 24, 53
if statements

 

基本

if 条件 {
  xxx
}

if 文; 条件 {
  xxx
}

else類

} else if あああ {
  xxx
}

} else {
  xxx
}

 

備考

条件を () でくるむ必要はない。
文が書けるのは C言語っぽいが、宣言した変数の影響範囲=スコープはそれ以降のif内までなので C言語より狭い。
まあ、C言語だとその場で宣言できないから比べられないが。

C言語風に、先に変数を宣言してから if文で使ってもよいのだろうが、そうするとスコープが外れにくくてガベッジコレクションしにくくなるとかかもしれない。


for : ある

 

プログラミング言語Go: p.6, 52
for statements

基本

for 条件 {
  xxx
}

for 初期化; 状態; 後処理 {
  xxx
}

for レンジ表現 {
  xxx
}

備考

p.6 に「複数の形式がありますが次はその一つです」とあるが、じゃあ p.52 に他の形式の説明があるのかと思うとそうではない。そもそも p.52 は forの説明じゃなくてスコープの説明だし。
たぶん私がこの記事を書こうと思ったのも、forについてまとまった説明がなかったからだと思う。

しょうがないので言語仕様を見る。

  • with single condition
  • with for clause
  • with range clause

"with for clause" が C言語風の表現だ。

"with single condition" は while に近い。つまり繰り返し条件だけを書く。

"with range clause" は多彩なようだ。多才というのがよいのか。
文は1つだけしか書けないようだから "with single condition" に近いのかもしれない。
ただ "range" という識別子を使うからそう呼ばれるのだろう。


while : ない

for で代用


do-while : ない

代用するものが無いので、for でまかなうようにするしかないだろう。


switch-case : ある

 

プログラミング言語Go: p.26, 53, 243, 244, 246, 379, 27
switch statements

基本

switch 評価値 {
case 一致1:
  xxx
case 一致2:
  yyy
default:
  zzz
}

switch {
case 一致1:
  xxx
case 一致2:
  yyy
default:
  zzz
}

備考

書きたいことを書いておこう。

  • case ごとの break が必須ではない(break しなくても fallthrough しない)
    • fallthrough があるらしい。識別子のようだけど説明があまりない。
  • 文字列も使える

まあ、C言語でも fallthrough によるバグはお手本のように出てくるから、言語でなくすのも理解できる。

評価内容を書かずに switch を使えるなら if はいらないんじゃないのという気もする。まあ、そんなことをいえば C言語だって switchなくして if だけでいいやんってことになるのだけど。

 

Type switches

プログラミング言語Go: p.243
Type switches

基本

switch target.(type) {
case nil:
  xxx
case int, uint:
  xxx
case *MyType:
  xxx
}

説明

switch文の一種と見なしてよいのかどうかわからない。if文でも書けるのだが、switch文でやった方がわかりやすい。
型がなんなのかわからない変数の判定に使うときの書き方だ。
C言語の ... を解釈するときのやり方みたいなイメージだが、ちゃんと自前の型でもチェックできる。
例はリンク先を見てもらった方が良かろう。

 


三項演算子 : ない

"Go言語はシンプルだ"という評判を聞いたとき、心配したのは三項演算子だ。
そう、わかる。
三項演算子というのはわかりづらい演算子だということはよくわかるのだ。
そもそも if などで十分対応できるものだし、なぜ三項演算子が生き残る理由があるというのだろうか?
いや、ない。
だから Go言語にも三項演算子はない。

しかし・・・納得はしつつも存在して置いてほしかったという個人の感想は消え去ることができない。
三項演算子を許容すると、さらにその中に三項演算子を入れ込んで、という状況を生んでしまうからきりがない。
そういうのを頭で理解しても、やっぱり三項演算子はほしかったなー、と思ってしまうのは C言語歴が長いからだと思っておこう。

ともかく、ないのだ。


Go言語にしかないものもあるけど、今回は C言語にあるものという観点だから記載しない。

2022/02/05

[quest2]眼鏡に悩む

先週からうちにある Quest2 だが、平日はまったく使っていない。
ビルドに時間がかかるしストレージに空きがないというのが大きい理由ではあるが、眼鏡を付けたまま付けたり外したりが面倒という理由もかなりの部分を占めている。

JINSさんがフレームの短い眼鏡を出しているということで紹介されていたのだが、買いに行くのがめんどくさい(乱視の矯正でプリズムを入れる場合にはネットではできないらしい)。

手持ちの材料で何とかしたい。


まず、シリコン製のカバーを外してみた。
直接スポンジみたいな部分と顔が接することになるので汚れなどが気になるのだが、それを忘れてしまえばずいぶんましになった(眼鏡については)。

そもそも眼鏡が持って行かれる理由は、眼鏡のフレームとゴーグルの左右が当たっているからだ。シリコン製カバーだと摩擦が強いので、顔とフレームの摩擦が負けてしまうのだ。
だから、もうちょっとゴーグルの左右が広がれば良いのよね。

そういうわけで、左右をぎゅうぎゅうに縛ってみた。
紙で巻いて、その上をテープでぐるぐる巻きにしたのだ。

image

ほら、これならいつもの眼鏡でも少しスペースができるくらいになった。

これならシリコン製カバーを付けてもいけるのでは!と思ったが、ほんのちょっとの厚みでぶつかってしまった。まあ当たりが弱いので眼鏡は外れなさそうだけど、気持ちが良くないのだ。

 

頭を固定するハーネス類も取り除いたので、手を使わないと何もできない。
下に置いたまま顔をかぶせても、ゴーグルの向きを判定して何も見えなくなるからだ。
メガネ屋さんにある、あごを乗せて視力を確認するあれみたいなのがあるとよいのだけどね。

GitHubのcompareはドットの2つ版と3つ版があるのか

お仕事でやっているプロジェクトで、根っこに近いブランチを変更する作業が発生した。
revert してやってもなんとかなりそうだったけど、二転三転しているので仕切り直してもよいかと思い、差し替えたい手前でブランチを作って、あとはいるところだけ cherry-pick したりして、最終的には現行版のブランチとだいたい同じようなコードになる予定だった。

なので最終確認と思って現行版ブランチと変更版ブランチをGitHubのcompareで見てみたのだが、なんか思ったような差分の出方じゃなかった。
単純なファイル比較ではないということか?


実例がないと分かりづらいのでリポジトリを作った。

https://github.com/hirokuma/GithubCompare

ブランチはこんな感じ。

image

feature/morning-early

image

feature/evening-dark

image

この2つを compare すると、1行目だけ一致して、それ以降の差分がそれぞれ表示されると思っていた。

https://github.com/hirokuma/GithubCompare/compare/feature/evening-dark...feature/morning-early

image

左側の方は差分が表示されない。
ちなみに左右を逆にしても同じようなものだった。

 

https://github.com/hirokuma/GithubCompare/compare/feature/morning-early...feature/evening-dark

image

GitHub の compare はドットが2つでやる場合と3つでやる場合があるそうだ。
↑のはドットが3つのパターンだ。

2つだとどうなるかというと・・・。

https://github.com/hirokuma/GithubCompare/compare/feature/morning-early..feature/evening-dark

image

そうそう、こういうのを期待してたんだよ!

このドット数による違いはGitHubの仕様なのかと思っていたけど git 自体の仕様なのか。

Git - git-diff Documentation
https://git-scm.com/docs/git-diff#git-diff-emgitdiffemltoptionsgtltcommitgtltcommitgt--ltpathgt82308203

 

プルリクではドット3つのを見せているそうだから、今まで思ってなかったマージをしていなかったか急に不安になるね。