at backyard

Color my life with the chaos of trouble.

JavaScriptやPythonを書いていた自分がGoを書き始めるために読んだ本、3冊

最近、自身の事業として運用しているソフトウェアをGoですべて書き直した。
元はPythonで書かれていたソフトウェアだったが、それをGoに書き換えた形となる。

なぜGoに書き換えたのか?というのにはいくつか理由があるのだが、そこについては表題から外れるのでここには書かない。

私は普段JavaScriptをメインに書いており時折Pythonも書くのだが、そんな私がGoでソフトウェアを書く際に知識のキャッチアップとしてどのような書籍を読んだかをここに書き残しておくことにした。

非常にありきたりな内容ではあるが、まあ無事にGoで書き直せた達成感から、こんなポストを書いているのだと甘く見てほしい。

前提となる知識のキャッチアップ

前提としてGo TourなどでGoの知識は学んでいた。

go.dev

またGoの有名なOSSなども興味本位でソースを覗いていたりした。
あと自分でちょっとしたCLIツールなどを書いたりはしていた、というところから本格的にGoで書いていくにはどうしたらよいか?という観点で書籍を読んだ。

改訂2版 みんなのGo言語

私が読んだのは1版の方だが、まずはみんなのGo言語を読んだ。

gihyo.jp

他の言語を触っていたが、そんな人がGo言語を触る際に読む、という立ち位置ではかなり読み勧めやすい本だと思う。

実際にGoでCLIツールやWebアプリを書くときなど、様々なシチュエーションでのGoの使い方が学べて良い。

Go言語による並行処理

様々な人々が口々に名著だと言っている書籍。
そこまで言うなら、と購入してみたら実際に名著だった一冊。

Goでの並行処理の書き方、バッドノウハウ、様々なTIPSがいい感じに書かれている「これはたしかに名著だ」と読みながら心から言葉が溢れる一冊。

www.oreilly.co.jp

Goでの書き直しで並行処理なども使っているが、それらの設計をするときには大いに参考になった一冊。

逆に読まないでここらへんの設計していたらと思うと、若干怖くもある。
(と言ってもまだまだ未熟者ゆえ、改善点は見つかるのだが...)

実用 Go言語

Go言語で本格的に書き換え対象のソフトウェアを書き直し始めてから、一つの迷いが常に頭をよぎり続けた。

Goでこんな書き方は良くないのではないか?

私はそんなときGoで有名な方々のOSSリポジトリでの書き方を参考にしていたが、それでも時にはGoっぽくないコードも書いてしまっていた。
Goのベテランエンジニアにコードレビューしてもらいたい...と思っていたときに出会った、まさにGoベテランエンジニアのありがたいTIPSをたくさん知れる一冊。
(ちなみにソフトウェア書き換えるという件は私一人でやっていたので、誰にも相談できないまますすめるという状況だった)

www.oreilly.co.jp

Go言語でソフトウェアを書く際に現場レベルで役立つ、実用的なTIPSが散りばめられた一冊。
私は最初から読まず気になるところから、つまみ食いして、その場ですぐに自身の書いているコードにも反映させた。

私と同じようにGoのベテランエンジニアはこういうときにどうするんだろう?って考えが頭の中をよぎり始めたら、購入を検討したほうが良い一冊。
少なくとも私は買ってよかったと思った。

というわけで3冊書いたが、どの本も購入金額以上に役立ったと思える本だった。この場を借りてこれらの本の著者に感謝である。

GoでクロスコンパイルしたWindowsバイナリを利用したら、Windows Defenderに Trojan Wacatac.H!ml として検知された

GoのWailsで書いているアプリでM1 MacBook AirからWindows向けのバイナリをクロスコンパイルした際の起きたことメモ。

作成したWindowsバイナリを実際にWindowsマシン上で実行しようとしたらMicrosoftWindows Defenderから Trojan Wacatac.H!ml として検知されてしまった。
(ちなみに Trojan Wacatac.H!ml の正式な文字列はメモを取っていなかった...もしかしたら Trojan:Win32/Wacatac.H!ml とかそんな文字列だったかもしれない)

ロスコンパイル時の環境

  • M1 MacBook Air (macOS Monterey 12.6.1)
  • Goのversionは go version go1.19.2 darwin/arm64
  • Wailsのversionは v2.1.0

M1 macから M1以降のmacWindows(amd)向けのバイナリを作成したくて下記のようなコマンドを実行した。
(ちなみに -clean オプションはビルド後のディレクトリをきれいにしてからビルドするオプション)

wails build -clean -platform=darwin/arm64,windows/amd64

このようにして生成したバイナリをWindows側に持っていき実行しようとしたら誤検知されたという形となる。

Windows環境でコンパイルすることでご検知は回避できる

この問題だが、Windows環境でそのまま以下のコマンドを用いてバイナリを作成した場合は誤検知されない。
つまりmacからのクロスコンパイル時にのみ発生するようだ。

wails build -clean

似たような事案

Go言語で作成したプログラムがWindows Defenderに「Wacatac!ml」と誤検知される件と回避方法 という記事を見つけたが、ここで書かれている内容と同じだと考えている。

zenn.dev

こちらの方はソースコードレベルでの回避に成功しているようだが、私の方ではまだここまでの回避には至っていない。

Amazonで購入ボタンを押したのにkindleが購入されない事案が発生している?

AmazonHUNTER×HUNTERハンターハンター)37巻を購入しようとしたときに起きた話

Amazonで購入ボタンを押したのにKindleが購入されない?

昨日AmazonKindleを購入しようと思い、購入ボタンを押したのだが画面は遷移するのに購入完了にはならないという事象に直面した。
購入ボタンは押しても再度購入ボタンが表示された商品ページに遷移してしまうという状態だ。

購入履歴を確認した限りでは決済は行われていないようだったが、決済周りでこの挙動はとても不安になるので、同じような人がいないか知りたくてTwitterでも呟いた。

すると、同じ事象に直面した方からのコメントも頂けたので、どうやらこの問題は私だけの問題ではないようだ。

ツイートにも書いたが、この問題は別のPCから再度Amazonにアクセスして購入ボタンを押すことで無事に解決できた。

詳細に書くと、最初に購入が完了しない問題に遭遇した際のPCは普段Amazonを利用していないPCだった。
もちろん正常にログインできていることは確認しているので実は未ログインの状態だった、とかそういうことではなさそうだ。

普段Amazonを利用しているPCに変えて再度実行したら処理が完了できたので、cookie周りとかそこらへんの処理に問題があるのかもしれない。
(ここらへんはあくまで想像で書いているので、適当です。)

他にも同じような場面に遭遇する人がいるかもしれないので、このメモを残しておくことにした。

HUNTER×HUNTERハンターハンター)37巻の感想(ネタバレなしで)

HUNTER×HUNTERはそこまで熱心なファンというわけではなかったが、一応最新刊までは読んでいたので、このたび最新刊付近を読み返した上で37巻を購入した。

ネタバレない範囲で感想を書くと面白かった。

ハンターハンターは漫画内の文字量も多いし、物語自体の設定が複雑に絡み合っているのでそこらへんを把握するのは大変で、というかちゃんと把握はできていないのだが、そんな私でも読み進めていて面白いと感じた。

購入してよかったと思えるほどの満足度はあったので、購入しようか迷っている方、最新巻付近を読み返して「あーこの続き読みたいなー」という気持ちになったら購入してみると良いかもしれない。

ルームツアーはお好き?

ルームツアーを見るのが好き

割りと人の部屋を見るのが好き。

先日も友人の素敵な新居にお邪魔させていただき、その居心地の良さや空間やレイアウト、また動線のデザインなんかについて説明を受けて興奮した。

また、下のようなタイプの動画なんかも好き。
こういうのも味わい深くて良いし、これはこれでリアルな感じ。ついつい湯船に浸かりながらジッと見入ってしまった。

100万人YouTuberが住む「5万円の欠陥住宅」ルームツアー!!!(前編) - YouTube

少し余談だが、断熱材や西日差し込む窓の重要性(危険性)というのはかなり共感できるところでもある。

以前住んでいた部屋は西陽差し込む部屋で、かつ断熱性能が弱かったため夏は暑くて冬は寒い感じだった。当時はそんなものかぐらいにしか思わなかったが、今は窓は南向きだし、断熱性も高い。また鉄筋マンションだからか防音性も悪くないし、階数の関係か虫も出ない。というわけで、住居環境によってここまで生活の満足度に違いが出るかと感心するぐらいには、今の部屋には満足している。

そういう経験もあってか、やはり部屋というのはとても重要なのだという至極当たり前なことを日々強く感じている。

私自身は賃貸志向なので家を建てる予定というのはないのだが、人が家を建てる時の話や、実際に建てた家の間取りや空間とかの話を楽しめるのは、そういうことも背景としてあるのだろう。

なぜ人のVim設定を見るのは好きなのにVSCodeの設定に興味がないのか?

いきなり話はコンピュータ関連に変わるが、私は他人のVimの設定を見るのが好きだ。

これはルームツアーを見るのと同じ理由だと思う。 自分自身が日々触っているものだから単純に興味があるし、人がどういうポイントに不満を感じているか?どういう工夫をしているのか?ということに興味がある。

そのため、YouTubevimを開いてコーディングをしている動画とかは、おっ!と気を惹かれる。

ただここで面白いと思うのが、人のVSCodeの設定についてはまるで興味がわかない。

VSCodeも日々利用しているのだが私自身、なるべく必要最低限の拡張しか入れないようにしているせいか、他人のVSCodeの設定にまるで興味がない。

またVSCodeはデフォルトのままでも十分使える状態なのでそもそもカスタマイズしたいという気にならない。そういうのも理由の一つとしてあるのではないか?
(ちなみに最近はVimもなるべく拡張しないように意識している。それでも他人のVimカスタマイズには興味あるので、まあそこらへんは他にも理由があるのかもしれない)

macのデスクツアー動画は面白い?

ルームツアー絡みで一時期Mac環境のデスクツアーを見ていた時がある。

YouTubeで検索すればたくさん出てくるが、このデスクツアー、検索上位に出てくるのはオシャレなデスクツアーだったりするが私としては案外そういうのはそこまで楽しくなかったりする。

オシャレの方向性がどれも似たり寄ったりというのもあるし、オシャレ&モダン過ぎて親近感を感じられないというのもあるかもしれない。

親近感というのは一つ重要なポイントかもしれない。

例えば友人がオシャレなMacデスクトップ環境を構築していれば、友人という距離の近さからその環境について興味を持てると思うが、赤の他人のオシャレなデスクを見ても「オシャレだなー」ぐらいにしか思わない。

YouTubeで見るなら、そこまで作り込まれたデスク環境よりもリアルな机の上を見てみたい。

今度そういう動画を探してみるか。

ちなみに私が作業する際は

  • 普通の棚の上にMacBook置いてスタンディング
  • または食卓でMacBook置いて座って
  • ソファに座るorゴロン(最近はあまりやっていないが)

という感じで、そもそも個人のデスクというものが存在していなかったりする。
強いていうならMacBook載せてる棚が自分のデスクか。

wailsでbuild後のバイナリを起動した際に xxx is not a function というJavaScriptのエラーが出ることについて

今日はWailsに関する備忘録。

github.com

wails dev コマンドを用いてdevモードで起動している際には正常に動いていたJavaScriptの処理が、ビルドしたバイナリからアプリを起動した場合にだとエラーになる問題を発見した。

具体的なサンプルコードをいかに示す。
(サンプルと言ってもwailsでプロジェクトを作成後に生成されるコードを少し修正したものになる)

import { useState } from "react";
import logo from "./assets/images/logo-universal.png";
import "./App.css";
import dayjs from "dayjs";
// 下記だと build 後のバイナリから起動した場合にエラーで動かない
// import * as dayjs from 'dayjs';

function App() {
  const [resultText, setResultText] = useState("");

  function onClick() {
    setResultText(dayjs().format());
  }

  return (
    <div id="App">
      <img src={logo} id="logo" alt="logo" />
      <div id="result" className="result">{resultText}</div>
      <button className="btn" onClick={onClick}>Click</button>
    </div>
  );
}

export default App;

このコード内で dayjs をimportしている部分だが、 import * as という形でimportしている場合、wails buildで生成したバイナリからアプリを起動するとimportした処理が下記のような形でエラーになる。
Click ボタンを押して dayjs().format() が呼ばれた箇所でエラーになる)

xxx is not a function.

build 実施時にminifyされているので、関数名自体は dayjs ではなくなっているが、呼ばれているもとは dayjs となる

なお、このエラーログは

wails build -debug

という形でデバッグ確認ができる形でビルドを実施し、バイナリから起動したアプリ上で右クリックメニューを出して Inspect Element を選択することで表示されるDevtools上のconsoleから確認できる。

このようなエラーがでる詳細についてはまだ追えていないが、ひとまず import dayjs from "dayjs"; という形でimportすることでエラー自体は解決できることがわかったのでこちらにもメモを残しておく。

M1以降のMacにOh My Zshを導入する

未だに手元のmaczsh環境ではOh My Zshを導入している。

github.com

以前は少しカスタマイズもしていたが、今ではほとんどOh My Zshのデフォルト設定のまま利用している。

他にも良さそうな設定やシェル環境は出てきているので、そちらを試してみるかなども考えたりすることもあるが、そこに手を出すには腰が重くなっている。
またそろそろこういうカスタマイズなどせず、必要最低限の設定で試してみてはどうか?と自問することもあるが、素のzsh環境からのカスタマイズは億劫に感じ、結局 Oh My Zshを入れてそのままの設定で利用する、ということをここ数年は行っている。

最近M2 MacBook Airを購入したが、こちらでも上に書いたとおり、Oh My Zshを入れてデフォルト設定のまま利用する、という形に落ち着いた。

Oh My Zshの導入方法(M1以降のMac想定)

で、Oh My Zshを導入する際の自分なりの手順というのがあるのだが、導入のたびにちょこちょこ調べつつ作業していることに気づいたので、こちらのブログに導入手順をまとめておくことにした。

M1以降のmacを利用している方であれば多少は参考になるかもしれない。

Homebrewのインストール

Oh My Zshを利用する際に利用しているzsh環境はmac上ではじめから入っているものではなく、brewで別にインストールしたものを利用している。
利用はあったような気がしたがもう何年も前のことなので忘れた。

brew.sh

下記のコマンドを叩きインストールを実施する。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

brewをインストール後は下記のように .zshrc に書き込む。

export PATH="/opt/homebrew/bin:$PATH"
export PATH="/opt/homebrew/opt/ncurses/bin:$PATH"
export LDFLAGS="-L/opt/homebrew/opt/ncurses/lib"
export CPPFLAGS="-I/opt/homebrew/opt/ncurses/include"

brew経由でzshをインストール

以下の通りにコマンドを叩き zsh をインストールしていく。

# インストールするzshをまずは確認
brew info zsh

# zsh install
brew install zsh

インストールした zsh/opt/homebrew 配下に格納されている。

ログインシェルの変更

/opt/homebrew/bin/zsh にインストールしたシェルがあるのでそれを追加する。

# 以下のコマンドでvimを起動し、/opt/homebrew/bin/zshを追加する
sudo vim /etc/shells

# シェルを切り替える
chsh -s /opt/homebrew/bin/zsh

ターミナルを再起動して以下のコマンドを打つ。

echo $SHELL

/opt/homebrew/bin/zsh が表示されればOK

Oh My Zshのインストール

インストール方法は下記に記載されている。

https://ohmyz.sh/#install

brew同様、こちらも install.sh を実行してインストールしていく。

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

これでインストール自体は完了。
最初にも書いたがカスタマイズは行わずこのまま利用している。

ちなみにOh My Zshを導入する前に .zshrc を作成した場合、 .zshrc.pre-oh-my-zsh というファイルがホームディレクトリ配下に作成されており、こちらに以前の .zshrc の内容が移されている。

こちらの内容を再び .zshrc に移し、 .zshrc.pre-oh-my-zsh は削除した。
(管理が面倒なので一本化したいという意図)

Oh My Zshの導入手順は以上。

windows環境にて Goのexec.Commandを実行した際に exec: "start": executable file not found in %PATH%

windows環境にて Goのexec.Command経由で start コマンドを実行した際に

exec: "start": executable file not found in %PATH%

というエラーが出たので解決方法をメモ。

目次

goのexec.Command経由で startコマンドを実行する方法

以下のコマンドを実行した。
(コード内容は簡略化しています)

exec.Command("start", "<Excelファイルのパス>")

すると以下のようなエラーとなった。

exec: "start": executable file not found in %PATH%

これについては以前Node.jsで同じようなことをした際に一度調べた気がしたのですぐに解決できそうな気がしたが、その時に調べた情報源にたどり着けず、記憶を頼りに下記のようにたどり着いた。

args := []string{"/c", "start", "<Excelファイルのパス>"}
exec.Command("cmd", args...)

これでOK。

以下のようなコマンドを実行する形となる。

cmd /c start <Excelファイルのパス>

Explorerを開く場合に explorerコマンドを使うとexit status 1が返ってくる(原因は未調査)

以下は、上と似たようなことをやろうとして、windowsexplorerを開こうと explorer コマンドを使おうとした際に遭遇した事象。

args := []string{"/c", "explorer", "開きたいフォルダパス"}
exec.Command("cmd", args...)

これだとexit status 1となる。
が正常にフォルダは開かれ、一見挙動としては問題なさそう。

試しに下記のようにやってみたら

args := []string{"/c", "start", "開きたいフォルダパス"}
exec.Command("cmd", args...)

今度はエラーなく開かれた。

explorer でも start でもやりたいことは実現できるので良いのだが、実際に2つのコマンドの細かな違いなどは調べられていないので、そのうち調べてみようと思う。
というわけでこの挙動はまだ追えていない。

ひとまずメモだけ残しておく。