カンテラの光の下で

dNaga392's memorandom

ドヤ会のススメ( ・´ー・`)

ちょっと誇張タイトルです。

先日会社でドヤ勉強会(以降、「ドヤ会」と呼びます)を開催しました。

それまで不定期ながら会社で勉強会が開催されていたのですが、 しばらく開催されなくなっていたので、じゃあ自分がやるかと企画したのがドヤ会です。

ドヤ会のコンセプト

ドヤ会はドヤるための勉強会です(ここが重要です)。

自分にとって好きなことや調べたことを発表・紹介をしても、 いい評価がつくとは限りません。

だとしても、お前の発表はダメだとだけ言われると、 凹んでモチベが下がり発表しなくなります。

それを乗り越えてこそなどという根性論もありますが、 そういうのはそういうのが好きな人同士でやっててほしいです。

そこで、全体の利益は無視して、各自好きなこと・話したいことをテーマに 自分にとってのスゴイことを発表する会としました(つまりは自由発表ですね)。

ドヤ会のルール

初回ということもあり、今回は技術的な内容としかルールは設けていませんでした。

ただ、理念として次のことをお話ししました。

  • 「勉強会」という名前から受ける発表の敷居の高さを下げたい。
  • 自己評価の低い人にも発表をすることで自信をつけてほしい。
  • 発表をするときはドヤって、発表を聞くときはドヤらせてください。

多くはないものの、「勉強会」で自分が感じた問題点を踏まえた内容になっています。

どこにでも一言言って存在感を出したがる人はいるのですが、 ほとんどの場合は誰の得にもならないので、それを制限したいという意図があります。

アドバイスについては、話し手次第で毒にも薬にもなるため悩んだのですが、 社内開催ということもあり今回は特に制限をかけませんでした。

また、存分にドヤってもらうため、時間に制限はかけませんでした。

ドヤ会アフター

実際に開催して感じたことは次の通りです。

  • 思っていたより発表者が増えた。
  • 普段交流が少ない人の興味や関心を知ることができた。

一番驚いたのは、話したいって人が意外といたってことです。

構想をお話しして賛同してくれた先輩に勇気づけられて企画したものの、 せいぜい4人くらいしか集まらないんじゃないかと思っていました。

それが最終的には発表者5人、聴講のみ3人の計8人となりました。 会社全体で50人程度なので、1/5近くの人に参加いただいたことになります。

本人許可を取ってないので詳細は避けますが、発表は次の内容でした。

  • Docker を用いた現場の開発環境について
  • Markdownによる軽量予定管理ツールを作っていること
  • MP3のタグ情報について
  • React Hooks入門ライブコーディング
  • 時系列データに関するクラスタリング手法の紹介

発表者には他社常駐や元社員の方もいたため、 普段会わない方がどのような視点でどういうことに興味があるかを知れてよかったです。

ひとつだけ、企画側として気になったことは時間のことがありました。

発表が5人ということもあり時間を気にしていなかったのですが、 想定より遅くまで盛り上がってしまったので、キチンとやるなら時間制限を検討するとよいと感じました。

おまけ

似たような企画がないか調べたら出てきました。「そう、その目標を掲げたかったんだ!」という気持ちになったので紹介しておきます。

www.sjc-net.co.jp

まずは、「自信をもって、自らの考えを相手にわかりやすくかつ正確に伝える」ことを目標に掲げました。もう少し具体的に言うと、「プレゼンテーション」と「スモールトーク」の技術の習得と向上です。

【C++】ifstreamで一行戻す

ifstrean には「一行戻すため」の関数は存在しない。しかし、tellg()seekg() を用いることで実現できる。

std::ifstream myReadFile("route.txt");
....
auto oldpos = myReadFile.tellg();  // stores the position
getline(myReadFile, line);
myReadFile.seekg(oldpos);   // get back to the position

Go back one line on a text file C++ - Stack Overflow

参考資料

【地理】ポケモン新作の「ガラル地方」をスコットランド地方とみた

要点

  1. ポケモンの新作の発表があった。舞台は「ガラル地方」。
  2. 「ガラル地方」のモチーフをブリテン島と考える人たちがいた。
  3. 「ガラル地方」のモチーフをスコットランド地方と考え、類似性が挙げてみた。

「ガラル地方」とは

ガラル地方は、昨日のニンテンドーダイレクトで発表された、ポケモンの最新作『ポケットモンスター ソード』『ポケットモンスター シールド』の舞台です。

f:id:dNaga392:20190228225107j:plain
ガラル地方

いまのところ何人かがガラル地方のモチーフをブリテン島とみています。 私が最初に見かけた次の方もその一人です。

スコットランドの田舎町からロンドンを目指すというシナリオは、ストーリー的にもわかりやすく、現在主流の見方となっています。

ただ、この説の場合は地形に違和感が残ります。というのも湿地や平地が多いはずのイングランドに山地が重なってくるのです。

そこで私は「ガラル地方」上部の山地に着目し「スコットランド地方」ではないかと考えました。

ガラル地方とスコットランド地方の類似性

ガラル地方を正位置で見たとき、奥に山地が広がり手前に平地と森が広がっています。 かつ、手前は雲に隠れていて陸続きか海で途切れているかわかりません。

仮に手前の雲に隠れているところが陸続きだった場合、 スコットランドイングランドの一部を含めたブリテン島北部との類似性が見えます。

f:id:dNaga392:20190228233434j:plain
ブリテン島北部とガラル地方

この範囲を「スコットランド地方」として、具体的には次のような類似性があると考えます。

ガラル地方 スコットランド地方
奥の山地の町 インヴァネス(Inverness)・ネス湖(Loch Ness)
奥の山地 ハイランド地方(Highlands)
山地の手前の壁 アントニヌスの長城(Antonine Wall)
中央の上方の町 グラスゴー(Glasgow)
中央の右側の港町 エディンバラEdinburgh
中央の城壁の上の町 ダンフリース(Dumfries)
中央を横切る城壁 ハドリアヌスの長城(Hadrian's Wall)
中央下方の湖 湖水地方(Lake District)
下の島 マン島(Isle of Man)
手前の町 リーズ(Leeds)

f:id:dNaga392:20190301004249p:plain
ブリテン島北部とガラル地方(比較テキスト)

まとめ

こうして図で示すことで、よりスコットランド地方らしく見えてくるのではないでしょうか。 実際のモチーフがどうであったとしても、こうした地図の考察は楽しいものです。

もしガラル地方のモチーフがスコットランドであれば、スコットランドと「古い同盟(Auld Alliance)」の関係にあるフランスをモチーフにしたカロス地方との関係も気になりますね。

なお、ガラル地方のつづりは「Galar」だそうで、北欧神話ドワーフ「フィアラルとガラール(Fjalar and Galar)」と同じつづりです。 こちらの名前に関する考察をしても面白いかもしれませんね。

参考資料

【C++11】スコープ列挙型(Scoped enumerations)

TL;DR

enum classで定義した列挙型は、従来のenumに加えて、「整数型への暗黙の型変換を行わない」「列挙型のスコープを持つ」という機能を持つ。

enum class Color { Red, Green, Blue };

// 単にRedと指定するのではなく、どの列挙型に属するのかを指定する
Color c = Color::Red;

// 明示的な型変換は許可する
int color = static_cast<int>(Color::Red);
//int color = Color::Red; // コンパイルエラー : 暗黙の型変換はできない

Try it

cpp.sh で試してみた。intを基底にした場合でも暗黙の型変換は許されないようだ。

enum class Color : int { Red, Green, Blue };

int main()
{
    Color c = Color::Green;
    // int cc = Color::Blue;  // Error: cannot convert 'Color' to 'int' in initialization
    int cc = static_cast<std::underlying_type<Color>::type>(Color::Blue);
    return 0;
}

Diff

従来の手法との違いとしては、やはり次の2つが大きい。

  1. 「列挙型のスコープを持つ」
  2. 「整数型への暗黙の型変換を行わない」

「列挙型のスコープを持つ」に関してはメリットが大きい。

従来の列挙型で同様のスコープを実装したい場合、名前空間を使用して次のように実装していた。 これと比べるとずいぶんスマートになった。

namespace Color 
{
enum enumColor { Red, Green, Blue };
}  // namespace Color 

一方、「整数型への暗黙の型変換を行わない」については判断が分かれるかと思う。 というのは、整数型への暗黙の型変換を意図的に活用しているケースがあるからだ。

具体的には次のような場合がある。

namespace TableColumn
{
enum enumTableColumn { Id, Name, Address, numColumn };
}  // namespace TableColumn

この列挙型は次の2点で整数型への暗黙の型変換を意図的に活用される

  1. 各要素(Id, Name, Address)の並びに意味があり、列インデックス(int)として活用される。
  2. 末尾の要素(numColumn)が列挙子の数(int)として活用される。

実際にこういう運用は少なくないのでないだろうか。 このように順序に意味がある列挙型を、私は「順序付き列挙型(Enumerations with order)」と呼んでいる(正しい用語があれば教えてください)。

「順序付き列挙型」の場合、スコープ列挙型にしたところで キャストの手間がかかってしまうため、単純には導入できず検討が必要になるだろう。

Column

なお、末尾の要素で列挙子の数を定めることには是非があるようだ。

Ref

【Git】 コマンドを間違えたとき git reflog が便利だった

導入

コミットをしたものの止めたくなったとき、 git reset HEAD^ をすることがあるでしょう。
あの日の私もそんな思いで git reset HEAD^ を叩いていました。

ところが思ったより一回多く git reset HEAD^ を叩いてしまいました。
これでは本来含めたかったコミットを消してしまい、ブランチとも齟齬が発生してしまします。

どうにか元に戻せないかと調べると、ちょうどその方法が見つかりました。
今回の記事はそんなお話です。

要点

気取った導入を書きましたが、要点は次の通りです:

  1. git reflog で戻したい状態を示す SHA(ハッシュ) を確認する。
  2. git reset でその状態に復帰する。

詳しく

やってしまった~ って思ったその時に git reflog を実行します。 すると、次のようにコマンドに対応するログが表示されます(画像はぼかしています):

f:id:dNaga392:20181116132003p:plain

今回は最後のコマンドを打ち消したいので、上から2番目の ff8ab38 までリセットします。

git reset ff8ab38

これで消してしまったコミットが復活しました。 よかったよかった。

参考資料

【Qt】Qt 5.11.2 を MinGW 64 bit 向けにビルドした

Qt は Qt Online Installer により複数の環境に対応したライブラリがインストールできます。しかし、Windows 向け g++ が利用できる MinGW の 64bit 環境に対応するものはなく、該当の環境での開発を望む場合、開発者自身の手でQtのソースからビルドする必要があります(少なくとも本記事の執筆時点には存在しませんでした)。

本記事では、前述のようなケースにある開発者を対象に、 Qt5.11.2 を MinGW 7.3.0 64 bit 対応の開発環境の構築手順を示します。

開発環境構築

構築手順は次のとおりです:

  1. Qt のソースを準備する
  2. ビルドのためのツールをインストールする
  3. Qt をビルドする
  4. Qt 開発環境を整える

1. Qt のソースを準備する

Qt Online Installer を利用して Qt をインストールします。 Qt Online Installer は次のダウンロードページから取得できます:

今回は Open Source 版を選択して、 Online Installer をダウンロードします。

参考:Online Installer のバージョンによる差は小さいと思いますが、本記事では qt-unified-windows-x86-3.0.5-online.exe を使用しています。

Qt Online Installer を実行します。 本記事では、次のようにインストールしました。

  • Open Source 版を利用するため、 Qt Account は Skip しました。
  • インストール先フォルダは、既定の C:\Qt としました。
  • インストール項目の選択は次のとおりです:
    • Qt
      • Qt 5.11.2
        • [x] MinGW 5.3.0 32 bit
        • [x] Sources
      • Tools
        • Qt Creater 4.7.1
        • [x] MinGW 5.3.0 32 bit
        • [x] MinGW 7.3.0 64 bit
  • ライセンス条項は同意しました。
  • スタートメニューは、既定の Qt としました。

参考:本記事では比較のため、 Qt/MinGW 5.3.0 32 bit および Tools/MinGW 5.3.0 32 bit を選択しています。必要がなければ、これらは未選択でも影響はありません。

2. ビルドのためのツールをインストールする

Qt のソースを準備できたら、ビルドのためのツールをインストールします。 ビルドの必要要件は次のとおりです:

ツール バージョン
MinGW gcc 4.9 以降
Perl 5.12 以降
Python 2.7 以降
Ruby 1.9.3 以降

参考:ビルドの必要要件は Qt/5.11.2/Src/README に記載があります。

MinGW は Online Installer によりインストールされているので、 Perl, Python, Ruby のインストール方法を示します。

Perl をインストールする

Perl は次のダウンロードページからインストーラーが取得できます:

取得したインストーラーを実行してインストールします。

参考: ダウンロードページは Qt/5.11.2/Src/README に記載があったものです。 本記事作成時は、ダウンロードページに次の2バージョンありました。

  • 5.24.3.2404
  • 5.26.1.2601

本記事では最新の 5.26.1 をインストールしました。

Python をインストールする

Python は次のダウンロードページから取得できます:

取得したインストーラーを実行してインストールします。

参考: ダウンロードページは Qt/5.11.2/Src/README に記載があったものです。

本記事作成時、ダウンロードページには次の3バージョンありました。

  • 3.5.4.3504
  • 2.7.14.2717
  • 3.6.0.3600

本記事では 2.7.4 をインストールしました。

注意: ビルドでは Python 2.x 系が要求されます。

Ruby をインストールする

Ruby は次のダウンロードページからインストーラーが取得できます:

取得したインストーラーを実行してインストールします。

参考: ダウンロードページは Qt/5.11.2/Src/README に記載があったものです。 本記事では 2.4.4-2(x64) without devkit をインストールしました。

3. Qt をビルドする

いよいよ Qt5.11.2 を MinGW 7.3.0 64 bit 向けにビルドします。

管理者権限でコマンドプロンプトを立ち上げ、Qt 5.11.2 のフォルダに移動します。

>cd C:\Qt\5.11.2

続けて、次の2つのフォルダを作成します:

  • インストール用のフォルダ mingw73_64
  • ビルド用のフォルダ mingw73_64_build
>mkdir mingw73_64
>mkdir mingw73_64_build

作成したビルド用のフォルダ mingw73_64_build に移動して、ビルド用のツールのPATHを通します。

>cd mingw73_64_build
>set PATH=C:\Qt\Tools\mingw730_64\bin;C:\Qt\Tools\QtCreator\bin;%PATH%

上のコマンドは、各ビルド用ツール(PerlPythonRuby)のインストーラーでPATHを通してある状態のものです。 PATHを通さなかった場合は次のコマンドで PATH を通します:

>set PATH=C:\Qt\Tools\mingw730_64\bin;C:\Qt\Tools\QtCreator\bin;C:\Ruby24-x64\bin;C:\Python27\;C:\Python27\Scripts\;C:\Perl64\site\bin;C:\Perl64\bin;%PATH%

echo %PATH% を実行し、PATHが通っていることを確認します。

>echo %PATH%
C:\Qt\Tools\mingw730_64\bin;C:\Qt\Tools\QtCreator\bin;C:\Python27\;C:\Python27\Scripts\;C:\Perl64\site\bin;C:\Perl64\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Ruby24-x64\bin;C:\Users\dev\AppData\Local\Microsoft\WindowsApps

問題がなければ、configure を実行し、ビルド設定をします(時間がかかることがあります)。

>..\Src\configure -developer-build -opensource -confirm-license -opengl desktop -nomake examples -nomake tests -prefix C:\Qt\5.11.2\mingw73_64

コマンドの意味は次のとおりです。

コマンドとオプション 説明 コメント
..\Src\configure Src ディレクトリにある configure 本体。
-developer-build Qtをコンパイルしてリンクする。
-opensource OpenSource版でビルドする。
-confirm-license ライセンス条項に同意する(確認画面を表示しない)。
-opengl desktop デスクトップ OpenGL を使用する。 未指定だと QtGui でエラーが発生し、ビルド全体が失敗するため
-nomake examples 各モジュールの examples を作成しない。 ビルド時間短縮のため
-nomake tests 各モジュールの tests を作成しない。 qtwebglplugin のテストパートでエラーが発生し、ビルド全体が失敗するため
-prefix C:\Qt\5.11.2\mingw73_64 C:\Qt\5.11.2\mingw73_64 をインストール先とする。

その他のオプションは configure -h で確認できます。

mingw32-make を実行し、ビルドします(とても時間がかかることがあります)。

>mingw32-make

mingw32-make install を実行し、インストールします(時間がかかることがあります)。

>mingw32-make install

C:\Qt\5.11.2\mingw73_64 にインストールされていることを確認します。

以上でビルド&インストールが終了です。

4. Qt 開発環境を整える

Qt開発を始めるには、次の2つのPATHを通す必要があります。

  • C:\Qt\5.11.2\mingw73_64\bin
  • C:\Qt\Tools\mingw730_64\bin

インストーラーからインストールした場合はスタートメニューが作成されますが、 ビルド&インストールの場合は作成されません。

そのため、 MinGW 5.3.0 32 bit 版を参考に同様の開発用ショートカットを作成します。

MinGW 5.3.0 32 bit 版ショートカットは、リンク先が次のようになっています:

C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\5.11.2\mingw53_32\bin\qtenv2.bat

qtenv2.bat は 64 bit 版に存在しないため、これを C:\Qt\5.11.2\mingw73_64\bin に作成します。

作成する qtenv2.bat の内容は次のとおりです:

@echo off
echo Setting up environment for Qt usage...
set PATH=C:\Qt\5.11.2\mingw73_64\bin;C:\Qt\Tools\mingw730_64\bin;%PATH%
cd /D C:\Qt\5.11.2\mingw73_64

参考: 本質的な部分は3行目のみです。3行目以外はインストール版と同様の挙動にするためのコマンドです。

スタートメニューに次のリンク先でショートカットを作成します:

C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\5.11.2\mingw73_64\bin\qtenv2.bat

以上で、開発用ショートカットの作成は終了です。

【Hyper-V】VMのディスク領域を増やす

Hyper-VVMのディスク領域を拡張しました。

要点

  1. 「ディスクの編集」で仮想ハードディスクを拡張します。
  2. VMで「ボリュームの拡張」をします。
  3. 回復パーティションがある場合、ツール「AOMEI Partition Assistant」を使います。

内容

VMでライブラリをビルドしていると、ディスク領域不足によるエラー(No space left on device)が発生しました。 確認すると、既定のディスク領域(50GB)を使い切り、空き容量がゼロになっています。

これを解決するため、VMのディスク領域を拡張する方法を調べると、次の記事が見つかりました:

この記事によると、次の2つの手順で実現できるようです:

  1. Hyper-V マネージャーで仮想ハードディスクを拡張
  2. VMで「ボリュームの拡張」

1. Hyper-V マネージャーで仮想ハードディスクを拡張

仮想ハードディスクの拡張では、関連付けられているチェックポイントがあると、 拡張後にはうまく関連付けられないという警告が出ます。

該当のVMは初期に作成したチェックポイントがあったため、 このチェックポイントを適用したのち、全てのチェックポイントを削除して拡張しました。

2. VMで「ボリュームの拡張」

続けて、VMを起動してボリュームの拡張を実行しようとすると、 右クリックメニューから「ボリュームの拡張」が選べませんでした。

これを調べると次の記事に説明がありました:

どうやら拡張するには連続した領域が必要で、今回は「回復パーティション」が未割当て領域との間に挟まっているためできなかったようです。

とはいえ、回復パーティションを削除するのも怖いので、次の記事を参考にしました。

AOMEI Partition Assistant というツールをインストールし、 これを実行することでパーティションの移動および拡張ができました。

余談ですが、とても使いやすかったのでパーティション管理をされる方におすすめです。