RSS ジュリア・エヴァンス ノート

RSS ジュリア・エヴァンス

ジュリア・エヴァンズの個人ウェブサイトは、技術、ソフトウェア・エンジニアリング、学びに関する洞察深い内容が満載の宝庫です。エヴァンズは、有名なソフトウェア・エンジニアで、彼女のプラットフォームを使い、博識な知識を詳細なブログ・ポスト、魅力的なイラストレーション、個人的な逸話を通じて共有します。彼女の文体はアプローチャブルでユーモラスで、技術的なトピックが非常にアクセスしやすくなります。ウェブサイトには、Linuxの内部、プログラミング・ランゲージ、デバッグ・テクニックなど、さまざまな主題に関する記事が特徴です。エヴァンズの技術に対する情熱と、複雑な概念を明確に説明する能力が彼女の作品を通じて輝いています。このウェブサイトは、経験豊富なデベロッパーや、コーディングの旅を始めようとしている人々にとって、貴重な洞察とソフトウェア・エンジニアリングの世界に関する新鮮な視点を提供します。

ノートのスレッド

Tailwindから離れて、CSSの構造化を学ぶ

著者はCSSとの道のりを振り返り、当初はTailwindの構造を気に入っていたものの、現在はバニラCSSに移行しています。この変更は、CSSをより深く理解し、スキルを向上させたいという願望から促されました。著者は、インポートされたリセット、コンポーネントベースのスタイリング、定義済みのカラー変数、Tailwindから適応されたフォントサイズシステムを含む新しいCSS構造を詳述しています。また、ユーティリティクラスを活用し、グローバルスタイルのベースを確立し、スペーシングを意識的に管理しています。レスポンシブデザインは、Tailwindのメディアクエリ中心のアプローチから離れ、CSSグリッドレイアウトにより依存しています。ビルドシステムは、開発中は必須ではありませんが、本番環境のバンドルにはesbuildを採用しています。著者は、ビルドシステムへの依存、CSS知識の向上、Tailwindの限界、そしてよりセマンティックなHTMLへの願望を挙げ、移行の主な理由を概説しています。最後に、@layerのような機能について議論し、Tailwindの利点を認めつつも、その原則に価値を見出していることを述べています。

CSSカラーパレットへのリンク

著者はTailwindの使用をやめたが、その便利なカラーパレットが恋しくなった。ワークフローを改善するために、Tailwindのカラーシステムに代わるものを探した。特にCSSでの使いやすさのために、事前に定義されたカラーパレットを求めた。著者はMastodonでパレットの提案を求め、その回答をまとめることにした。この記事では、uchū、flexoki、reasonable coloursなどのカラーパレットをリストアップしている。他にも様々なパレットやデザインシステムが検討対象として提供されている。カラーパレットジェネレーターもいくつか紹介されているが、著者はそれらの使用が難しいと感じている。色覚異常に関する情報やoklch CSS関数など、追加の色ツールも紹介されている。著者はこのリソースが、自分自身やCSSカラーソリューションを探している他の人々にとって役立つことを願っている。

ブラウザでVueコンポーネントをテストする

著者は、Node.js に依存せずにフロントエンド JavaScript を記述することを目指しています。直面した大きな課題は、フロントエンド コードの効果的なテスト方法の欠如です。Playwright を使用した以前の試みは遅く、Node.js が必要であると判断されました。これを解決するために、著者は Alex Chan によるミニマリストなブラウザ内単体テストフレームワークに関する作業に触発され、テストをブラウザタブ内で直接実行することを検討しました。Chan のアプローチは単体テストに焦点を当てていましたが、著者は Node.js ビルドプロセスなしで Vue コンポーネントのエンドツーエンド統合テストを実行することを目指しました。 著者は QUnit をテストフレームワークとして使用し、デバッグのための「rerun test」ボタンを高く評価しました。プロセスには、Vue コンポーネントをグローバルに公開し、それらを非表示のオフページ div でレンダリングする `mountComponent` 関数を作成することが含まれていました。フィクスチャデータは、専用のエンドポイントへの POST リクエストを介してデータベースをリセットすることによって管理されました。基本的なテストでは、コンポーネントをレンダリングし、そのコンテンツをアサートしました。 遭遇した主な問題には、非同期操作の完了を待つことが含まれ、`waitFor()` 関数の開発につながりました。待機する正しい要素または条件を特定することは困難であることが判明し、より信頼性の高いアプリケーションのリファクタリングが提案されました。著者は、要素の識別のために CSS クラスを追加することも実験しましたが、Testing Library のようなライブラリは、よりアクセスしやすいアプローチを推奨していることに注意しました。 フォーム処理は、値を単純に設定するだけでは不十分であり、関連する DOM イベントをディスパッチする必要があったため、困難をもたらしました。これは、UI テストライブラリがそのようなタスクを簡素化する理由を浮き彫りにしました。テストカバレッジは、Chrome の組み込み開発者ツールを使用して部分的に評価されましたが、プロセスでは、バンドルされた JavaScript で機能するために特定の構成とアクションが必要でした。 学習曲線にもかかわらず、著者はこの経験を楽しんでおり、フロントエンド プロジェクトの自信のあるテスト スイートを構築することに楽観的であることを表明しました。また、ブラウザのみの実行と互換性のある UMD ビルドを提供する Testing Library のようなライブラリのさらなる調査を検討しており、ブラウザ中心のテストを CI 環境に統合する方法を検討しています。

tcpdumpとdig manページの例

著者は、manページにおける例の有用性に触発され、digおよびtcpdumpツールのmanページを改善しました。主な目的は、たまにしか使わないユーザーや初心者向けに、最も基本的な例を提供することでした。この初心者やたまにしか使わないユーザーを対象としたアプローチは、効果的で好評であることが証明されています。著者は、レビュープロセスがmanページ内でより正確な情報を見つけやすくする上で価値があると感じました。また、パケットを保存する際の`-v`フラグなど、tcpdumpの便利な機能についても学びました。ドキュメント全般に対する懐疑的な見方にもかかわらず、著者は現在、高品質で正確なmanページの可能性に楽観的です。roffの学習を避けるため、tcpdumpのmanページ更新のためにカスタムのMarkdownからroffへのスクリプトが作成されました。これには、Markdownの抽象構文ツリーを解析し、roffコードを出力することが含まれていました。著者はまた、roffの歴史と進化、およびmandocプロジェクトについても調査しました。BSDシステムとLinuxシステムにおけるドキュメント作成の実践における技術的および文化的な違いについて、好奇心をそそられました。

VimからHelixへの移行に関するメモ

著者は、言語サーバーの統合の容易さに惹かれて、テキストエディタであるHelixにVim/Neovimから乗り換えました。長年複雑なVimの設定に苦労してきた後、Helixの組み込み機能は魅力的でした。Helixの検索機能とクイックリファレンス機能は特に役立ち、高く評価されています。著者は、一部のVimの習慣を調整する必要がありましたが、Helixのキーバインディングには容易に適応しました。著者は、VimのマクロやタブよりもHelixのマルチカーソルとバッファ切り替えを好むようになりました。しかし、リストの折り返し問題や、永続的なアンドゥ、自動リロードの欠如など、いくつかの不満点も指摘しています。これらのフラストレーションにもかかわらず、著者はHelixに適応しており、移行は予想よりも容易だったと感じています。エディタのシンプルな設定は、以前のセットアップの複雑さに比べて大きな利点です。著者は主にターミナル内でHelixを使用し、専用のウィンドウでプロジェクトを整理しています。著者は3ヶ月の使用を経てHelixに満足していますが、Vimに戻る可能性も排除していません。

新しいジン:ターミナルの秘密のルール

著者による新しいジン「ターミナルの秘密のルール」がリリースされました。このジンは、ターミナルがどのように機能するかを説明し、ターミナルプログラムの使用に関するヒントやコツを提供しています。著者は20年間毎日ターミナルを使用していますが、その仕組みについて多くの誤解を抱えていました。ターミナルには、矢印キーで移動できる場合とできない場合があるなど、多くの小さな不整合があります。ターミナルがどのように機能するかについての「ルール」は、多くの異なるソフトウェアで構成されているため、理解するのが困難です。このジンは、ターミナルの4つの部分(シェル、ターミナルエミュレータ、プログラム、TTYドライバ)がどのように連携するかを説明し、ターミナルでの動作に関するコアな規約を提供しています。著者は、シェルの設定方法やエスケープコードの理解など、ジンを書きながら驚くほど多くのことを学びました。このジンは、PDFまたは印刷版として購入可能であり、著者のすべてのジンがセットになった15パックも利用可能です。著者は、PuTTYを開発した人物やターミナルの内部構造を理解している人物など、多くの人々の支援を受けました。印刷版は8月に発送予定であり、著者は印刷部数を決定するために注文を待つ必要があります。ジンは12ドルで販売されており、読者がターミナルをよりよく理解し、使用できるようになることを著者は願っています。

非Cプログラマー向け:`make`を使用してCプログラムをコンパイル

著者はCプログラマーではありませんが、時々C/C++プログラムをソースコードからコンパイルする必要があります。以前は他の人にコンパイルを頼っていましたが、Macに乗り換えてからは、自分でプログラムをコンパイルする方法を学ばざるを得なくなりました。Cプログラムをコンパイルするには、Cコンパイラをインストールし、プログラムの依存関係をインストールし、必要に応じて./configureを実行し、makeを実行する必要があります。著者は、Cコンパイラをインストールする方法、依存関係をインストールする方法、および./configureを実行する方法を説明しています。また、依存関係の問題やコンパイラエラーなど、コンパイル中に発生する可能性のある一般的な問題についても議論しています。著者は、コンパイラとリンカにフラグを渡すことで、これらの問題を修正する方法を説明しています。さらに、特定のファイルをビルドする方法、他のパッケージングシステムが同じCプログラムをどのようにビルドしたかを確認する方法、そしてバイナリをインストールする方法についてもアドバイスしています。著者は、Cプログラマでなくても、Cプログラムの仕組みの基本を理解することは役に立つと結論付けています。

ANSIエスケープコードの標準

ANSIエスケープコードはターミナルのユーザビリティを向上させるために使用されますが、完全に標準化されているわけではないため、信頼性の問題につながります。著者はターミナルを研究する中でANSIエスケープコードについて知り、それらを取り巻く標準を理解したいと考えました。エスケープコードは、ターミナルエミュレータがプログラムと通信するために使用され、キー入力やマウスの動きに対する入力コードと、テキストの着色やカーソルの移動などのタスクに対する出力コードの2種類があります。1976年に発行されたECMA-48規格は、エスケープコードの一般的な形式といくつかの特定のコードを定義していますが、網羅的ではありません。Xterm制御シーケンスは、ターミナルエミュレータによって広く実装されているエスケープコードのもう1つのセットですが、正式な標準ではありません。terminfoデータベースはncursesによって管理され、さまざまなターミナルのエスケープコードを保存しており、一部のプログラムはそれを使用してどのコードを使用するかを決定します。ただし、terminfoを使用せずに、ほとんどのターミナルエミュレータで動作するエスケープコードの「単一の共通セット」をハードコードするプログラムもあります。この共通セットが何であるかについての明確な合意はありませんが、VT100、ECMA-48、およびxtermからのコードが含まれている可能性が高いです。課題はあるものの、ANSIエスケープコードの標準化は、より豊かなターミナル体験につながる可能性があり、著者はより明確な標準化の状況がターミナルエミュレータとアプリケーションの革新を促進することを期待しています。

PATH にディレクトリーを追加する方法

PATH にディレクトリーを追加するには、まず使用しているシェルを特定する必要があります。これは、コマンド `ps -p $$ -o pid,comm=` を実行することで行うことができます。Linux ではデフォルトのシェルが bash であり、Mac OS では zsh です。 次に、シェルの設定ファイルを見つける必要があります。これは通常、zsh の場合は `~/.zshrc`、bash の場合は `~/.bashrc`、fish の場合は `~/.config/fish/config.fish` です。ただし、bash の設定ファイルは `~/.bashrc`、`~/.bash_profile`、`~/.profile` の 3 つのオプションがあり、どれが使用されているかをテストする必要があります。 シェルの設定ファイルを見つけた後、PATH に追加するディレクトリーを特定する必要があります。これは、プログラムのインストール手順を確認するか、インストーラー固有のコマンド(例えば Node/npm の場合は `npm config get prefix`)を使用することで行うことができます。 正しいディレクトリーを見つけた後、ディレクトリーからプログラムを実行できるかどうかを確認する必要があります。 次に、シェルの設定ファイルを編集して、ディレクトリーを PATH に追加する必要があります。シェルによって構文が異なり、bash と zsh は `export PATH=$PATH:~/directory` を使用し、fish は `set PATH $PATH ~/directory` を使用します。 最後に、シェルを再起動する必要があります。これで変更が有効になります。プログラムがまだ動作しない場合は、PATH の先頭にディレクトリーを追加する必要があるか、IDE または cron ジョブからプログラムを実行する場合は、PATH にディレクトリーを追加する方法を変更する必要があります。 また、一部のインストーラーは、PATH を自動的に設定するスクリプトを提供します。これをシェルの設定ファイルに追加することで実行することができます。ただし、手動でディレクトリーを PATH に追加する方が好ましい場合もあります。

いくつかのターミナルの不満点

ターミナル利用に関する不満を調査するため、1600人を対象としたアンケートを実施しました。回答者のほとんどは経験豊富なユーザーで、40%が21年以上、95%が少なくとも4年以上ターミナルを使用していました。不満の上位カテゴリーには、構文の記憶、ターミナルの切り替え、色の問題、キーボードショートカット、コピー&ペーストの問題が含まれていました。その他、発見可能性、急峻な学習曲線、履歴、ドキュメントの不足、スクロールバックの問題なども共通の不満として挙げられました。一部のユーザーは、ターミナルを使用する際に不安や恐怖を感じるとも述べており、シェルスクリプト、コマンドライン引数の不整合、パフォーマンスの問題についても言及がありました。アンケートでは、多くのユーザーが異なるシステム間でのdotfilesの同期や、tmuxタブとターミナルタブによるウィンドウ管理に苦労していることも明らかになりました。また、ターミナルの機能に圧倒され、より効率的なエクスペリエンスを求めるユーザーもいました。このアンケート結果は、ターミナルに関するジンを作る際に役立てられます。全体的に、このアンケートは、経験豊富なユーザーにとっても、ターミナルの使用には複雑さと課題が伴うことを浮き彫りにしています。

「モダンな」ターミナルセットアップを行うには何が必要ですか?

著者は、「モダン」なターミナル体験を構成する要素について考察しています。これには、複数行のクリップボードコピー&ペースト、無限のシェル履歴、24ビットカラーサポートなどが含まれます。シェル、ターミナルエミュレータ、テキストエディタなど、多くのコンポーネントが関わっているため、この体験を実現するのは難しいと著者は認めています。著者は、モダンなターミナル体験を実現するための個人的なアプローチとして、fishシェル、24ビットカラーサポートに対応したターミナルエミュレータ、そしてカスタム設定済みのneovimを使用しています。多くの設定に時間をかけたくない人のために、著者はfishまたはoh-my-zshを備えたzsh、24ビットカラーサポートに対応したターミナルエミュレータ、そしてmicroやhelixのようなテキストエディタの使用を提案しています。しかし、著者はこれらの選択肢を用いても、シェル、テキストエディタ、個々のアプリケーションの問題によって、モダンなターミナル体験を得ることが困難である可能性があると指摘しています。シェルは特に問題であり、bashやzshのような一般的なシェルは、満足のいく体験を得るためにはカスタマイズが必要です。テキストエディタも問題となる可能性があり、vimやemacsのような選択肢はかなりの設定が必要となる一方、nanoは機能が限られています。著者は、個々のアプリケーションも問題を引き起こす可能性があり、これらの問題のデバッグには時間がかかる可能性があると述べています。最終的に、著者はモダンなターミナル体験を実現するには、忍耐、実験、そして小さな変更を加え、新しいツールや設定に適応していく意思が必要であると結論付けています。

端末プログラムが従う「ルール」

ターミナル内のプログラムは、規格がないにもかかわらず一貫した動作を示します。Ctrl-Cを押すと非対話型プログラムが終了する、TUI(テキストユーザーインターフェイス)が「q」を押すと終了する、REPL(Read-Eval-Print Loop)が空行でCtrl-Dを押すと終了するなどの特定のルールに従っているからです。ほとんどのプログラムは、readlineキーバインドをサポートし、パイプに書き込むときに色を無効にし、'-'をstdin/stdoutの意味で使用します。これらのルールは、規定ではなく、記述的なものであり、これらを理解することで、ターミナルプログラムを効果的に使用することができます。

「パイプが時々「詰まる」理由:バッファリング」

バッファリングは、ターミナルプログラムでパフォーマンスを向上させるために一般的に行われます。パイプにデータが遅く追加される場合、プログラムがその出力をバッファし、決して書き込むことがない問題が生じる可能性があります。 grep や類似のプログラムは、パイプに書き込むときはブロックバッファリングをデフォルトで使用し、ターミナルに書き込むときはラインバッファリングを使用します。これが、"tail -f /some/log/file | grep thing1 | grep thing2" というコマンドが出力を見せない理由です。 grep、sed、awk、tcpdump、jq などのコマンドがバッファリングを行い、tail、cat、tee などのコマンドはバッファリングしません。 C、Python、Ruby、Perl などのプログラミング言語もバッファリングを行い、バッファリングを無効にするさまざまな方法があります。 パイプに Ctrl-C を押すと、プログラムの出力バッファが失われる可能性があります。シグナルが受信される前にバッファがフラッシュされることがないためです。 ファイルにリダイレクトするときもバッファリングが起こりますが、一般的に予想通りの動作を示し、プログラムが終了する前にバッファの内容が書き込まれます。 バッファリングを避けるには、速く終了するプログラムを実行する、grep に "--line-buffered" フラグを使用する、awk を使用してコマンドを書き換える、stdbuf を使用する、unbuffer を使用してプログラムがターミナルに書き込むように強制するなどの方法があります。 最適なソリューションは、特定の状況によって異なります。unbuffer は、信頼できる選択肢です。 バッファリングは、一般的に問題とはならないが、パイプにデータが遅く追加される場合に生じる可能性があります。バッファリングを無効にする環境変数があれば便利ですが、そのデザインと実装には課題があります。

ビルドシステムなしでフロントエンドJavaScriptライブラリをインポートする

著者は、ビルドシステムなしでJavaScriptを書くことを好むと述べ、ビルドシステムを使用せずにライブラリをインポートする経験を共有します。著者は、ライブラリが提供する3つの主要なJavaScriptファイルのタイプを説明します:クラシックなグローバル変数ファイル、ESモジュール、CommonJSモジュール。著者は、NPMビルドのライブラリのファイルを見つける方法と、ブラウザーでESモジュールを使用するためのimportmapsの使用を説明します。彼らはまた、CommonJSモジュールをESモジュールに変換するためのesm.shの使用も述びます。著者は、Chart.js、@atcute/oauth-browser-client、@atproto/oauth-client-browserの使用例を提供し、各々のアプローチを議論します。彼らは、importmapsを使用するにはブラウザーのサポートが必要であり、古いブラウザーでは問題が生じる可能性があると述びます。著者は、importmapsの代替としてesbuildを使用することも述びます。最後に、3つのJavaScriptファイルのタイプとそれらを識別し使用する方法をまとめます。

新しいマイクロブログ(TILs)

著者は、ソーシャルメディアで投稿する面白いツールや事実を保存するために、自分のサイトに「TIL(Today I Learned)」という新しいセクションを作成しました。目標は、フルブログ投稿を書く必要なく、これらの小さな情報を保存する場所を持つことです。著者はMastodonやBlueskyで「クールなもの」をよく投稿していますが、これらを追跡する場所がなかったため、この新しいセクションを作成しました。この新しいセクションは、Simon WillisonのTILブログにインスパイアされていますが、著者の投稿ははるかに短いものです。著者はTILセクション用の新しいフォルダーを作成し、カスタムスタイリングを追加し、別のRSSフィードを設定しました。TILセクションは、主に著者のためのもので、便利なリンクやツールを追跡する方法です。著者は数週間前にこのセクションを使用し始め、うまく機能していることを発見しました。著者は「POSSE(自分のサイトに投稿し、他の場所に共有する)」という考え方のファンですが、自分のサイトに保存したい特定のカテゴリのコンテンツを特定するのが簡単だと感じています。著者はブログ投稿や漫画のメールリストとRSSフィードを持っており、TIL投稿の要約をメーリングリストに追加する可能性があります。著者は、一部のコンテンツを一時的なものとして保存し、特定のカテゴリのコンテンツのみをアーカイブすることを好みます。

ターミナルでの ASCII 制御文字

著者は、ターミナルでの制御コードの概念、例えばCtrl-A、Ctrl-C、Ctrl-Wなど、そしてそれらの動作原理を探索しています。ASCII制御文字は33個あり、オペレーティングシステムのターミナルドライバーが処理するコード、リテラルキー押下に対応するコード、readlineが使用するコードに分類できます。著者は、これらのコードが有機的に進化したため、実際の構造はないと指摘しています。制御コードはわずか33個しかないため、Ctrl-1をキーボードショートカットとして使用することは意味がありません、それは単に1を押下するのと同じです。著者はまた、Ctrl+Shift+Cは制御コードではなく、ターミナルエミュレーターの動作に依存すると指摘しています。ASCIIの公式名称は、元々は電信機械向けに定義されたため、現在ではあまり役に立たないと著者は考えている。著者は、Ctrl-MとCtrl-Iをキーボードショートカットとして使用することを困難と感じています、それらはそれぞれEnterとTabに対応するためです。著者は、さまざまなキーコンビネーションを押下したときに送信される制御コードを特定するためのPythonスクリプトを提供しています。著者は、Ctrl-WやCtrl-Uのような制御コードが、ターミナルがカノニカルモードかノンカノニカルモードかによって異なる動作をすると指摘しています。最後に、著者は、制御コードに関する多くの注意点や衝突があると認め、実際にはこれらの情報が必ずしも役に立たないと述べています。

Mess With DNS での IP アドレスの検索に使用されるメモリーを減らす

Mess With DNS の作者は、プログラムがメモリー不足でOOMが殺される問題に遭遇し、バックアップスクリプトに問題が生じるようになった。この問題を解決するために、作者は Mess With DNS がメモリーを少なく使うようにすることを決めた。このプログラムは、IPアドレスのデータベースをメモリーにロードし、約117MBのメモリーを使用していた。作者は、メモリー使用量を削減するために3つの異なるアプローチを試みました。 第一のアプローチは、SQLite を使用してデータをディスク上に保存することで、初期のメモリーの目標を達成することができましたが、IPv6アドレスの保存と、元のバイナリーサーチよりも500倍遅いという問題がありました。第二のアプローチは、trie を使用することで、メモリーの使用量が増加し、元のバイナリーサーチよりも遅くなりました。 第三のアプローチは、Name と Country フィールドの重複を削除し、メモリーの使用量を117MBから65MBに減らすことで、netip.Addr ではなく net.IP を使用することで、メモリーの使用量をさらに20MB削減し、合計で46MBにまで減らすことができました。作者は、合計で70MBのメモリーを節約することができました。

Hugoのアップグレードに関する注意事項

ブログ投稿の著者は、古いバージョンが正常に機能しているにもかかわらず、Hugoのバージョンを0.40から0.135にアップグレードすることにしました。彼らはアップグレードプロセス中に変更を加える必要があったことを文書化しました。これには、テンプレートの呼び出しの置換、ページ参照の更新、およびテーマ内の「次」と「前」の意味の反転が含まれます。著者はまた、古いBlackfridayレンダラーに代わる新しいGoldmarkレンダラーを使用するためにMarkdownファイルを更新する必要がありました。これには、HTMLとMarkdownの混合、山かっこ引用符の使用、ネストしたリストのインデントなど、Markdownの書き方に変更を加えることが含まれます。また、著者Goldmarkレンダラーを構成してコードの強調表示を無効にし、見出しIDを生成するための古い方法を使用する必要がありました。彼らはBlackfridayレンダラーとGoldmarkレンダラーの出力を比較するスクリプトを記述し、それを使用してMarkdownファイルの問題を特定して修正しました。著者は、アップグレードプロセスは時間がかかり、課題がないわけではなかったと述べていますが、最終的には、将来の証明となるMarkdownレンダラーを持つことが価値があると信じています。彼らはまた、Hugoの古いバージョンを使用している他のサイトwizardzines.comをアップグレードするときにも同様の変更を行う必要があるだろうと述べています。

fish シェルが今でも愛される理由

Fishは、自動的な履歴候補、スマートな自動補完、複数行のコマンドを簡単に貼り付ける機能、ユーザーフレンドリーなタブ補完インターフェース、Git統合のあるデフォルトのプロンプトなど、多くの主要な機能を備えたシェルです。Fishは、包括的な履歴システムと検索機能、ターミナルが壊れることを防ぐためにバイナリーデータを送信するのを避ける、Ctrl+Sキー組み合わせの無効化、グローバルパス変更ユーティリティ、存在しないコマンドのシンタックスハイライトなど、多くの利点があります。加えて、Fishはループ構文を簡略化し、多行編集を簡単にする、Ctrl+左/右矢印キーで単語をナビゲートする便利なショートカットも提供します。特定のツールとの統合に関する指示が限られている場合でも、Fishはますます一般的に受け入れられており、必要に応じてPOSIXシェルに戻ることができます。Fishは、最小限度の設定を重視し、デフォルトの設定を気に入り、直感的で機能豊富なデザインのシェルを求める人々にとって特に適しています。

DNS を PowerDNS に移行するためのメスの移行

Mess With DNSは、DNSの機能を学び、レコードを作成し編集するためのプラットフォームです。元のDNS実装には、下線が含まれるドメイン名が許可されなかったり、CNAMEレコードのサポートがなかったり、SVCBレコードやHTTPSレコードの種類がなかったりするなどの制限がありました。 これらの問題を解決するために、著者はPowerDNSというオープンソースのDNSサーバーを導入しました。このDNSサーバーはHTTP APIを備えており、前のDNS実装を置き換えました。この変更は、DNSクエリーのインターセプトとフロントエンドのニーズに合ったAPIのデザインという新たな課題をもたらしました。 エラーハンドリングのために、著者はユーザーが直面するエラーメッセージをより明確にするようにカスタマイズし、PowerDNS APIのエラー応答と基本的な入力検証を実行しました。Postgresで経験したOOMキル問題を解決するために、SQLiteがデータベース管理に使用されるようになりました。 Vue.jsライブラリはバージョン3にアップグレードされ、組み込みのブラウザーフォームバリデーションツールの使用とグローバルステートマネジメントストアの実装が伴いました。 プロジェクトは、Vueのアップグレード、ステートマネジメントストアの作成、バックエンドAPIの再デザイン、PowerDNSの統合というフェーズに分割されて実装されました。更新されたウェブサイトは既にリリースされており、ユーザーが報告していたDNSの問題を解決しています。

Go 構造体は割り当て時にコピーされる (そして Go についての他の誤解)

著者は、Goのカジュアルプログラマーで、構造体が割り当てられたときにコピーされるという基本的な誤解を明らかにするバグに遭遇しました。この誤解は、構造体が割り当てられたときに参照されるのではなくコピーされるという事実に基づいています。この結果、別の変数に構造体を割り当てた後で構造体を変更すると予想外の動作が生じました。著者は、他の言語での経験から変数が一般的に参照によって渡されるという信念を持っており、この動作に驚きました。この誤解は、関数引数でのパス・バイ・バリューとパス・バイ・レファレンスの著者の理解も複雑化させましたが、変数の割り当てにはこれらの概念を適用していませんでした。著者はまた、Goのサブスライスが元のスライスと同じバッキングアレイを共有していることを発見し、サブスライスに追加すると元のスライスが意図せず変更される可能性があることを学びました。 さらに、著者は、Goのメソッドにおける値レシーバーとポインターレシーバーの違いを明確にし、メソッドが呼び出された構造体を変化させる必要がある場合はポインターレシーバーが必要であることを理解しました。著者は、「100 Go Mistakes」リソースを高く評価し、明確かつコンパクトなフォーマットで一般的なGoの落とし穴を素早く学びました。最後に、著者は、有益なGoリソースとして「Go by Example」、「go.dev/play」、静的解析ツールの「staticcheck」や「golangci-lint」などをリストアップしました。

ターミナルでテキストを入力するのは複雑です

ターミナルでのテキスト入力は、プログラム間の不一致により困難が生じることがあります。矢印キーなどの基本的な機能がサポートされていない場合があります。Readlineは、テキスト編集機能を提供するライブラリで、多くのショートカットキーをサポートしています。Readlineサポートが無いプログラムは、rlwrapを使用して機能を向上させることができます。いくつかのプログラムは、Readlineを模倣するか、追加の機能を提供するカスタム入力システムを使用します。この入力システムを理解することで、予想可能性が高まります。一般的なショートカットキーには、Ctrl+Aで行の始まり、Ctrl+Eで行の終わり、Ctrl+Rで履歴検索があります。多くのシェルは、代替的な入力モードとしてviキーバインディングをサポートしています。この入力システム(なし、Readline、カスタム)の診断により、利用可能な機能を適切に使用することができます。ただし、ターミナルでのテキスト入力に関する追加の複雑さがあり、ここでまとめられた内容を超えるものもあります。

シェルのジョブ制御を使用する理由

ジョブ・コントロールは、シェルがプロセスを3つの状態(フォアグラウンド、バックグラウンド、ストップ)で管理することを許す機能です。この機能には、fg、bg、Ctrl+z、jobs、kill、disown、wait などのコマンドが含まれます。Fish、bash、zsh すべてがジョブ・コントロールをサポートしますが、各シェルで異なる方法で使用できます。ターミナル・タブではなくジョブ・コントロールを好む人もいるのは、同時にすべてのターミナルを画面上で見ることができるからです。Ctrl+Cに対応しないプロセスを殺す、GUI・アプリケーションやCPUを多く消費するプログラムをバックグラウンドで実行し、複数のコマンドの環境変数を設定するためにジョブ・コントロールが有効です。シングル・ユーザー・モードでいるか、tmux や screen なしで SSH されたマシンにアクセスしている状況でもジョブ・コントロールが必要です。

新しいジン:Gitのしくみ!

"Gitのしくみ"は、ジュリア・エヴァンズが作成した新しいジンで、人気のあるバージョン管理システムであるGitを明るみに出すことを目指しています。このジンは、Gitを数年使いながらまだ困惑しているユーザーを対象にしており、一般的な誤解を明確化し、内部の論理をより深く理解することを目的としています。エヴァンズは、Gitの用語、エラーメッセージ、不一致な振る舞いの複雑さを認めつつも、経験が積むとこれらの癖を扱えるようになることを強調しています。このジンは、ユーザーインターフェースの振る舞いとそれがGitの内部プロセスに関連する方法に焦点を当てており、内部の詳細を過剰に強調しないようにしています。また、印刷可能なチートシートとアクセシビリティのためにHTMLトランスクリプトも含まれています。Gitの複雑さを強調しながらも、エヴァンズはこのツールのスピード、後方互換性、無料のホスティングオプションの存在を高く評価しています。このジンの作成には、多くの人々が協力し、特に、マリー・クレア・ルブラン・フラナガンが明確な説明を提供し、ヴラディーミル・カシコヴィチがカバーのデザインを担当し、66人のベータ・リーダーがフィードバックを提供しました。このジンは、PDF版や印刷版で購入可能で、印刷版の注文は7月に発送予定です。

Gitのエラーメッセージに関するノート

Gitのエラーメッセージは、特に初心者にとって混乱させるものです。著者は、一般的なエラーメッセージのいくつかを分析し、複雑さを強調し、実用的解決策を提供します。Gitのメンテナンスは複雑で、国際的な翻訳や改善努力のための限定された資金など、多くの要因が絡み合っています。にもかかわらず、エラーメッセージを改善するためのいくつかの提案があります。例えば、分岐したブランチと遅れているブランチとの明確な区別を提供し、分岐したブランチを調整する際にユーザーに提示される圧倒的なオプションの数を減らすことが挙げられます。さらに、著者は、Gitの内部的な論理、例えば`git checkout`コマンドの文脈でのブランチとパスの違いを理解することが重要であると強調します。このような微妙さを理解することで、ユーザーはエラーメッセージをより効果的に解釈し、Gitのコマンドラインインターフェースをよりスムーズにナビゲートできます。

かぎ針編みのサボテンを作る

著者はコンピューターよりも非コンピューターの趣味、特に小さなサボテンを編むクロシェットを試みています。彼らは経験、パターン、糸の種類、使用した技術などを共有します。初めは無料のパターンを使っていたが、クリエイターをサポートするために今はパターンを購入することを好むようになりました。パターンを変更し、間違いを学びの機会として受け入れる喜びを強調します。安全の目ではなく、刺繍の目と、プロセスを簡単にするためにスクラップ糸をステッチ・マーカーとして使用します。クロシェットでのカウントが困難だが、視覚的な検査と近似値を通じてこれを克服する方法を見つけています。メリノ、綿、合成繊維など、さまざまな糸の重さとブランドを探検し、サボテンのプロジェクトではフックのサイズがあまり問題にならないと学びました。基本的なステッチを学び、新しいステッチに対処するためにパターンを始め、YouTubeのビデオからガイダンスを求めます。象、サボテン、進行中のマウスなど、様々なアイテムを作成しました。著者はクロシェットの触れる性質、社会的な側面、必要な材料の最小限度のスペースを高く評価します。クロシェットの許容性を強調し、実験と間違いの受け入れを許容します。

ギットの世論調査結果

著者は、Gitの使用方法と認識を調査するためにMastodon上で投票を実施し、驚くべき結果を明らかにした。最も一般的なマージ戦略は「マージ」で、わずか30%が「リベース」を頻繁に使用している。まれに衝突が生じるが、最近の数年間でGitの問題で作業を失った人は14%にすぎない。多くのユーザーが「HEAD」、「ref」、「fast-forward」などの用語に馴染みがなく、著者はこれらの用語の使用に注意を払った。興味深いことに、ほとんどのユーザーがGitをSVNよりも好み、GitとMercurialの好みは割れている。特筆すべきは、71%のユーザーがシェルプロンプトに現在のブランチを表示している。著者は、コミット、ブランチ、Git環境などに関するGitの概念に関する投票結果を共有し、ユーザーの認識と好みに関する貴重な洞察を提供する。

Git の '現在のブランチ'

Gitの「現在のブランチ」コンセプトは、近くで検討すると、明らかに複雑です。Gitの用語集が、.git/HEADファイルの内容として定義する一方で、他にも、"git status"の出力、最後にチェックアウトされたブランチ、シェルプロンプトなどの解釈があります。これらの解釈は、一般的に一致しますが、デタッチドHEAD状態、チェックアウトされたタグ、リベース中の状況など、特定のシナリオで異なる結果を示します。例えば、タグをチェックアウトすると、.git/HEADはコミットIDを格納するが、"git status"は、ユーザー便宜のためにタグ名を表示します。同様に、リベース中は、"git status"がリベース状態を強調し、シェルプロンプトは元のブランチを示します。さらには、"git init"が行われると、明示的なチェックアウトなしで「現在のブランチ」が自動的に設定されるというニュアンスもあります。裸のリポジトリの場合、"git status"と"git checkout"が動作しないという状況もあります。これらの不一致は、「現在のブランチ」を厳格に定義する限界を示し、状況に応じて理解することが重要です。 「現在のブランチ」が、新しいコミットのターゲットであるという定義は、リベース中でコミットが元のブランチに着陸するため、一般的に真です。"現在のブランチ"がGit操作の文脈を表すという考え方も有効ですが、裸のリポジトリでの"git status"の異なる動作など、不一致があります。結局、「現在のブランチ」を理解するためには、.git/HEAD、"git status"の出力、最後のチェックアウトアクションなど、状況に応じて異なる指標を組み合わせて捉えることが必要です。

Git での HEAD の動作

記事の著者は、Mastodonで投票を実施し、人々がGitのHEADの動作をどのように理解しているかを尋ねました。その結果、多くの人が不確かや何もわからないと回答しました。著者は、HEADが単純なトピックと思っていたが、他の人々との後続の会話で、自分が評価していたよりも複雑であると発見しました。HEADは、.git/HEADというファイル、git show HEADのようなコマンドでの"リビジョンパラメータ"HEAD、Gitの出力でのHEADの様々な使用方法など、異なるものを参照することができます。.git/HEADファイルには、ブランチ名かコミットIDが含まれ、Gitの現在のブランチを決定します。.git/HEADがコミットIDを含む場合、Gitはそれを"detached HEAD state"と呼び、新しいコミットはブランチに付かないため、見つけることが困難か、Gitのガーベジコレクションによって削除される可能性があります。著者は、git status、git log、merge conflictsなどのGitコマンドの出力の解釈方法を説明し、GitのHEADに関する用語がより一貫し、直観的であるべきだと提案します。

よく使われる git 設定オプション

- プルハンドリング:`pull.ff only` または `pull.rebase true` を使用して、上流ブランチが分岐するときにマージコミットを生成しないようにします。 - マージコンフリクトの可読性向上:`merge.conflictstyle zdiff3` を使用して、マージコンフリクトの可視性を向上させ、オリジナルコードを中央に表示します。 - 自動コミット修正:`rebase.autosquash true` を使用して、リベース中に `fixup!` コミットをターゲットと結合します。 - 自動的なスタッシュ:`rebase.autostash true` を使用して、リベースの前後に `git stash` を実行します。 - プッシュの自動化:`push.default current` または `push.default simple` を使用して、現在のブランチを一致するリモートブランチにプッシュします。`push.autoSetupRemote true` を使用して、初回のプッシュで追跡を設定します。 - デフォルトブランチ:`init.defaultBranch main` を使用して、新しいリポジトリで `main` ブランチを作成し、`master` ブランチを使用しません。 - コミットメッセージの向上:`commit.verbose true` を使用して、コミットメッセージエディタにコミットの差分を表示します。 - コンフリクト解決の自動化:`rerere.enabled true` を使用して、マージコンフリクトの解決を記憶し、自動化します。 - オートコレクト:`help.autocorrect 10` を使用して、Gitが指定された遅延後にオートコレクションを実行します。 - ディフの視覚化:`core.pager delta` を使用して、シンタックスハイライトのディフビューワーを使用します。`diff.algorithm histogram` を使用して、関数の再並びの可視性を向上させます。 - グローバルGitignore:`core.excludesfile` を使用して、グローバルgitignoreファイルを指定します。 - 別のGit Configs:`includeIf` を使用して、個人用と仕事用のリポジトリに対して異なる構成を設定します。 - データ損壊防止:`transfer.fsckobjects` と関連する設定を使用して、データ損壊を検出して防止します。 - その他の顕著なオプション:ブレーム無視、ブランチのソート、カラーセッティング、エディタ選択、コミットのクリーンアップ、コアの設定、ディフツール、メージの設定、プッシュのタグの追跡、リベースの安全性、ログの日付形式など。

分岐した Git ブランチの処理

分岐ブランチが発生するのは、ローカルブランチとそのリモートカウンターパートが異なる歴史を持つ場合です。分岐を認識することは非常に重要で、`git status`、`git push`、`git pull`などの方法で確認できます。分岐の解決方法は状況によって異なります。ひとつのアプローチは、`git pull --rebase`を使用して両方の変更セットを維持することです。リモートの変更を破棄するには、`git push --force`を使用しますが、`git push --force-with-lease`を使用することで安全性が高まります。代わりに、ローカルの変更を上書きするには、`git reset --hard origin/main`を使用します。これらのソリューションは、ワークフローと状況に基づいて分岐を解決するための選択肢を提供します。

.gitの内部

.git ディレクトリーには、Git でのバージョン管理のために必要な情報が含まれています。HEAD は現在のブランチを指します。ブランチ、コミット、ツリー、ブロブは Git の核心を形成し、コミットの歴史、ファイルのリスト、実際のコードをそれぞれ保存します。リフログはブランチ、タグ、HEAD の変更を追跡します。リモート追跡ブランチはリモートブランチの最新のコミットを維持し、タグは特定のコミットをマークします。スタッシュはコミットされていない変更を保存します。.git/config はリポジトリの設定を保持します。フックはコミットの前に自動的にアクションを実行するために使用できます。ステージングエリア(インデックス)はファイルをコミットの準備にします。この概要は .git ディレクトリーの一般的な理解を提供しますが、すべての細部をカバーするものではありません。

git コミットを差分、スナップショット、歴史のいずれかとして捉えるのか?

Git のコミットの理解は複雑で、人々は異なる精神モデルを持っています。調査によると、51%がコミットを差分(バージョン間の変更)として捉え、42%がスナップショット(ファイルの現在の状態)として捉え、わずか4%が過去のコミットの歴史として捉えています。 内部的に、Git はコミットをスナップショットとして保存し、チェックアウト時間を高速化します。ただし、スペースを節約するためにパックファイルも使用し、ファイルをデルタ(差分)として保存します。 このスナップショットベースの実装にもかかわらず、Git はデルタからスナップショットを再構築し、比較することで差分を計算します。 一般的に誤ったとされる精神モデルは、前のコミットからの差分としてコミットを捉えるものです。このモデルは、日常的な使用においては不正確ですが、依然として有用です。 最も一般的な精神モデルは、コミットを差分として捉えるもので、典型的なコードの変更に焦点を当てることに合致します。他のモデル、例えばスナップショットモデルは、ファイルの移動やマージコミットの理解に有用です。 さらに、人々はコミットと一緒に余分な情報(例えば、メール、会話)を関連付けるか、コミットを「前」状態と「後」状態として捉えることがあります。

NixOSについてのメモ

Ansibleを使用する際のアドホックな変更の問題に直面し、著者はサーバー上でNixOSを設定することを選択し、パッケージとユーザーに対するより多くの制御を提供しました。NixOSのインストールプロセスは、nixos-infectを使用し、生成された構成をコピーし、flakeを作成し、nixos-rebuildを使用して変更をデプロイすることを含みました。サーバー上でGoサービスを実行するために、著者は単一の.nixファイルでサービス構成を定義し、動的なユーザー作成と永続的なストレージを有効にしました。Nix言語の構文の複雑さにもかかわらず、著者はNixOSが提供する信頼性と中央集権的な構成管理を高く評価しました。ただし、nixos-rebuildが行う特定のチェックと、サービス更新のデプロイメントワークフローを簡単にする方法に関する疑問が残っています。一般的に、著者はNixOSが有望的であると考えているが、デバッグと言語構文の学び方の困難さも経験しました。

2023:今年を振り返って

今年、著者は、メモリー上での整数と浮動小数点数の表現を説明するジンを出版する作業に取り組みました。 また、メモリー上での変数の表現を視覚化するツール「memory spy」を作成し、整数の表現を実験するためのプレイグラウンド「integer.exposed」をリリースしました。 大きなプロジェクトの一環として、著者はPythonを使用してネットワークスタックを実装する方法を示すことを目指しました。 そのプロジェクトの第一部分、「週末でDNSを実装する」がリリースされ、多くの言語で実装が行われました。 著者は、困難な概念をアクセスしやすくするための基調講演を行いました。 また、Gitに関するいくつかのブログ投稿とプロトタイプ、例えば「git-commit-folders」や「git-oops」も公開しました。 著者は、ビジネスのロジスティックスを管理するためのオペレーションマネージャーを雇いました。これにより、著者は執筆とコーディングに集中できるようになりました。 また、Mastodonに移行し、技術的な話題に関するより適切なプラットフォームを見つけることができました。 著者は、プロジェクトの完了が予想よりも長くなることが多いという課題を認めました。 そして、独特の仕事を追求することを可能にするサポートに対する感謝を表しました。

Git コミットを NFS とのフォルダーとしてマウントする

- プロジェクト "git-commit-folders" は、Git のコミットをフォルダーとしてマウントすることで視覚的に表現する新しいアプローチを提供します。 - サポートされているファイルシステムは FUSE、NFS、WebDAV であり、WebDAV のシンボリックリンクサポートが不足しているため NFS が主な焦点です。 - 実装を同期させるために、コア FS インターフェースが作成され、NFS と WebDav 用のアダプターが作られました。 - リポジトリの多くのコミットを管理するために、プレフィックスでフォルダーに組織化し、パックされたコミットハッシュをキャッシュします。 - デバッグでは Wireshark を使用して NFS パケットを分析し、「ディレクトリーではない」や「古いファイルハンドル」などのエラーを処理しました。 - ループを避けるためにファイルパスをハッシュし、inode 番号を生成しました。 - "branch_histories" ディレクトリーは、現在各ブランチの最新の 100 個のコミットしか表示しません。 - サブモジュールは現在無視されています。 - NFSv4 のサポートがありますが、NFSv3 との比較でその利点が明確ではありません。 - プロジェクトの目的は、Git の内部構造をより直観的に理解することを目的として、コミットをフォルダーとして表現することです。

Git ブランチ:直観と現実

多くの人が、git ブランチを親ブランチからの分岐と直感的に捉えます。ただし、git は内部的にブランチを、単に "分岐" したコミットではなく、すべての前のコミットの完全な歴史として定義します。このため、すべてのブランチが同じ完全な歴史を含みます。内部的に、ブランチは最新のコミット ID を含むテキスト ファイルとして保存されます。git がブランチの関係性の概念を欠いているにもかかわらず、リベース、メルジ、GitHub プル リクエストがどのように動作するかという直感的なモデルと一致します。ただし、git のブランチとブランチの間に階層がなく、分岐コミットを分離するための非慣用的な UI が混乱を招く場合があります。GitHub のデフォルト ブランチには特別な特権があり、git の階層的な中立性にもかかわらず "特別なブランチ" の概念を強調します。

Nix フレークに関するいくつかのメモ

著者は、Nix フレークに対する初期的な懐疑心を持ちながら、フレークの有用性を理解するための旅に出ました。Docker コンテナとの類似性を描くことで、概念的な明確さを高めました。フレークが再現性と依存関係の管理において上回ることを認めつつ、著者は、中央のシステムパッケージリストを維持するためにフレークを使用することを目指しました。このアプローチで、システムの設定とソフトウェアのアンインストールの両方で利益を得ることを期待していました。 作者は、Git リポジトリ内の追跡されていないファイル、非自由パッケージの組み込み、フレーク依存関係の相対パス問題など、多くの課題に遭遇しました。'nix develop' と 'buildEnv' を使用し、望まれるパッケージを表すシンボリックリンクのディレクトリーを作成することに成功しました。 しかし、進捗を阻むビルドフック関連のエラーもありました。にもかかわらず、作者は、Nix パッケージ管理ワークフローの向上を目指し、フレークのマスターをめざしました。既存のフレークの説明が難解であったため、作者は、類似性と実践的な実験に頼り、フレークの理解を深めました。 作者のフレークに対する初めてのアプローチは、多くの困難に遭遇しましたが、Nix パッケージ管理体験をより堅牢かつ効率的なものにするという作者の願望を明確に示しています。

git cherry-pick と revert が 3-way merge を使用する方法

著者は、git cherry-pickが単にパッチを適用するものと誤解し、実際の作業原理を探り始め、より微妙なプロセスである「3-way merge」が明らかになった。この誤解は、パッチメソッドでマージコンフリクトを解決しようとしたが、失敗し、git cherry-pickの予想される動作とは異なったため生じた。更なる調査でgitのソースコードを調べた結果、cherry-pickが3-way mergeを使用していることがわかり、当時著者が知らなかった概念であった。この発見が3-way mergeの探検を促し、3-way mergeは、元のバージョン(ベース)と比較することで2つのファイルをマージするプロセスであると捉えることができる。この概念は、gitでのパッチの適用にも拡張され、コミット前のファイルバージョン、コミット後のファイルバージョン、現在のファイルの3つのバージョンがマージに使用される。cherry-pick、rebase、revertはすべてこの3-way merge戦略を使用し、主にベースバージョンとターゲットバージョンの順序と解釈で異なる。 著者は、この技術を「3-way patch」と呼び、従来のパッチと比較してマージの文脈を提供する利点を強調する。git applyは従来のパッチを処理するが、--3wayフラグも提供し、3-way mergeを実行する。gitのパッチ適用メカニズムの探検は、様々な操作に対する統一的なアプローチを提供し、従来の「パッチを適用する」概念に慣れたユーザーにとって透明なままである。著者は、gitのマージの複雑さを認め、recursive mergesや複数のマージアルゴリズムのような概念を示し、更なる探検のために「Building Git」書籍を推奨する。 最後に、著者は、gitのパッチメカニズムのエレガントなデザインを賞賛し、その直観性と効果を称賛する。