サポンテ 勉強ノート

サポンテの勉強ノート・読書メモなどを晒します。

2018年に読んでよかった本

はじめに

ほんとうは年末にこのような記事を書くことができていれば良かったのですが、筆が遅い上に自宅にネットがないので年をまたいでしまいました。

2018年中に読んだ本は126冊になりました。100冊は読みたいと思っていたのでこの結果には満足しています。2019年もこのペースを続けることができればと思います。

読んだ本はタイトルと最大三つの星でレーティングを行っていました。その中で三ツ星を付けた本を紹介したいと思います。

続きを読む

「PC を再起動させる」は間違いか

はじめに

髪を切る際の待合席で読んだ週刊誌に「『PC を再起動させる』(中略)といった間違った日本語が...」という記述がありました。それについて書きたいと思います。

記事の内容は PC に関連する記事でもなければ日本語の乱れについて書かれたものでもありません。すでに記憶がまったく定かではありませんが、上記の部分だけが心に残っています。

何が間違っているか

さてこの週刊誌記事には「なぜそれが間違いなのか」が書かれていませんでした。記事の主旨ではないので省略されたのでしょう。なので間違いだとする理由については推測するしかありません。

続きを読む

Windows タスクスケジューラーで PostgreSQL の vacuum や pg_dumpall を行う際の注意事項

はじめに

ときどき実施が必要な PostgreSQL の vacuum。定期的にタスクスケジューラで以下のようなバッチを起動するよう設定していましたが、動作していないことがわかりました。

REM バッチファイル
vacuumdb -U foo -a -w > "vacuum.log"

バックアップのために pg_dumpall もタスクスケジューラから定期的に実行していますが、こちらも同様に失敗しています。

続きを読む

ハードタブ VS ソフトタブ

長く続く争い

プログラムを記述する際のインデントにタブ文字を使うか、複数のスペースを使うか。ここには大きく長く続く宗教論争があります。

「宗教論争」という言葉には「一部のコアな人たちだけのもので、一般人には縁遠く無関係な論争」という皮肉めいた意味がこめられています。しかしプログラマたるもの、考えなしににコーディングするわけにはいきません。理由があるならちゃんと考えないと。

私はスペースを用いる派です。

ちょっと気になることがあったので今回は調べてみました。

プログラミングのコードを書く時のタブvsスペース戦争がついに決着 | ギズモード・ジャパン

派閥の大きさに関して言えば、ほぼ決着していると見て良さそうです。私はあまり関心を持ってこなかったので両者の主張をもう一度じっくりと調べてみましょう。

続きを読む

Developer's Code 本物のプログラマがしていること(アスキー書籍)

この本は、最後にこう結ばれています。

誰かが僕に「仕事は何なの?」って聞いてきたら、僕はこの本を渡してやるんだ。これはそのための本なんだ。

これは実際に作者のほんとうの気持ちかもしれません。でもおそらくは多くの開発者の心を代弁したものであると感じました。

この本は、エンジニアリングに関する本ですが、この本を読んで何かを身につけるというものではありません。エンジニアリングに関するエッセイがつまった本です。

技術書じゃないのか。読みたくなくなりましたか?自分の本棚に置いておくような本ではないと感じますか?サポンテはそうは思いませんでした。何となく折りに触れ読み返してみたい、そんな本でした。

本には、「あ、自分のことが書いてある」と思えるものがあります。新しい知識を得る。新しい世界を見る。そのために読む本というのも確かにあります。そのような読書をしていても、まれに、読んでいるこちら側の心のうちを、なんとなくモヤモヤとはっきりと言葉にできなかった気持ちを、明確にしてくれる本に出会うことがあります。

本に出会うまではっきりとしなかった、むしろ意識すらしていなかった「モヤモヤ」は、経験の中で気付かないうちに刺さった棘のようなものだったり、時代の雰囲気だったりというものです。こうした「モヤモヤ」を明確にすることで、人は前へ進んだり、深い知見を得たり、人に共感できる部分が増えたり、その深みを増すことができます。

「モヤモヤ」をそのままに日々を過ごすことはできるかもしれませんが、勇気を持って前へ進むにはモヤモヤをひとつひとつ丁寧にはっきりさせる作業が書かせないと思うのです。

この本はまさにそんな本でした。この本はエンジニアとして生きる私に、いくつかの示唆を与えてくれました。時を経てまた別の機会に読めば、また別の示唆を与えてくれるのではないかと思います。

またこの本には、ひとつひとつの話題に関連していくつかの参考書籍が紹介されていましたが、それらの本もかなり読みたくなりました。そうした指針になったという点でもこの本を読んでよかったと思います。

本を読みながらいくつかメモをとりましたが、ひとつのセクションのタイトルでもある「アサイチで自分の仕事をテストしよう」は明日からでも取り入れてみようと思いました。

LINQ テクノロジ入門

はじめに

前回の記事を書いた後で LINQ についてちゃんと身につけたかったため、この本を読んでみました。

LINQ は様々なネット情報だけを見てなんとなく使っていて、モヤモヤ部分があったのでスッキリしました。

LINQ とは

漠然と「集合1を加工する機能」だと思っていましたが、ネット情報にはいずれもそのようなことは書いておらず、探せば探すほどモヤモヤが募っていました。

この本にはそれがズバリと書かれていて、ああやっぱりその理解で良いのかと、やっと腑に落ちた次第です。

本の紹介

全部で 250 ページほどと短めです。手を動かしながら進める部分があるため、そこは少し時間がかかりますが、3日もあれば終えることはできるでしょう。後述の読む部分だけなら1日で済みます。それだけでももちろん強力です。

全体的に LINQ to SQL の情報が多く、手を動かしながら進める部分は LINQ to SQL の操作が大半です。LINQ to SQLSQL とは、ここでは Microsoft SQL Server のことを指していて、残念ながら一般的な意味での RDBMS ではありません。LINQ to SQLSQL Server に格納されているデータに LINQ でアクセスするためのプロバイダ(ドライバ)です。私は現在、業務に SQL Server をつかっていないため、この部分については参考にならず興味も持てなかったので読み飛ばしました。反対に、SQL Server を業務で使用しているかたには実りがあるでしょう。

LINQ はもちろん SQL Server の世界に留まらない技術なので、読んだ価値は十分にありました。

この本の読みかた

一章から三章までと「8.3 ラムダ式の展開」を熟読し、五章から七章は手を動かしながら進め__そして実開発ではリファレンスのように使い__残りの部分に目を通す。そのような読み方になるかと思います。

私は前述の通り、五章から七章は業務に関係ないので読み飛ばしさせていただきました。

この本での呼称

前回の記事で書いた LINQ の二つの構文「クエリ構文」と「メソッド構文」は、この本ではそれぞれ「埋め込みクエリ方式」「拡張メソッド方式」と呼称されていました。まあ当たらずしも遠からずだし、なんだか長いので特に訂正しないでおきます。

LINQ の導入に当たって追加された機能

一章から三章までは概念的な読み物になっていますが、サンプルコードが多用されていてとてもスムーズに頭に入ってきます。

LINQ の導入にあたって C#VB それぞれに導入された新しい概念について LINQ と関連しながら説明がありました。いずれも柔軟で強力な機能ですが、落とし穴を作りそうな機能でもあるので LINQ の文脈以外で濫用しないようにとの戒められています。この一文はぜひこの本を実際に手に取って読んでほしいです。

匿名データ型

Dim a = New With {.Name = "Nobu", .Age = 33}

VB.NET で上記のようにとすると変数 aコンパイラが自動的に匿名クラスのオブジェクト型として扱ってくれます。なんとエディタのコード補完も効きます。C# では var キーワードで作成する変数です。

LINQ とともに導入されたもので、かつての Variant 型のようなものではありません。

自動プロパティ

public class Employee
{
    public string Name {get; set;}
    public int    Age {get; set;}
}

知ってると思いますが C# で上記のように記述するとコンパイラが自動的に private なフィールドを作成してくれます。

この機能は VB.NET にはありません。

オブジェクト初期化子

オブジェクト初期化子は、コンストラクタを持っていないクラスでも同時に初期化ができる記述法で、VB.NET では以下のように記述します。

Dim a As New Employee With {.Name = "Nobu", .Age = 33}

拡張メソッド

Dim a As Integer() = {1, 2, 3}
Dim b As Integer = a.Sum()          ' 結果、変数 b は 6 になる。

上のコードの二行目にある Sum() は、これまでの感覚だと Integer() のメソッドのように思えますが、LINQ ライブラリによって提供されている「拡張メソッド」だとのことです。

外部からメソッドを追加するという、オブジェクト指向の理念に反したものなので LINQ 以外で濫用しない旨、この本では戒めています。

パイプライン処理(RDBMS との違い)

RDBMS の SELECT は、データの集合から別のデータの集合へと加工します。それに対して LINQ は、データの集合をパイプライン処理で加工するものです。そうして LINQ で加工した結果は、やっぱりデータの集合である場合もありますが、オブジェクトだったりすることもあります。

上記の Sum() のコード例では整数の集合(配列)から整数へと加工しています。

パイプライン処理というよりメソッドチェーンと言った方が理解しやすいかたもいるかもしれません。

RDBMS では最初に抽出後の列を SELECT 句の下に書きますが、LINQ はパイプライン処理なので、最初に「どのデータ集合を加工するのか」を指定しなければなりません。これは RDBMS では FROM 句で指定するものです。そこから「データ集合から抽出する内容は何か」を指定する WHERE が続きます。LINQ クエリで SQL の SELECT 文とは Select, From Where の登場する順序が異なるのは、このパイプライン処理に由来するものであるためということがよくわかります。

LINQ の二つの記述法のうち、パイプライン処理(メソッドチェーン)であることが明確にわかる「拡張メソッド方式」の採用を、この本でも勧めていました。なじみのある SQL からへだたりがある理解し難い LINQ の記法も、こうした説明があればとても理解しやすいものだと感じました。

ソートの方法・JOIN の方法

ソートや結合など、気がかりだった機能とその記法についても知ることができました。ハンズオンはしていませんが五章から七章にかけて、LINQ のさまざまな機能についての詳説があり、とても役に立ちました。

説明は割愛します。役に立つ本なので手元に置いても良いでしょう。

おわりに

「入門」とありますが LINQ 以外については「.NET Framework の他の機能についてはもう知っているよね」というスタンスで書かれた本です。Amazon にもそのような旨のレビューがありました。全くの初学者が手に取っても、確かにつらいでしょう。しかし業務である程度(数年?) .NETRDBMS に触れたことがあれば読み進めることができると思います。

本記事も含まれると思いますが、ネット情報では、やはり圧倒的に情報が不足しています。ぜひ実際にこの本を手に取って読んでみてください。


  1. .NET の世界では「コレクション」と言った方が解りやすいかもしれません。

SQL - LINQ コード対比

はじめに

統合言語クエリ - Wikipedia

.NET 3.5 で導入された新しい(当時)構文ですが、ほとんど使ったことがありませんでした。

理由としては以下のような感じになります。

使いどころが無い。

そもそも使いたいと強く感じる場面がありませんでした(少なくとも今までは)。入門記事を読んでみても、その魅力をずいぶん強調してはいるものの、適用シーンが思い浮かびません。

ネットのサンプルが C# ばかり

現在の職場では VB.NET 主流です。同じ .NET なので C# のコード査読も基本的には苦にならないはずなのですが、しかし LINQ は新しい(当時)概念であり、構文もこれまでと大きく異なる(ように見える)ため、同じようには読めません。

ネット上のサンプルに添えられた説明だけでは不足していてよくわからず、逆に詳細なものは理論が先行しすぎていて、実際の使い方がよくわからないという状況でした。

SQL 憎しの説明が多い

どうも「SQL を使わなくてもいい」とか「なじみの無い SQL に似た構文もあるけど、そっちは使わなくても書ける」といった説明が多く見受けられました。

私としては SQL の方がずっとなじみがあるものなので、そうした説明はむしろバリアになります。「SQL ではこう書くところ、LINQ ではこう書く」という、私にとって解りやすい説明がなかったのです。

また後日感じたことですが、C# では SQL に似たクエリ構文よりも、メソッドチェーンのように書ける構文の方がすっきりとしていて好まれるのに対して、VB ではクエリ構文の方がすっきりしています。この点では時代を経るごとに両者の文化の溝が深まっていきそうな感じがします。

使いたいところ

自分の思いつく使いどころは「SQL で採ってきたデータを、いろいろ編集してから集計したりソートしたりしたい」というものでした。既に SQL の世界を離れ .NET の世界にあるデータテーブル(System.Data.DataTable)に対して SQL を発行するような気楽なイメージで使いたいのです

複雑なサブシステムが多く、あちこちからデータを取得し、最終的に集計をしたい場合、SQL だけでは望むものが作れません。

また経験上、サブクエリを駆使してデータベースへの問い合わせ回数を減らすよりも、取得したいデータを VB.NET の世界に持ってきてからプログラムで操作をした方がパフォーマンスが出る場面も多かったので、そのような場面でも LINQ が威力を発揮すると考えました。

コード対比サンプル

ではその「SQL ではこう書くところ、LINQ ではこう書く」の対比サンプルを掲載しておきます。

ユースケースとしては、以下の SQL で行うような集計を、データテーブルに対して行うことを想定します。

SELECT
      theID         AS product_code
    , SUM(price)    AS summary_price
FROM theTable
WHERE 1=1
    AND discontinue = 0
    AND disabled_date IS NULL
GROUP BY
    theID
ORDER BY
    theID

続いてデータテーブルから同様に集計データを抽出する LINQ サンプルです。データテーブル「 dt 」には SELECT theID, price FROM theTable の結果のようなものが入っていると想定します。

Imports System.Data

' 中略

Dim dt as DataTable

' 中略

Dim olinq As Object

olinq = From dr As DataRow In dt
        Where 1 = 1 _
            AND dr("discontinue") = 0
            AND dr("disabled_date") Is DBNull.Value
        Order By dr("theID") Ascending
        Group By
            product_code = dr("theID")
        Into
            summary_price = Sum(CInt(dr("price")))
        Select New With {
            .ProductCode = product_code
            .SummaryPrice = summary_price
        }

For Each row As Object In olinq
    System.Diagnostics.Debug.Print(row.ProductCode & " " & row.summary_price)
Next

最後の Select 句の中で無名オブジェクトに初期化していますが、特定のクラスにも出来ます。

Class ProductObj
    Public ProductCode As String
    Public SummaryPrice As Integer
End Class

' 中略

olinq = ... ' 中略
        ' ... 略
        Select New ProductObj With {
            .ProductCode = product_code
            .SummaryPrice = summary_price
        }

For Each row As ProductObj In olinq
    System.Diagnostics.Debug.Print(row.ProductCode & " " & row.summary_price)
Next

免責

サンプルは、説明のために要点以外は省略しています。そのままでは動作しません。

終わりに

LINQ は今までと勝手が違うので、まずはなじみのある書き方で挙動を確認してから、理論的なものを追いかけていけば取っ付きやすいかなと思います。

やっと LINQ のスタート地点に立てた感じです。