え!何?なんで今まで買ってなかったの!!
今まで割と簡易なキースイッチプラーを使って、うまくキースイッチを抜けずに苦労していたのだけど、この形のプラー、一発でバシっとハマって、シュッと抜けて最高だ!
キースイッチの交換をする人は、絶対にこの形のキースイッチプラーを買った方がいいよ!!
どんどんキースイッチを買って、どんどん交換する機運か!(待て)
2023年のお買い物、技術書編です。
技術書以外はこちら
他に、類似の本がないか、有ってもこっち買っておけばよくね?という3冊
Scalaをベースとした関数型プログラミングの学習本。オブジェクト指向言語であり、関数型プログラミング言語であるScalaの特性を生かして、命令型から宣言型のコードの書き方への変え方を学んでいくスタイル。
前半の凄まじい丁寧な学習のステップと、後半の「ここまで一気にやらなくても良くない?」の落差もすごいけど、ページ数の厚さに躊躇せず、前半1/3くらいを時間をかけて丁寧に学習するくらいが良いと思います。
周りに良い先生が居れば別ですが、そうでなければこの本でじっくり学ぶのはかなりお勧めです。
プロパティベーステストの本がこの先、さらに日本語で出版される日が来るのか分かりませんが、かなり確率は低い気もするので、さっさとこの本を読んで学習しておくと良いと思います。
例題がErlang、Elixirなので、プロダクションコードを書く言語としては決してメジャーとは言えない言語ですが、逆に言えば自分が使っている言語用のプロパティベーステストのライブラリを使って書き換えていく、という学習法が取れるところが良いですね。
出版自体は2022年の12月の終わりですが、今年に入っても何度か読み直しましたし、色々な人にお勧めしました。今年の本といってもいいかな。
表紙のかわいさに騙されてはいけません。これ本当にちゃんと理解する気持ちで、コードを書いたり、周辺情報を調査したり、周りの人とディスカッションしながら読み進めたら、平気で1年かかる密度の本です。
現代的なソフトウェアのプラクティスが、ものすごい密度で書かれています。でも表層的に読んで「へーそうなんだ」と思っても、意味はないので自身の血肉となるまで考えながら読むことが大切です。
残念ながら現時点で入手する方法が存在しませんが、カンファレンスや勉強会を運営する人のためのリファレンスの決定版。長年勉強会を開催してきた人でも、新たな学びや視点がてんこ盛りなので、機会が有ればぜひ読んだ方がいいです。
早く日本語版が出ないかなー、出たら色んな人にお勧めするのになーと、邦訳を首を長くして待っている1冊。
Scalaをベースに、関数型プログラミング用のライブラリ(Listとか、Optionとか、Stateとか)を実際に作りながら、その概念を理解する、というストロングスタイルな1冊。
『なっとく!関数型プログラミング』が、表側(利用者視点)から関数型プログラミングを学ぶ本だとしたら、こちらは裏側(ライブラリの提供者側視点)から関数型プログラミングを学ぶ本といえます。 この2冊をセットで読み進めて、そのテストを『実践プロパティベーステスト』による理解を元に、プロパティベーステストで書けばかなりの実力がつくこと間違いなしです。
1st Editionはずいぶん前に日本語訳が出ていて、今でも内容は全然古くなっていないので、Scala3対応や、回答の解説はGitHub上のサンプルコードを読み解きます!という人にはこちらでも大丈夫です。ただ、練習問題の解答例が本誌上に無い中で読み進められる人はなかなか居ないかも……とは思ってしまいました。
スクラム開発をどうやってスケールさせていくか?その方法論はいくつか有るけど、その中でも「Scrum@Scale」をベースにコミュニケーションを軸とした組織の作り方、運用の仕方を解説していく本。
組織論みたいな本、なかなか苦手なのですが、これは開発組織をスケールさせるための本、ということで非常に興味深く読むことができました。
個人的には、本書の中心的なテーマであるトレードオフではなく、「7章 日付と時間のデータを効率よく扱う」の内容が一番刺さった。この章、全然トレードオフの話をしていなくて、いかに日付や時刻、時間を扱うライブラリの設計が難しいのか?ということが延々と語られる章になっている。他の章も十分に役に立つのだけど、これだけ身近なテーマである「日付と時間」がここまで大変な設計の上に成り立っているのか!ということはみんな理解しておいた方が良いと思う。
ブログのエントリも凄いブクマを集めたけど、みんなそれだけこのテーマに関心が高い、ということなのだと思っている。
若干、タイトルと中身のメインテーマがずれていると思うけど、投資フェーズと組織の開発戦略、採用を絡めて論じる、という切り口がすごく新鮮で、これは(それぞれの会社ごとに状況は違っているかもしれないが)、読んでおいて損の無い1冊だな、と思いました。
どんどんアプリケーションを構成するコンポーネントが増えていくなかで、「監視、つらい」という場面も増えてきました。
本書は、構造化ログ、トレース、OpenTelemetryというキーワードを元に、どうやってアプリケーションのリアルな振る舞いを追いかけ、おかしな挙動を速やかに検知するのか、ということを理解するための本です。
いやー、ほんと、異常終了すればスタックトレースと、アクセスログを見ればよかった時代は、もう遠い過去の世界なんですね、というか、なんでこんなに辛いんだっけ?というと、それを軽減するための仕組みを導入していないだけでは?という話に行き着くので、まずは読んでおきましょう。
令和最新版のシェルスクリプトの入門書とリファレンスがセットになった1冊。
ブログのエントリでも書きましたけど、なんかコンテナの勉強しているのか、シェルスクリプトの勉強をしているのか自分でも分からなくなってきたので、もう一回腰を据えて勉強するぞ!と思って読みました。
Rustとか、コンテナとか、クラウドとか、その辺が全然フォローできていないんですけど、それはそれであくまで自分の興味の向くままに読んだ結果なので。
積んだまま読めていない本も本当にたくさん有るし、読んでも紹介するほどでもないな、と思った本はブログにも書いてませんしね。
というわけで、来年も色々な本を読んでいきたいと思っています。
なお、技術書を除くと、この2冊がよかった。
前者は小沢健二のソロデビュー時のマネジメントや、数々のコンピレーションアルバムの編集をやっていた井出靖さんの視点から見た90年代の東京の音楽シーンの回顧録。 後者は三体の前日譚というか、直接の繋がりは無いけど、いかにも劉 慈欣らしい、静かなムードの中で進むSF。
『井出靖 / Rolling On The Road 僕が体験した東京の1960年代から90年代まで』
『劉 慈欣 / 三体0【ゼロ】 球状閃電』
なお、2022年版はこちら
2023年に買ったもの
技術書以外編
技術書編は、こちら
特に説明不要なノイズキャンセルヘッドホンの定番。それまで使っていたWH-1000XM3が完全に壊れてノイズキャンセルどころか、謎のノイズが出てしまう症状が出たため買い替え。
Bluetooth接続が圧倒的に早くなったのと、マルチポイント接続により同時に複数の機器と接続できるようになったのは、割と頻繁に接続先を変える自分はとても利便性が上がったので、それだけでも買い換える価値が有った。
ノイズキャンセルの効きも良くなり、地下鉄や飛行機などの、ノイズが多い移動手段が多い人にはぴったりの一台。
5万円を超える価格はオーディオ機器としてみるとちょっと高いけど、音楽鑑賞から、オンラインミーティングまでこれ一台でなんでもできてしまうので、コストパフォーマンスは非常に高い。一時はほんと朝から晩までずっと付けっぱなしで過ごしていた。
自宅でのオンラインミーティングなどで、独立マイクも用意できるし、ノイズキャンセルが不要な場所ではこちらを使うようにしている。
有線の煩わしさは有るけど、軽いのと、充電を気にせず使える気軽さもいいし、どんな環境でも「とりあえずプラグを刺せば音が出てくる」という安心感は、とにかく安定しておいてほしいオンラインミーティング環境では必須。
これも複数のPCを使い分けることが多いので、その切り替えごとに、操作をしたくない、という観点で有線の安心感を選択。
ソニーのヘッドホンといえば、MDR-CD900STも惹かれたけど、接続がミニプラグの方が直接PCに挿せて便利なので、MDR-7506を選択。
年齢が上がったせいか、だんだんと集中力の持続時間が落ちてきているなーと感じることが多くなってきたので、見やすいタイマーを導入。
厳密に、ポモドーロテクニックを使っているわけではないですが、15分とか、30分とか、「この決めた時間の間は集中する!」と決めると、それなりに集中力も持続するので、重宝しています。
何のギミックも無く、ただぐるっと手でツマミを回した分だけ時間を測る簡単仕様。
あと、デザインがかわいくて、机の上に置いておきたくなるデザイン。
今年だけで2台も買ってしまった。
ここ数年色々なメーカーからミニPCが発売されていて、あまりの価格の安さに採算取れるのかな?と心配になるのだけど、サポート面などでの不安も聞こえてくる。
そのため、ちょっと価格帯は上がるけど、Lenovo純正の複数年サポートが付けられる安心感を優先して選択。
主な使い方は、プリインストールされているWindowsを完全に消去して、Linuxをインストールして、個人の開発環境用。 やっぱりWSLより、素のLinuxが動く環境が有った方が余計な苦労をしないで済むのが楽だし、一台の高スペックPCより、複数台のミドルスペックPCの方がコストパフォーマンスも良い。
Lenovoの場合、Linuxからでもファームウェアアップデートが可能なところもオススメのポイントの一つ。
若干ファンが煩いので、普段はテレビボードの下にしまい込んでリモートアクセスでしか使わないけど、そういう使い方ができるのもミニPCの良いところ。
Keychronから出ているHHKB完コピメカニカルキーボード。
本家は、HHKB Studioを出したけど、割とギミック多めで、それは特に要らないかも...という人向け。
とにかくシンプルなデザインがイイ!有線専用のQ60は既に終売になっていて、今は無線と、更なる静音化のために構造が見直されたQ60 MAXが現行モデルになっています。
なお、本家より便利なのは、Win-Macの配列変更のスイッチがあるところで、これが有るだけでも日常的にWindows機と、Macを切り替えながら使っている自分にとっては最高の機能です。 本家のディップスイッチ方式はさすがになーと思っていたので
今のところ、キーキャップと、スイッチを交換していて、この組み合わせの打鍵感が過去最高に気に入っているので、当面はこの組み合わせ使っていくと思います。
Cherry Industrial Keysnovelkeys.com
Kailh Clione Limacina Switch tactileの打鍵感は最高なのですが、周りに人が居るような環境だとちょっと使うのを躊躇するくらいの軽快な打鍵音が響いてしまうので、そんな時は、同じKALIHのMidnight Silent V2というスイッチを使っています。
キーボードと、トラックパットをまとめてデスクマットの上に置きたいので、KEEBMATのKEEBMAT Premium Felt Editionというのを導入しました。
KEEBMAT™ Premium Felt Edition (incl. Free Coaster!)
KEEBMATは、小型キーボードのサイズにぴったり合わせたキーボードマットが有名ですが、フェルトエディションの一番大きなサイズは、完全にデスクマットとして使える大きさで、お勧めです。
ただし、アイロンが無いと綺麗に平らにならないので気をつけてください。
定番中の定番ですが、定期的に書い直していて、通算3本目を買いました。
どんなにPCやスマホ、タブレットが進化しても、ボールペンの書き味からくるフィードバックにはまだ敵わないんですよね。
まだまだ買ったものが有った気もしますが、ついにキーボード沼にハマったな……というのが今年の一番のトピックですね
2023/12/30 追記 はてブでコメントいただいたので追記
WH-1000XM5のマイク WH-1000XM3を買ってしばらくしてからコロナ禍が始まり、オンラインミーティングの環境がイマイチ揃えられなくてしばらく不便な音声環境が続いていた。でもある日「あれ?これ、もしかしてノイズキャンセル用のマイクで通話もできるのか!」と気づいて以来、WH-1000XM3をミーティング用に使うことで劇的に通話環境が改善されたので、さらに音声用マイクとしての改善が反映されているというのも、WH-1000XM5に決めた理由の一つだった。
HHKBライク配列のMacと、Windowsの日本語入力について
Windowsの方でのローマ字入力と、英字入力の切り替えを「CTRL+Space」に設定しておくところがポイントです。これでWindowsとMacで同じキー操作になります。あとは、Spaceキーの横のキーをWindowsモードの時はALTキー、Macモードの時はCommandキー、その更に横をOptキーになるように配列を変更しておけば完璧です。それぞれのOSに適した配置になるので、操作性がキープできます(そもそもWindowsはCTRL、MacはCommandになっているショートカットは慣れましょう、でしかないですが)
2022年版はこちら
『実践プロパティベーステスト』の例題をScalaで解いていくシリーズの第3回目です。
前回は、テストが失敗して、収縮した結果を確認する、という内容でした。
今回は第3章に入ります。
初めてプロパティベーステストを書き始めたとき、サンプルコードだけを見て、「なるほどこう書けばいいのか!」と納得して書き始めたものの、すぐにピタっと手が止まりました。それは、「テスティングフレームワークが提供するAPIは分かった、でもそれを使ってどんなテストを書けば、プロパティベーステストになるのか?」...このとっかかりが分かりませんでした。
色々なテストコードの事例を見ながら、実際に自分で書いてみて少しずつ感覚をつかんでいきましたが、やはり何らかのとっかかりが有ると理解が早く進みます。
第3章「プロパティで考える」では、以下の4つの観点でプロパティベーステストを書くときの観点を紹介しています。
モデル化
テストしたいコードと同じ振る舞いをするコード(たいてい効率が悪い)と、結果を比較する手法です。 ビジネスロジックのような固有の振る舞いをコードに落とすような場合には、モデル化できるものは少ないと思いますが、汎用的なライブラリや、他の言語の実装から移植などでは有効です。
事例テストを汎化する
これが一番分かりやすい取り組み方と言えます。通常のユニットテストを書いてみて、そのパターンを元に抽象化を行い、プロパティベーステストとしてまとめていく手法です。例えばリストの要素がゼロの場合、一つの場合、二つの場合...と増やしていったときに、その長さに依存しないような抽象化ができれば、プロパティベースのテストとして実装できます。
ユニットテストベースのテストを考え、そこから抽象を見出す……という流れが遠回りにも感じられますが、具体的なテストから出発する分、結局これが一番早く、確実な手法と言えます。
不変条件
一つのテストですべてをカバーするのではなく、複数のテストを組み合わせて、そのコードの振る舞いの確からしさを総合的に判断するための手法です。それぞれ分解した観点ごとに、不変条件(必ず満たさなければいけない条件)を特定し、それらがすべてテストをパスすれば、コード全体としての確からしさが確認できた、と言えるところからの発想です。
何をもって不変条件が網羅したか?と考えるのは非常に難しいですが、一つの指標としてテストのカバレッジによる判断は有効であるといえるでしょう。
対称プロパティ
JSONライブラリのような、エンコーダと、デコーダがセットで提供され、変換⇒再変換により元の結果に戻れば、その結果の正当性が確認できる、という手法です。
適用できる場面は限られますが、適用できる場合は確実な方法です。
本の中で紹介されていたbiggest
関数をScalaに移植します。
package Pbt object PbtHelper: def biggest[A](list: List[A])(using Numeric[A]): A = def go[A](l: List[A], m: A)(using Numeric[A]): A = val num = summon[Numeric[A]] (l, m) match case (Nil, i) => i case (h :: t, i) if num.gteq(h, i) => go(t, h) case (_ :: t, i) => go(t, i) go(list.tail, list.head)
再帰とパターンマッチで書き直すと、割とさっぱりと書けます。
また、特定の型に依存したくなかったので、比較関数を提供するNumeric
を継承している型に限定して指定できるようにusing Numeric[A]
の指定を入れています。ネストされた内部関数にまでusing
は効果を及ぼさないので、内部関数の中でも指定しています。
summon
はScala3から導入された関数で、using
の引数に型のみを指定した場合に、具体的なインスタンスを取得します。
この辺りの仕組みは、以下の公式ドキュメントに詳しく書かれています。
次にテストを書いていきます。エンコードと、デコードは、ちょっと面倒だったので、circe
で雑に済ませてしまいました。
import org.scalacheck.Properties import org.scalacheck.Prop.forAll import org.scalacheck.Arbitrary.* import org.scalacheck.Gen.* import Pbt.* import io.circe.syntax.* import io.circe.Json object PbtTest extends Properties("Pbt Test"): property("最大の要素を見つける") = forAll(nonEmptyListOf(arbitrary[Int])): (x: List[Int]) => PbtHelper.biggest(x) == modelBiggest(x) def modelBiggest(list: List[Int]): Int = list.sorted.last property("最後の数を選ぶ") = forAll(listOf(arbitrary[Int]), arbitrary[Int]): (list: List[Int], knownLast: Int) => val knownList = list :+ knownLast knownLast == knownList.last property("ソート済みリストは整列したペアを持つ") = forAll(listOf(arbitrary[Int])): (list: List[Int]) => isOrdered(list.sorted) def isOrdered(list: List[Int]): Boolean = list match case h1 :: h2 :: t => (h1 <= h2) && isOrdered(h2 :: t) case _ => true // 2要素未満のリスト property("ソート済みのリストはサイズを維持する") = forAll(listOf(arbitrary[Int])): (list: List[Int]) => list.length == list.sorted.length property("何も要素が追加されなかった") = forAll(listOf(arbitrary[Int])): (list: List[Int]) => val sorted = list.sorted sorted.forall(x => list.contains(x)) property("何も要素が削除されなかった") = forAll(listOf(arbitrary[Int])): (list: List[Int]) => val sorted = list.sorted list.forall(x => sorted.contains(x)) property("対称的なエンコードとデコード") = forAll: (l: List[Map[String, Int]]) => val encoded = enocde(l) l == decode(encoded) def enocde(o: List[Map[String, Int]]): Json = o.asJson def decode(j: Json): List[Map[String, Int]] = j.as[List[Map[String, Int]]].getOrElse(Nil)
前回に続いて、ScalaCheckによるプロパティベーステストを書いていきます。
当然すべてのテストが一度で成功することは有りません(一発で完璧なコードが書けるなら、そもそもテスト書かなくてよくなってしまいます)。
ScalaCheckでテストが失敗するとどうなるか見てみます。
まずは、第2章の例に倣って、テストが失敗するコードを書きます。
def biggest[A](list: List[A]): A =
list.head
必ず先頭の要素を最大として返却しているので、いかにも失敗しそうです。
対応するテストコードを用意します。標準コレクションのsort
機能を使ってソートした結果の最後の要素を最大として取り出します。
property("最大の要素を見つける2") = forAll(listOf(arbitrary[Int])): (x: List[Int]) => PbtHelper.biggest(x) == modelBiggest(x) def modelBiggest(list: List[Int]): Int = list.sorted.last
実行すると、テストが失敗しました。
sbt:pbt> test failing seed for Pbt Test.最大の要素を見つける is oSzCiQZYscT-yK1oib2eve7Ls7uAmFa3cNYxkn7YJdK= [info] ! Pbt Test.最大の要素を見つける: Falsified after 7 passed tests. [info] > ARG_0: List("0", "1") [info] > ARG_0_ORIGINAL: List("1", "-1", "1773528742")
ARG_0_ORIGINAL: List("1", "-1", "1773528742")
が実際に失敗したテストですが、よりシンプルなARG_0: List("0", "1")
というパターンが出てくることで失敗した理由がより分かりやすくなっています。これが収縮です。
今年読んだ技術書のベスト3を選べと言われたら、間違いなく『実践プロパティベーステスト』を取り上げます。
日本では過去に類似の本も出ていないし、これからもプロパティベーステストだけで1冊の本が出版される可能性も限りなく低いことを考えると、さっさと読んでおいた方がいい1冊と言えます。
記載されているサンプルコードをそのまま写経して動かすだけでも学びはあるけど、やはり何らかの変化が有った方がより学びが深まる。
ちょうどこの本に興味を持つきっかけがScala用のプロパティベーステスティングフレームワークであるScalaCheck
に興味を持ったタイミングだったこともあって、ScalaCheck
ベースでサンプルコードを書き直していきながら、調べたこととかをつらつらと書いていきます。
プロパティベーステストは、テスト対象のコードが備えるべき特性(プロパティ)の定義と、それを検証するために利用するテストデータの生成を分離することで、コードを書いた人が想定しなかったコードの不具合を特定するためのテスト手法です。
しかし、抽象的な思考が求められる手法のため、プロパティベーステスト用のテスティングフレームワークのサンプルコードだけでは、なかなか実践的なテストコードの書き方を習得するまで至るのは難しく、とにかく他人が書いたテストコードを読むか、自分で書いてみて発見していくしかなかったので、このような本の登場で実践的な書き方が早く身に付けられる道筋ができたのは素晴らしいことです。
ではさっそく始めていきます。
まずはScalaのScalaCheckの実行環境を整備します。
ScalaCheckは、各種Scala用のテスティングフレームワークの中から呼び出して使うこともできますが、ここではScalaCheck自体をテスティングフレームワークとして使い、sbt
からtest
コマンドでテストが実行される環境を用意します。
Scalaの新規プロジェクトの作成方法はいくつか有りますが、ここではsbt new
コマンドでGiter8
形式のテンプレートから作成します。
% sbt new scala/scala3.g8 name [Scala 3 Project Template]: pbt Template applied in /path/to/./pbt % cd pbt
テンプレートから作成されたbuild.sbt
にはテスティングフレームワークとしてmunit
が指定されていますが、これをScalaCheck
に置き換えます。
- libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test + libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.17.0" % Test
また、不要なサンプルコードのファイルを削除しておきます。
% rm src/test/scala/MySuite.scala % rm src/main/scala/Main.scala
sbt
は、最新のバージョンが使われるようにリリースされているバージョンを確認して、必要に応じてproject/build.properties
を書き換えてください。
2023年12月27日時点の最新バージョンは、1.9.8です。
まずは、「1.4 プロパティを実行する」の例にならって必ず成功するテストを例に始めていきます。
(なお、以降のコードは全てScala 3.3以降でサポートされたFewer Braces記法で書かれいるため、従来のScalaのコードとはずいぶん見た目が異なっています)。
src/test/scala/PbtTest.scala
import org.scalacheck.Properties import org.scalacheck.Prop.forAll import org.scalacheck.Arbitrary.* object PbtTest extends Properties("Pbt Test"): property("always works") = forAll(arbitrary[AnyVal]): (a: AnyVal) => boolean(a) def boolean(v: AnyVal): Boolean = true
上記のコードをテストとしてsbt
から実行します。
$ sbt ...(省略)... sbt:pbt> test [info] compiling 1 Scala source to /path/to/pbt/target/scala-3.3.1/test-classes ... [info] + Pbt Test.always works: OK, passed 100 tests. [info] Passed: Total 1, Failed 0, Errors 0, Passed 1 [success] Total time: 3 s, completed xx xx, xxxx, xx:xx:xx xx
100回のテストに成功し、Pbt Test
というテストが成功したことが分かります。
見れば分かるレベルの内容ですが一応解説をしておくと…
Properties
を継承し、テストオブジェクトを作成
Properties
への引数がそのままテスト全体の名称になります。
具体的なテスト内容は、property
で定義
慣れないとちょっと引っかかる記法ですが、Mapの更新にも使われるupdate
メソッドへの糖衣構文と同じです。
内部実装としては、property
という変数を経由してPropertySpecifier
というクラスのupdate
メソッド呼び出しに変換されますが、利用者側では気にする必要はありません。(Map以外で出てくると、ちょっとアレっ?と思う、Scalaの独特な記法だと思っています。)
forAll
関数の引数には、ランダムに生成されたテストデータを引数として取り、Boolean型の結果を返すコードブロックを渡します
標準コレクションでもおなじみのforAll
関数は、要素の中に一つでもfalse
となるものがあれば全体をfalse
と判定します。つまり、たくさんのテストデータが自動生成された結果、一つでもテストの結果が失敗すればテスト全体が失敗した、とみなされます
ScalaCheckのプロパティベーステストは、以下の形式で書くことになります。
forAll(ジェネレータ): (コードブロックへの引数) =>
...
...
Booleanを返すコード
最後はBoolean型を返すため、a == b
といった、テストの真偽を判定するコードを書く形式になります。
ヘルパー関数として、boolean
という関数を用意
本書のサンプルに従って、ヘルパー関数を用意しました。引数として渡された変数の値に拠らず、必ずtrue
を返します...結果としてテストは必ず成功します
なお、先ほどのコードでは、本書に出てきたあらゆる型のデータを任意に生成してくれるany()
のような便利ジェネレータがScalaCheckには無かったので、任意のAnyVal
型のデータを生成するようにしていますが、本質的な意味は変わりません。
ジェネレータは省略可
ScalaCheckはジェネレータは省略可となっています。続くコードブロックの引数の型から型推論可能な場合は、自動的に型に合わせたジェネレータが選ばれます。そのため、先ほどのコード例は、以下のように書き換えることができます。
property("always works") = forAll: (a: AnyVal) =>
boolean(a)
デフォルトでは100回のテストが実行され、このコードサンプルでは全てのテストが必ず成功します。
とりあえず、テストが通る環境までは作ることができました。
すっかり見えないところで当たり前のように使っているはずなのに今一つ理解が不完全なまま来てしまったのが「IPv6」。家のインターネット環境を一新したときに色々と調べたはずなのに、すっかり忘れてしまったので『プロフェッショナル IPv6 第2版』の紙版を購入して勉強しなおしています。
470ページに渡って、「そもそもIPアドレスとは?」から始まり、IPv6を学ぶために必要な情報が全部詰まっている、ほんと全部入りです。
個人的には、「ip a
」コマンドを叩くとアドレスっぽいものが複数出てくるけど、これ何?という疑問が解消したのと、DNS周りの仕組みが分かったので、非常に役に立ちました。
最近は、自宅インターネット環境にフレッツを使っていないのでNTTのNGN固有のIPv6事情には影響されることもないのですが、背景が興味深かったですね。
そしてこの書籍の凄いところは、電子書籍版はなんと無料で読めること。
企業スポンサーや、クラウドファンディングにより実現したそうです。
筆者への応援のため、価格付きのページも用意されています。
IPv4を分かっていると、何となく分かった気になってしまうIPv6……本当はしっかり理解しないといけないけど、どこから手をつければいいのか分からない……そんな時に、本書は体系的に理解するための最高の書籍で、かつ無料でも読めてしまうので、読まない理由がないです。年末年始のまとまった時間にぜひ読みましょう。