サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
Switch 2
blog.lufia.org
最近、Goで関数呼び出しを無限に繋げる書き方を気に入っています。文字で書いても伝わらないと思うので実例を挙げると、例えばこういう書き方。 repeat(yield)("しか", 1)("のこ", 3)("こし", 1)("たん", 2) どうやって実現しているのかというと、自身を参照する型を作ればいいだけです。 type Emitter func(s string, n int) Emitter func repeat(yield func(string) bool) Emitter 完全なコード例は以下のGo Playgroundを見てください。 range over funcでしかのこのこのここしたんたん このような、関数呼び出しを繋げる方法でパイプライン演算子を再現するとどうなるか?と思って試してみた記事です。 パイプラインを作る パイプライン演算子を使うと、 c(b(a(10)))
Goで単体テストを実装する場合、動的な言語のように「テスト実行中に外部への依存を置き換える」といったことはできません。代わりに、 外部への依存を引数で渡す 外部への依存をインターフェイスで渡す のように、テスト対象をテスト可能な実装に変更しておき、テストの時は外部への依存をモック等に置き換えて実行する場合が多いのではないかと思います。 個人的な体験でいえば、テスト可能な実装に置き換えていく過程で設計が洗練されていく*1ことは度々あるので、面倒を強制されているというよりは設計を整理するための道具といった捉え方をしているのですが、そうは言っても動的な言語に比べると面倒だなと感じるときは少なからずあります。既存の実装がテスト可能になっておらず、変更するコストが高い場合は特にそうですね。 そんなとき、気軽にモンキーパッチできると嬉しいんじゃないかと思って、テストの時だけ関数を置き換えられるようなラ
前置き 以前、BuildInfoからバージョンを取得する方法を紹介しました。 blog.lufia.org go installで正規の公開されたバージョンをインストールした場合は、以下の出力においてmodの行が示すように、sum.golang.orgでチェックサム等が検証されてバイナリのメタデータに埋め込まれます。 $ go version -m dotsync dotsync: go1.22.2 path github.com/lufia/dotsync mod github.com/lufia/dotsync v0.0.2 h1:JWm92Aw8pSKJ4eHiQZIsE/4rgwk3h5CjEbJ/S30wiOU= build -buildmode=exe build -compiler=gc build -trimpath=true build DefaultGODEBUG=ht
最近のGoには、関数やパッケージを非推奨と扱う方法があります。まとまっていると便利かなと思うので、種類ごとにまとめてみました。GoDocコメントを多用するので、GoDocを書き慣れていない場合は以下も参考にしてください。 blog.lufia.org 関数と型を非推奨にする 関数コメントに、// Deprecated: ではじまる段落を追加します。 // Parse parses a string of the form <status>=<status>. // // Deprecated: Use ParseStatusMap instead. func Parse(src string) (map[Status]Status, error) { ... } 型の場合も同様に。 // Error is the interface that wraps Error method. //
TL;DR Reusable workflowにタグを付けて、参照する側のリポジトリはDependabotなどで更新するといいと思う リポジトリごとにDependabotのプルリクエストをマージする手間は必要になる GitHub Actionsのscheduleトリガーでcron式を書けるが、60日以上更新がないリポジトリでは無効になるので使いづらい 背景 個人で複数のリポジトリを管理しているとき、それぞれだいたい同じようなワークフローを管理しているのではないかと思います。例えば私はGoを使って開発することが多いのですが、その場合、リポジトリには以下のようなワークフローを作ります。 jobs: test: strategy: matrix: os: ['ubuntu-22.04', 'windows-2022', 'macos-12'] go: ['1.20.x', '1.19.x'] r
標準のnetパッケージには、ホスト名とポート番号を操作する関数がいくつか用意されていますが意外と知られていないようなので、便利だけどあまり知られていない関数を3つ紹介します。 TL;DR Goで、pathの結合はfilepath.Joinを使えというのは広まっている気がしているけど、同様にホストとポートを:で結合するのはnet.JoinHostPortを使ってほしい。fmt.Sprintfの場合、IPv6アドレスには:が含まれるので困ることになる。— kadota (@plan9user) 2022年10月17日 ホスト名とポート番号を:で区切られたアドレスに変換する Goでコードを書くとき、localhost:8080のようにホスト名とポート番号を:で区切ったひとつの文字列として表現することがあります。この表記はAddressと呼ばれており、例えば以下のような関数で使われています。 pa
これはOpenTelemetry Advent Calendarの14日目です。 qiita.com どんな話がいいかなと考えていたのですが、ここでは「アプリケーションとOpenTelemetry Collectorがどのように関わってメトリックを(Prometheusなどの)バックエンドサービスに送信するのか」を見ていこうと思いました。今からOpenTelemetryを触るならOpenTelemetry Collectorは実質必須なコンポーネントだと思うで、関係を把握しておくと嬉しいことがあるかもしれません。 OpenTelemetry Collectorとは何か 記憶によると、2020年頃はOpenTelemetry Collectorが存在していなかったので、過去に書いたOpenTelemetryでメトリックを記録するではアプリケーションにExporter*1を組み込んでいました。
最近、SteamをLinuxにインストールしてWindowsのゲームを遊んでいます。Steamのインストール自体はそんなに困ることはありませんでしたが、コントローラーやパフォーマンスのところでいくつか悩んだところがあったので忘れないように記事にします。グラフィックスやハードウェア関連は本当に素人なので勘が働かなくて難しかったですね... 今どきのLinux事情 手元の環境 2022年12月現在、私物では2021年のVAIO Z勝色特別仕様にArch Linuxを入れて使っています。セットアップは12インチMacBookにArch Linuxをインストールしたときの内容とほとんど同じですが、ゲームに関係ありそうな要素はこの辺りでしょうか。 GNOME Wayland PipeWire+WirePlumber Steamのインストール Steamを動作させるには32bitアプリケーションのサポ
Goのソースコードをきれいに描画する目的で作られた「Goフォント」があるのをご存じでしょうか。周囲に聞いたところ、あまり知られていなかったので、紹介の意味も込めてインストール方法を書きます。 Goフォント Goフォントは、2016年に以下の記事で公開されたもので、単体で配布されたものではなく、golang.org/x/exp/shinyパッケージの一部として配布されています。 go.dev コミットログを見る限りでは、2016年にv2.004、2017年にv2.008がリリースされた後しばらく更新されていませんでしたが、2022年6月17日にv2.010がgolang-nutsで告知されました。 groups.google.com フォントの画像は上のブログ記事にもありますし、Goのコードを書きながらAcmeエディタの基本を覚えるチュートリアルの途中からはGoフォントでGoのコードを書いて
以前の記事で、ルートファイルシステムを暗号化する手順を紹介しました。 blog.lufia.org ルートとなるボリュームを暗号化すると、再起動のたびにパスフレーズの入力を促されますが、何度も入力するのは面倒です。そこで、TPMデバイスに鍵を保存してパスフレーズの入力を省略しました。パスフレーズの入力が必須な状態と比べると少しだけセキュアではなくなりますが、個人的には許容できる範囲かなという印象です。 若干丁寧に説明を書いたので長い記事になってしまいましたが、証明書や鍵の管理を(直接は)していないので、やること自体はそこまで難しくないと思います*1。 セキュアブートを有効にする 後で説明していますが、TPMデバイスの保護機構では「セキュアブートの設定が変更されたときに保存している鍵を読み取れなく」できます。そのため、この手順でセキュアブートを有効にしていますが、不要なら飛ばしても影響はない
2021年の11月に、業務端末としてDELL XPS 13を購入して、Linuxデスクトップに移行しました。いまでは快適に使えるようになりましたが、Linuxデスクトップに慣れていないこともあって思ったように動かず困ったところがあったので、導入にあたって悩んだところをまとめました。 ディスクの暗号化 業務利用の要件にディスクの暗号化があるので、bootパーティションを除いて暗号化しました。手順は過去記事に追記しました。 blog.lufia.org GNOME KDE Plasmaの方がスタイルは好みですし、実際に業務端末でも2ヶ月ほど使っていましたが、Wayland環境ではタッチパッドの左右スワイプが動かないとか、XWaylandで動作するアプリケーションを4Kディスプレイで表示するとぼやけた表示になるなど厳しいなと思いました*1。個人で使うものなら、少し効率が悪い程度なら問題にしません
手元のデスクトップ環境をLinuxに切り替えました。2009年頃からmacOS(当時はMac OS X)を使っていたけど、QEMUやFUSEを不自由なく使える方がPlan 9との相性が良いので、Linuxの方がいいかなと思ったのでした。 やったこと MacBook10,1 (Retina, 12-inch, 2017)にArch Linuxをインストールしました。このハードウェアではネットワークなど一通り使えていますが、バージョンによっては使えないケースもあるようです。MacBook Proの対応状況はState of Linux on the MacBook Pro 2016 & 2017にまとまっていますが、MacBookのものは無いので、近いハードウェアから推測する必要があります。 バックアップを取得 事前にMacBookのバックアップを取得しましょう。Time Machineがいち
2021年3月23日に、ノキアから、Plan 9の著作権をPlan 9財団に譲渡する発表がありました。 www.bell-labs.com 翻訳はこちら。 okuranagaimo.blogspot.com 元々、AT&Tの一部門が独立してLucent Technologiesとなっていて、ベル研はそこに含まれていたけれども、いつの間にかノキアに買収されていたらしいですね。 何が変わったのか 以前のPlan 9はLucent Public License 1.02*1でライセンスされ、ベル研(plan9.bell-labs.com)により配布されていました。ユーザーはreplicaコマンドを使ってベル研の中央サーバからアップデートを取得し、必要ならサーバへパッチを送ることが行われていましたが、2015年1月を最後に、Plan 9のメンテナンスを行う人がいなくなり、しばらくしてからは*2ベル
Goアセンブリの書き方からビルド方法までを一通り調べました。Goアセンブリを書いたことのない人がコードを書いてリンクできるところまでは一通り書いているつもりですが、Goアセンブリの言語仕様を網羅してはいないので、興味があれば最後に書いた参考情報も読んでみてください。 この記事ではGo 1.16.xでAMD64命令セットを扱いますが、具体的な命令や値のサイズ以外は、他のアーキテクチャを使う場合でもだいたい同じだと思います。 アセンブリコードの書き方 GoのアセンブリはPlan 9アセンブリを概ね踏襲していて、AT&T記法です。整数を受け取って、それに2を加算した値を返す関数func add2(i int32) int32を書いてみましょう。アセンブリのコードは.sファイルに書きます。また、アセンブリはアーキテクチャに強く依存するので、Goの習慣にしたがってファイル名にはアーキテクチャ名も入れ
2022年8月、Go 1.18対応版にアップデートしました 久しぶりのGoネタです。Go 5 Advent Calendar 2020の18日目が空いていたので書きました。 Goで実装されたコマンドでは、ビルドした時点のバージョンを埋め込むため以下のようなMakefileを用意することがあると思います。 .PHONY: build build: go build -ldflags '-X main.Version=$(VERSION)' しかしこの方法では、go installなどMakefileを経由せずビルドしたバイナリには適切なバージョンが埋め込まれない問題があります。個人的な意見では、可能な限りgo getでインストールできる状態を維持した方が良いと思っていますが、バージョンを埋め込むためには他に方法がないので仕方がないと理解していました。しかしGo 1.19現在、runtime/
CPUやメモリの統計は/proc以下のファイルを見れば調べられますが、ファイルシステムの容量などはどうやって取得しているんだろうと気になったでdf(1)のコードを眺めてみました。 coreutils: df.c coreutils: fusage.c macOS: df.c ライブラリの動作検証で用意したコードはこちら。 dfが何を使って出力しているのか調べたコード · GitHub Linuxの場合 Linuxでは、ファイルシステムの情報はstatvfs(3)で取得できるようです。これはstatfs(2)システムコールのラッパーという扱いですが、基本的にはstatvfs(3)を使うように推奨されます。statvfs(3)は以下のように使います。 #include <stdio.h> #include <string.h> #include <stdint.h> #include <int
この記事はQiitaで公開されていました ユーザ操作などで、同じAPIを同時にリクエストされたけれど、例えばGETメソッドの場合は結果もほとんど同じになるので、リクエストを1回にまとめてしまいたい場合は少なくないと思います。 または、期限付きの認証トークンが必要なAPIを並行して実行しているケースで、トークンの期限が切れた直後で同時に2つのリクエストが行われても、トークンの更新は1回だけに制限したい場合もあるかもしれません。 そういった、「複数の呼び出しが同時に発生しても、結果は同じなので同時に1つだけ行って結果を共有する」という処理に、x/sync/singleflightが使えます。 実装例 重複の排除を行いたい部分を、singleflight.GroupのDo(name, fn)でラップします。以下の例では、1ミリ秒ごとにcallAPI("work")が実行されますが、callAPI
この記事はQiitaで公開されていました 例えば、APIの結果を使った処理を行う場合、ユーザとしてはなるべく早く処理をしたいけど、早すぎるとサーバの処理が追いつかないケースはよくあると思います。 そういう時、APIを実行した後でtime.After等を使って少し待ってから、必要な結果が揃うまで繰り返すというのが簡単な解決方法ですが、APIの実行時間とtime.Afterで待つ時間の両方が実行時間に掛かってきますし、「1秒間に100回まで」というケースはなかなか対応が難しいので、x/time/rateを使ってみました。 制限しない実装 比較のために、何も制限をしない実装を用意しました。10万件のデータをチャネルに送り続けるだけのコードです。 package main import ( "fmt" ) const N = 100000 func main() { c := make(chan
READMEにpkg.go.devのバッジを貼る godoc.orgはpkg.go.devに移行していくことが告知されているので、新しいプロジェクトではREADME.mdに貼っているバッジを移行しましょう。pkg.go.devのURLやバッジは // バッジ https://pkg.go.dev/badge/<package path> // リンク https://pkg.go.dev/<package path> の形を取ります。例えばgithub.com/lufia/backoffの場合は以下のように書きます。 # Backoff ...summary... [![GoDev][godev-image]][godev-url] ...description... [godev-image]: https://pkg.go.dev/badge/github.com/lufia/back
この記事はQiitaで公開されていました GoでHTTPリクエストを行いたい場合、一般的には net/http のhttp.Getやhttp.Postを使うことになると思います。もしくは少し複雑なリクエストする場合、http.NewRequestを使うかもしれません。 net/httpの公式ドキュメント 上記どの方法を使うにしても、これらのリクエストはhttp.Client.Transportを通して、最終的にhttp.RoundTripper.RoundTripが呼び出されることになりますが、http.Client.Transportは http.RoundTripper インターフェイスを満たしていれば良いので、ユーザが自由に置き換えることが可能です。http.RoundTripper の実装については、過去や今年のアドベントカレンダーに記事があるのでそちらを参照ください。 Go ht
Gitは認証の必要なリポジトリへアクセスするとき、ユーザ名とパスワード入力を必要としますが、アクセスするたび入力するのは煩わしいので、資格情報を記憶するために、git-credential-から始まる名前のカスタムヘルパーコマンドが存在します。これらカスタムヘルパーはGitから標準入出力を扱う普通のコマンドで、標準入力経由でGitから渡されたパラメータに従って、対応するパスワードを標準出力を介してGitへ返します。ヘルパーコマンドが呼ばれるルールはgitcredentials(7)に書かれています。 これらのヘルパーコマンドとGitの間で使われるプロトコルがGit credentialプロトコルです。プロトコルは1行に1つのキーバリューが書かれるテキストプロトコルで、リクエストは空行で終わります。ヘルパーコマンドは空行までを読み取って、不足しているパラメータ(通常はパスワードだけ)を返しま
この記事はQiitaで公開されていました Goでドキュメントを書くとき、一般的にはGoDocを使うと思います。GoDocはシンプルにみえて、実際は色々な書き方をサポートしていますし、ブラウザで単純に表示する以外の読み方もあるので、一通りの方法をまとめてみました。 ドキュメントの書き方 GoDocではソースコードの中に、ある決まった形でコメントを書くと、そのコメントをドキュメントとして扱うことができます。具体的には、パッケージ、型、定数、構造体フィールド、関数・メソッドそれぞれの直前に、空行を入れずコメントを書きます。これらの前に改行を入れてしまうと、ただのコメントになってしまいます。 装飾について GoDocは、大きなドキュメントのために、ヘッダと整形されたテキストの2通り装飾ができます。ただし、リストやテーブルなどは対応していません。 ヘッダ 以下の条件を全て満たせば、ヘッダとして認識さ
この記事はQiitaで公開されていました ほとんど情報がなかったので調べながら書いたメモ。基本的に、公式情報が最もまとまっている。 Using a Jenkinsfile Pipeline Syntax Pipeline Steps Reference Jenkins Job DSL API また、古い情報らしいけど、現状こちらにしか書かれていない項目もある。 pipeline-model-definition-plugin Wiki Declarative Pipelineの1.2.8から、ジェネレータが追加されたようです。 The new things arriving in Declarative Pipeline! 基本 現状のJenkinsfileは2通り書き方があって、pipelineがルートになっている場合はDeclarative Pipelineという。この場合は、Groo
Go 1.13までのゴルーチンの切り替えは、チャネルの送受信やシステムコール呼び出し、関数呼び出し前にコンパイラが暗黙的に挿入する処理などによって行われていました。そのため、上記の切り替わり操作を全く行わないループなどがあれば、そのゴルーチンがずっと実行されます。 func loop() { // この辺りにコンパイラがコード挿入している for { // 切り替わり処理が行われないので無限に実行される } } この結果、$GOMAXPROCSが1の場合はプログラムが停止します。コンパイラが挿入するコードは、インライン展開された場合やgo:nosplitディレクティブが記述された場合には行われないので、関数呼び出しをしていてもゴルーチンが切り替わらない場合はあります。 ゴルーチンの切り替えと関数のスタックチェック go doc compile/Compiler Directives Goの
Goモジュール管理下では、プロジェクトで使うGo製ツールのバージョンも管理できます。今までの経験では、ツールのバージョンが上がって困ることは記憶にないですが、とはいえ2018年5月ごろにprotoc-gen-goが大きめの変更を入れたこともあるので、バージョン管理しておいて損はないでしょう。このハックは、割とGoモジュール初期からあったようですが、最近使ったので書きました。 Go 1.11 Modules - How can I track tool dependencies for a module? Go modules by example - Tools as dependencies 使い方 ツールを追加する Go 1.13時点では、モジュール管理しているリポジトリでgoimportsなどのツールをgo getすると、go.modが書き換えられて管理対象に入ります*1が、恒久的に
OpenTelemetryトレースの例はいっぱい見つかりますが、メトリックはまだ実装中*1だからなのか、ほとんど見つからなかったので調べたことをまとめました。 OpenTelemetryの概要は公式ドキュメントのOverviewを眺めると雰囲気わかると思います。 Overview 2020/04/30追記: いくつか変更があったので大きめの差分を以下の記事にまとめました blog.lufia.org 使い方 OpenTelemetryでは、メトリックの記録と、メトリックをバックエンドサービスへ送るためのExporter設定を行う必要があります。ExporterはStackdriverやPrometheusなど標準で用意されていているものを使うこともできるし、なければ自分で作ることもできます。この記事では、(せっかく作ったので)Mackerel Exporterを使ってコードを書きますが、ど
この記事はPlan 9 Advent Calendar 2019の2日目です。 ベル研の公式ディストリビューションは、2015年1月に最後のメンテナだったGeoff Collyerさんが離職されたことにより、現在活動が停止していますが、代わりにコミュニティで派生したものがいくつかあり、現在はそれらを使う方が主流です。あまり情報がまとまっていないので、個人的に把握しているものについて今から始める人のために様子をまとめてみます。 Plan 9 from User Space (plan9port) Plan 9 from User Space インストール方法は過去に書いたのでこちらを参照ください。 Plan 9 from User Space(plan9port)を使う - Qiita これはOSではなく、Plan 9ツールをUnixに移植したものです。当然、Plan 9カーネルが提供する名
2018年の夏頃から、時間をみつけてはPlan 9にGitを移植していて、概ね動いたので公開する。ソースコードはこの辺りにある。 https://github.com/0intro/plan9-contrib/pull/6 https://github.com/0intro/plan9-contrib/pull/7 https://github.com/madler/zlib/pull/398 https://github.com/libressl-portable/portable/pull/510 https://github.com/libexpat/libexpat/pull/242 https://github.com/curl/curl/pull/3701 https://github.com/git/git/pull/604 GitへのPull requestが個人的な平成最
Goでファイルの存在確認について、インターネットではos.Statの戻り値がエラーかどうかを判定する方法が紹介されていますけれど、os.Statはファイルが存在する場合でもエラーを返すことがあるため、この方法では正しく判定できないケースが存在します。また、複数プロセスが同じファイルにアクセスする場合は、os.Statの直後で、別のプロセスによってファイルが作成されたり削除されたりするかもしれません。正確に存在確認する場合は、存在確認した後に行う処理によっていくつかパターンがありますが、基本は、事前に存在を確認するのではなく、意図しない場合にエラーとなるようなフラグを立てておいて、OSのシステムコールが返したエラーを判定することになります。 Cなどでは、Unix系OSと異なり、Windowsは別の関数とフラグを、Plan 9は別のフラグを使いますが、Go標準パッケージのsyscallはその辺
次のページ
このページを最初にブックマークしてみませんか?
『blog.lufia.org』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く