yak shaving life

遠回りこそが最短の道

「The DevOps 逆転だ!究極の継続的デリバリー」を読んだ

タイトル

The DevOps 逆転だ!究極の継続的デリバリー

ちなみに原題は「The Phoenix Project: A Novel about IT, DevOps, and Helping Your Business Win」。もはや別物…。


 

なぜ読もうと思ったか

友人(PM)が面白いと言っていたので。


書評というか感想

一言で言うと

面白いし意外とタメになったし二日で読めた。

本の内容

これは小説です。とある会社でボロボロのIT部門の責任者になりド炎上プロジェクトを任された男の話であり、あまり書くとネタバレになるのであれだけれども、とりあえずDevOps関連の技術書ではないです。継続的デリバリーの手法とか一切出てこない。

しかしこれがまたビジネス書のようでもあり、はたまた技術書のようですらある。フィクションであることは承知の上で、現実のビジネスにおいても役に立ちそうな内容満載。もちろんソフトウェアエンジニア目線から見ても。

読んでみてどうだったか

まずシンプルに面白い。若干読んでてもどかしくなったり、ご都合主義を感じた面もあるけれども、総じて楽しく読み進められた。

IT部門がビジネスに貢献ためにはどうすればいいかというのが重要なテーマなので、共感できる部分や参考にできそうな内容が結構あった。特に「4つのタイプの仕事」と「3つの道」、これは普通にビジネス書に書いてあってもおかしくないレベルで良い。自分が組織やプロセス全体について考えるときは意識してみようと思う。

あと翻訳が良い。読みやすかった。久々に小説読んで楽しかったです。

自社のIT活用がなんかうまくいってないなーという人は読んでみるとなにか発見があるかもしれません。もしなくてもまあ、面白かったらいいじゃないですか。そんな感じです。

ちなみに、同じ著者の実用書としては「The DevOps ハンドブック 理論・原則・実践のすべて」という書籍があり、こちらも評価が高い。未読だがそのうち読んでみたい。

「Learning GraphQL」を読んだ

まえがき

当時英語版しかなかったので英語版を読んだが、現在は「初めてのGraphQL」という和訳版(しかも色々追加修正されてるらしい)が出ているので日本語話者の方はこちらを読んだ方が良さそうです。

タイトル

Learning GraphQL: Declarative Data Fetching for Modern Web Apps

Learning GraphQL: Declarative Data Fetching for Modern Web Apps


Learning GraphQL: Declarative Data Fetching for Modern Web Apps

 

なぜ読もうと思ったか

そういえばGraphQLってよく聞くけど実際のところ全然わからないなーでも仕事で使いたいなーと思ったのが2年ほど前。しかし、2018年時点では日本語書籍が全くと言っていいほどなかった。仕方がないので普段読まない英語の技術書に挑戦してみた。

書評というか感想

一言で言うと

マジ良本。

本の内容

読んで字のごとく、GraphQLの入門書。自分はなんとなくのコンセプトやちょっとしたクエリの書き方ぐらいは知っていたが、GraphQL?何ソレ?みたいな人でも大丈夫です。多分。

まずGraphQLとは何か、なぜGraphQLが生まれたのかなどの概要を説明し、その後グラフ理論について軽く触れたあと、サンプルアプリケーションの実装を例に詳細に入っていく。

読んでみてどうだったか

いやーとても良かった。GraphQLについて、いろんなブログ記事やらGithub APIやらを見てなんとなく知っている気になっていたけど、全く何も分かっていなかったことに気づかされた。ありがとうございます。今は完全に理解した。(何も分からないとも言う)

本の構成が良かったのだと思うが、全体的に内容がスッと入ってきた。あと、英語が平易で読みやすかったような気がする。ただし3章のGraphQL Playgroundへのリンクが軒並み死んでいて、スキーマ全体が本文に書いていないのもあり、Playgroundで確認もできないしで割と困った。今は解消されているのだろうか…。(筆者が読んだのは2018年ごろです)

入門書として本当に素晴らしいと思う一方、これを読めばGraphQL APIを作れるようになるかというとそんなことはない。手を動かして何かしらの実装をやらなければいけない。ApolloでもGraphQL Javaでもgraphql-rubyでも使うライブラリはなんでもいいけど、とにかくやるべき。思ったよりムズい。そして、APIが大きくなってくると最適化問題にすぐぶち当たる。ここら辺の設計論やベストプラクティス、アンチパターン等がカバーされた中級者〜向け書籍が出てくれると嬉しいですね。

和訳版はRelayの解説が追加されているらしいし、そもそも英語を間違えて理解している部分がありそうなので、和訳版もそのうち読んでみたい。積読消化したつもりが一冊プラスになったのでプラマイゼロ。嬉しいような悲しいような。

まあとにかくGraphQLについて学びたい人には間違いなくオススメの一冊です。APIを作る側でなく、使う側の人(フロントエンドとか)にもおすすめ。

 

 

Jenkins Pipelineで特定の処理をDockerコンテナ上で実行する書き方3つ

Jenkinsfileを書いていて、一部の処理だけDockerコンテナ上で動かすにはどうすれば良いか調べたところ、なんか色々出てきたのでメモっておく。Jenkinsfile、たまにしか書かないのですぐに全てを忘れてしまう。

Jenkins 2系、Declarative Pipelineを想定してます。使いたいDockerイメージはDocker Hubあたりにホストしてあるものとします。

1. agentを指定する

stage の中でagentを指定できるので、必要な処理を含むstageのagentにdockerを指定しましょう。こんな感じ。

stage('Docker Pattern 1') {
    agent {
        docker {
            image 'image_tag'
        }
    }
    steps {
        // some process
    }
}

公式だとこの辺に書いてあります。Using Docker with Pipeline

ここではpipelineレベルのagentがnoneになっていますが、他のstageのagentを指定する必要がなければanyにしておきましょう。

2. withDockerContainer で処理をラップする

Docker Pipeline Plugin の機能らしい。

stage('Docker Pattern 2') {
    steps {
        withDockerContainer('image_tag') {
            // some process
        }
    }
}

stepsの中に書けるので、1. のパターンよりも細かい粒度で指定できる感じ。

3. docker.image().inside で処理をラップする

こう。

stage('Docker Pattern 3') {
    steps {
        script {
            docker.image('image_tag').inside {
                // some process
            }
        }
    }
}

この書き方はScripted Pipelineでしか使えないので、Declarative Pipeline内で使うためにはscript {}で囲う必要があります。

こちらは Using Docker with Pipeline のSidecar Patternあたりに書いてあるような書いてないような。ここではもっと高度な内容が書いてありますが、上記のようにシンプルに使うこともできるということです。

結局どれを使えばいいのか

よくわからん。

3.のパターンはScripted Pipelineで色々複雑なことをするためのモノなので、シンプルなDeclarative Pipelineで使う必要はなさそう。

1.と2.の違いはなんだろうか。Console Outputでログを見ると、1〜3全てで[Pipeline] withDockerContainerと表示されていて、同じコマンドが走っている。(唯一2.の場合だけdocker inspectを実行していないようだがどうでも良さげ)つまり内部的には同じ?ちょっとソースとかまで追う気にはなれないな…。

個人的には、公式ドキュメントに1.が載ってるんだから1.でやればいいのかな、くらいの認識で1.の書き方をしている。あとは1.だとオプションを色々指定したりDockerfileからbuildしたりというのが簡単にできるのでオススメです。現場からは以上です。

Nodebrewでnode.jsインストールしようとしたら失敗した

nodebrewでnode.jsをインストールしようとしたら失敗した。 MacOS version 10.14.6, nodebrew 1.0.1です。

$ nodebrew install v12.13.1
Fetching: https://nodejs.org/dist/v12.13.1/node-v12.13.1-darwin-x64.tar.gz
Warning: Failed to create the file
Warning: /Users/username/.nodebrew/src/v12.13.1/node-v12.13.1-darwin-x64.tar.gz: No such file or directory

こんな感じ。なんだ意味わからんな、と思って何度か試したがダメ。 ディレクトリがあれば良いのか?と思ってmkdir ~/.nodebrewしたけどダメ。 なんか権限足らんのか?と思ってchmod 2775 ~/.nodebrewとかしてみたけどダメ。

結局、一回全部消してからmkdir -p ~/.nodebrew/src/したらいけた。どーなってんだ。この島は。どーなっつ

Web API: The Good Parts を読んだ

なぜ読もうと思ったか


APIの設計・開発の難しさを実感することが多く、改めて書籍を読んでみようと思ったので、まず前から読みたいと思っていたこの本にした。

 

タイトル

 

Web API: The Good Parts

Web API: The Good Parts

 

Web API: The Good Parts

 

書評というか感想


一言で言うと

 

いやあー良い本だった。皆読むべき。

 

感想箇条書き

 

  • 良いAPI設計とはなにかを教えてくれる本
  • 「なるべくデファクトスタンダードに従う」という方針が良い
  • 有用なHTTPヘッダについての話が良い。よく使われているカスタムヘッダについてなど、独学では学び辛い内容が多い
  • 特定の言語や実装に依らない内容なので、APIを開発することのあるバックエンドエンジニアなら誰にでもオススメ
  • 有名企業のAPIを例にした解説が分かりやすい
  • 文章が読みやすく分量もちょうど良いのですぐ読みきれる
  • GraphQLへの言及はない(時期的に仕方ない)ので、そこは自分で補完すべし

 

実はよく分かっていないところ


HATEOASってあまり聞かないけど実際のところどうなんだろうか。

 

読んだ後どうするか


巻末にAPI設計チェックリストがあるので、これをアレンジして個人的に運用していきたい。

 

その他

 

読後感がすごく良かった。普段洋書の翻訳ばかり読んでいるからかもしれない。日本人著者による書籍のメリットとして、「読んでて気持ちがいい」というのは結構大きいような気がする。もちろん本によるけれども。

 

 

「Clean Coder」を読んだ

タイトル


Clean Coder プロフェッショナルプログラマへの道

なぜ読もうと思ったか

WEB+DB PRESS Vol.108|技術評論社 の懸賞みたいなアレで当たったから。こういうの全然当たったことないから妙に嬉しかった。

 

書評というか感想

一言で言うと

面白い。金言詰まってる。技術書ではなくて、プロのプログラマであるためにはどうすればいいかという心構えや振る舞い方、どういう技術を身につけるべきかといった指針を示してくれる。エッセイというか。あとRobert C. Martinの昔の苦労話が面白いし、誰しも初心者から始まるのだという希望と勇気をくれる。久しぶりに楽しくスラスラと本を読んだ気がする。


感想箇条書き

  • 第1章の最初の方でもう耳が痛かった。「プロ意識とは、自分で責任を取ることに他ならない」「書いたコードはすべてテストしなければならない」「容赦ないリファクタリング」「君のキャリアの責任は君にある」etc.. とにかく名言にあふれている
  • 「プロのプログラマは自分の時間に練習する。」これに全て詰まっている気がした
  • 「スキルを磨くのは自分の責任であり、雇用主の責任ではない」はい。すみません
  • さりげなく自分が作ったライブラリをおすすめしていてちょっと笑った
  • 第9章 時間管理、第10章 見積もりあたりは結構具体的かつ実用的なことが書いてあった
  • この本に書かれている内容はある種の理想。当たり前だけど現実とのすり合わせが必要
  • 内容は割と過激な方だと思う。誰でも何箇所かは同意できない部分もありそう。それでいいと思うけど
  • 著者の自分語りがかなり多いので、楽しめない人には向いてないかも。自分にとっては面白かった。1970年代のプログラミングがどんなだったかみたいな話とか、興味深さしかない

 


読んだ後どうするか

モチベーションが上がったので、「自分の時間に練習する」ために何か作り始めようと思う。というか始めた。あとは「週〇〇時間」といった感じで継続して取り組めるような仕組みを作りたいところ。
あと、すべてのソフトウェアのプロが備えるべき最低限のことというのが挙がっていたので、最低限になれるよう勉強する。


その他

「Clean Code」と名前が紛らわしすぎると思う。Clean Codeだと思ってこの本を読んだら怒りで発狂することであろう。南無三。
 

 

 

Rubyで配列の全要素に対する繰り返し処理の「正しい」書き方(Ruby 2.6.0 Ver.)

久々にRubyを触っていて、色々調べることが多い。

この間見つけた10年前のstack overflowがなんとなく面白かったので適当に言及してみる。「Rubyで配列の全要素に繰り返し処理する正しい方法はなんですか?」

stackoverflow.com   上から二番目の回答が好きなので、適当に訳してみる。

多分「正しい」方法はないんじゃないかな。イテレート(反復)の方法はたくさんあって、それらは適材適所だからね。

  • each は色んな場面で使えるよね。インデックスとかどうでもいいことが多いし。
  • each_ with _index は Hash#each に似てる。値とインデックスを扱える。
  • each_index はインデックスだけ。あんまり使わない。"length.times"と同じだね。
  • map はイテレートするもう一つの方法。配列を別の配列に変換したいときに便利。
  • select は配列の一部を抜き出してイテレートしたいときに使うやつ。
  • inject は全要素の和とか積を出すのに便利。あとはある一つの結果にまとめるようなとき。

なんかたくさん覚えなきゃいけないっぽいけど、心配ない。別に全部覚えなくてもなんとかなる。ただ、複数の異なるやり方を覚えてそれを使い始めれば、コードがより綺麗になる。そしてそれは、Rubyをマスターする道のりの一つでもあるんだ。 


どんな言語でもイテレート処理は微妙に違うので、こういうシンプルかつ適切なアドバイスができる人はすごくいいなあと思う。新しい言語を触るときにこういう記事があるととても助かる。(どうでもいいけど、injectよりreduceの方がしっくりくるんだけどな…と思ったらエイリアスされてるらしい。よかった)


ところで、この回答がされたのは2008年12月。当時のRubyの最新バージョンはいくつだろう。Release Noteを見てみると、どうやらRuby 1.9.1-preview1が最新で、普通に考えたらRuby 1.8.7-p72がプロダクションで使える実質最新版だったと思われる。

つまり、この回答にはRuby 1.9以降で追加されたメソッドが考慮されていない。Rubyに詳しい人ならそんなの当たり前だろという感じかもしれないが、僕みたいな未熟者はリファレンスを見ないと安心できないので、Arrayクラスと親のEnumerableクラスのメソッドを確認してみる。

プログラミング言語 Ruby リファレンスマニュアルのArrayとEnumerableのページについて、Ruby 1.8.7Ruby 2.6.0を比較してみる。2.6.0にのみ存在するメソッドは以下の通り。

# Arrayクラスのメソッド
append
push
bsearch
bsearch_index
difference
dig
filter!
select!
to_s
keep_if
max
min
prepend
unshift
repeated_combination
repeated_permutation
rotate
rotate!
sample
sort_by!
sum
to_h
union

# Enumerableクラスのメソッド
chunk
chunk_while
collect_concat
flat_map
each_entry
each_with_object
filter
grep_v
lazy
slice_after
slice_before
slice_when
sum
to_h
uniq

この中で配列の全要素探索に関係しそうなのはeach_with_object、sum/max/minあたりだろうか。

each_with_objectはinjectに似ているけどチョットチガウ的な感じ。https://blog.arkency.com/inject-vs-each-with-object/にいい感じの解説が書いてあった。個人的にはExample 2がわかりやすいと思う。(Example 1はなんかこう、それmapでええんちゃうの…と思ったので)

sum/max/mixは、この辺使えば全探索はいらないよという感じ。シンプルに便利。特にsumについては、上の記事で「総和はinjectで出せるよ」と書いてあるものの、sumの方がinjectで足し合わせるより早いらしいので覚えておくべきだろう。というかむしろ、以前はわざわざ全要素探索して加算や比較しないと出せなかったのかな。C言語かよ。もともとRuby 1.8を使っていたけど全然覚えてないな…。



まあそんなわけで、Ruby 2.6.0で配列の全要素探索するときは以下の7個+3個くらいのメソッドをおさえておけばよさそうです。なんか足りてなかったら誰か教えてください。

全探索

  • each:インデックスいらないとき
  • each_with_index:インデックスほしいとき
  • each_index:インデックスだけほしいとき
  • map:別の配列に変換したいとき
  • select:一部の要素だけ抜き出して全探索したいとき
  • inject (reduceでも可):全探索しながら結果を積み上げたいとき
  • each_with_object :初期値ありでmapみたいなことがしたいとき(※個人の意見です)

以下を使えば全探索が不要になるよ

  • sum
  • max
  • min



補足:バージョン間のメソッド一覧差分の出し方

リファレンス上でいい感じに見れるかと思ったけどなんか無理っぽかったしGithub上でdiffを見ようにもちょっと辛かった。ので、リファレンスの目次のメソッド一覧をコピペした上でこんな感じのことをした。Macです。

# 1.8.7のメソッド一覧をコピペ
pbpaste | sed -e 's/ /\'$'\n/g' > rb_array_1.8.7
# 2.6.9のメソッド一覧をコピペ
pbpaste | sed -e 's/ /\'$'\n/g' > rb_array_2.6.0

# 2.6.0にだけあるメソッドの一覧表示
diff rb_array_1.8.7 rb_array_2.6.0 |grep '>' |sed -e 's/> //g'

もっと簡単な差分の出し方があったら誰か教えてください。



蛇足

https://docs.ruby-lang.org/ja/2.6.0/class/Array.htmlインスタンスメソッド一覧、アルファベット順に並んでると見せかけてunshift だけ真ん中の方にあるのはなぜだろう。誰か教え(略)