やる気がストロングZERO

やる気のストロングスタイル

Git GUIクライアントツールからの脱却検討

git操作自体はgit cuiコマンドで行っているが、差分やtreeを見るためにSource Treeを使っている。
いちいちwindowを切り替えるのもめんどくさくなってきたので、CUI環境で完結出来るならそうしたいと思い検討中。

tigを使うとかなりの部分がGUIクライアントのノリで作業できる。

現在GUIで行っている作業をtigやコマンドでどのように対応するかを検討する。

前準備

brewとかaptとかでtigをインストールする。

tigのmain viewにコミットIDとauthorが表示されていると便利なので設定する
参考) やけに丁寧なtigの設定ガイド(表示制御編) - Qiita

~/.tigrc

# main viewの左端にコミットIDを表示する
set main-view = id date author commit-title:graph=yes,refs=yes
# デフォルト
# set main-view = date author commit-title:graph=yes,refs=yes

コミットTreeを見てブランチの位置関係の確認など

普通にtigコマンドを打てばOK

変更完了時、差分を確認して適宜stagingへaddしてコミット

tigで出来る。
tigのmain viewで[sキー]を押すと表示されるviewにて、uキーでステージングへ。
ハンクごとにaddも可能
[1キー]で1行ごとのaddも可能

[Cキー]でcommitを打てる

問題があるコードがあった場合に、どこでその変更が入ったのか?どういう理由で入ったのかを確認する

tig [ファイルパス]

でそのファイルの変更履歴だけを辿れる。

問題の変更が入ったcommitを見つけて変更意図を読む。
コミットIDがわかるので、一緒に変更された他ファイルの内容も見たければtigコマンドを打ち直して、
/[コミットID]
で検索してそのコミットを確認する。

特定のコミットとの差分を比較したい場合

比較元のブランチやコミットにチェックアウトして、

git diff [比較先コミットID] 

で全部の変更の差分確認できる。

git diff [比較先コミットID] --name-only

でファイル名だけ確認できる。

上記コマンドで怪しいファイルを見つけたら、

git diff [比較先コミットID] ファイル名 

でそのファイルだけ差分確認できる。

指定した複数のブランチのみのtree表示を見たい

branch1とbranch2のみのtree表示が見たい場合がある。(全部のブランチが表示されると見づらいため)

tig branch1 branch2

で確認できる。

【C#】virtual, override, new

下記のようなコードを書きたいときがある。(staffに複数形はないらしいがとりあえず無視)

Staff[] staffs = new Staff[2];
staffs[0] = new Alice();
staffs[1] = new Bob();
     
foreach(var staff in staffs){
     staff.who_am_i();
}

who_am_i()は自分の名前を表示する関数だとすると、 下記のような結果を期待する。

I'm Alice
I'm Bob

期待通りの動作をさせるには、正しくvirtualとoverrideを記述する必要がある。

public class Staff{
    public virtual void who_am_i(){
        System.Console.WriteLine("I'm staff");
    }
}
    
public class Alice : Staff{
    public override void who_am_i(){
        System.Console.WriteLine("I'm alice");
    }
}
    
public class Bob : Staff{
    public override void who_am_i(){
        System.Console.WriteLine("I'm bob");
    }
}

virtual, overrideを書かなかった場合、ビルド時に警告が出て、結果は下記のようになる。

I'm staff
I'm staff

意図的に上記のような結果にしたい場合はnewを使う

public class Staff{
    public virtual void who_am_i(){
        System.Console.WriteLine("I'm staff");
    }
}
    
public class Alice : Staff{
    public new void who_am_i(){
        System.Console.WriteLine("I'm alice");
    }
}
    
public class Bob : Staff{
    public new void who_am_i(){
        System.Console.WriteLine("I'm bob");
    }
}

どういうことか?

オーバーライドとは、基底クラスのメソッドを再定義するという事。
だから正しくオーバーライドされている場合、基底クラスの型(Staff型)でメソッドを読んだとき、再定義された処理が実行される。

virtualとoverrideを記載しないとメソッドがオーバーライドされない。

オーバーライドされない場合どういう状態かというと、
基底クラスとは別に派生クラス側で新しく同名のメソッドが定義された状態になる。
同名なので派生クラス側のメソッドが基底クラス側のメソッドを隠す形になる。

だから派生クラスの型(AliceとかBobとか)でメソッドを呼んだときは、派生クラスに定義された同名メソッドの処理が実行されるし、基底クラスの型でメソッドを呼んだときには、規定クラスに定義されている処理が走る。

意図的にオーバーライドをしない状態でメソッド定義したい場合にoverrideキーワードの代わりにnewキーワードを使う。

【WPF】高DPIディスプレイの場合、Screenオブジェクトから取得するサイズはDPI仮想化の比率で計算し直す必要がある

高DPIディスプレイのノートと普通のディスプレイでデュアルディスプレイを設定しているような場合、wpfアプリでscreenのサイズが直感どおりに使えなかったのでメモ

環境例

例えば上記の高DPIディスプレイノートをprimalyディスプレイとして、普通のディスプレイをその右側に配置する。
左側:ノートのディスプレイサイズは横幅1920 縦幅1080(ディスプレイ1)
右側:据え置きディスプレイが横幅2880 縦幅1800(ディスプレイ2)

したいこと

あるwindowを「ディスプレイ2」の左端ピッタリに表示させたい。
方法としては、「ディスプレイ2」の左端の位置を取得し、window.Leftへセットすれば出来ると思ったが、

window.Left = System.Windows.Forms.Screen.AllScreens[1].WorkingArea.Left

上記環境の場合は「ディスプレイ2」の左橋から右へだいぶズレたところに表示されてしまう。

対策

正しくセットするには、DPI仮想化の比率を取得し、計算してやる必要がある。

double dpi仮想化比率 =  PresentationSource.FromVisual(window).CompositionTarget.TransformFromDevice.M11;// DPI仮想化の比率を取得。参考にした)http://james-ramsden.com/c-get-dpi-screen/
window.Left = System.Windows.Forms.Screen.AllScreens[1].WorkingArea.Left * dpi仮想化比率

これで、意図通りに表示できた。

Ubuntuにてmacの英数・かなキーで日本語入力切り替えするための設定方法

macキーボードを認識させる

デフォルトでは英数・かなキーおしても認識していなかったので下記設定を行った。

参考)
https://qiita.com/koreyou/items/341e1fac95c72d9743ad

sudo dpkg-reconfigure keyboard-configuration

を実行して、下記を選択

  • Apple アルミニウムキーボード (JIS)
  • Japanese
  • Japanese - Japanese (Macintosh)
  • No toggling
  • No temporaly switch
  • The default for the keyboard

英数・かなキーでIME切り替えできるようにする

  • ubuntu画面の右上の入力切替で「日本語(Mozc)」を選択する。(なければ追加する。)
  • 同じく画面右上の入力切り替えドロップダウンメニューの中から「ツール」->「プロパティ」を選ぶ
  • 「キー設定の選択」横の「編集」ボタンを押す。
  • 「コマンド」欄が「IMEを無効化」となっているもの全ての「入力キー」をダブルクリックし、「英数」キーを押して更新登録する。
  • 同じく、「コマンド」欄が「IMEを有効化」となっているもの全ての「入力キー」をダブルクリックし、「かな」キーを押して更新登録する。
  • IME無効化」以外で「入力キー」が「Hiragana」になっているエントリーを全て削除する
  • IME有効化」以外で「入力キー」が「Eisu」になっているエントリーを全て削除する

個人開発環境をUbuntuにすることを検討・検証中

現在個人開発ではmacbookpro 13インチ 2014を使っている。
なんとなく次のマシンを買うことを考えているが、macではないという選択肢もありかとUbuntuを検討している。

なぜか

macappleに依存しているのが嫌になってきた。
実際macはよくできていると思うが、それに依存して不満点(touch barのやつしか選べなかったり、高かったり)を我慢せねばならないことに疑問を持つようになった。
Windowsで開発」という選択肢はまぁ今の所ないので、一度Ubuntuを体験してみて、乗り換えられそうならそちらに移行してみようかと思い検証してみることにした。

macbookproにデュアルブートUbuntuを入れた

ubuntuのインストール

環境設定

普段遣いするには色々設定にもう少し時間がかかりそう。

目指している環境

ある程度使って開発や普段の作業などが問題なく出来るようになったらthinkpadあたりを買ってUbuntuをインストールして使っていこうと思っている。

初期インストールされているwindowsは一応残しておいて(ハードを制御する独自ソフトなどが入っていたりするっぽいので)、Ubuntuデュアルブートで入れる。
エクセルなど、どうしてもUbuntu環境で使えないものを使うためにUbuntuの仮想環境にWindows(別途購入ライセンス)を入れる。ディレクトリを同期させて、ファイル類はubuntu上で管理する。

【PostgreSQL】 online alter tableを考える

Django migrationをオンラインで行えるのかどうか考えていた。

オンラインで行えるのかどうかはDjangoのmigrationコマンドの問題ではなく、使っているDB(今回の場合だとPostgreSQL)がどのようにロックを行うのかによるということがわかった。

では具体的にどうすれば良いのかを調べてみたのでメモ。(未検証なので注意。)

参考)
PostgreSQLで安全にテーブル定義を変更する - LCL Engineers' Blog

どうなるとダウンタイムが発生してしまう?

ALTER TABLEを実行した対象テーブルが排他ロック(参照も更新もできない)を取って、かつ完了までに長時間かかってしまう場合に、そのテーブルを参照・更新するリクエストが返らなくなってしまう。

PostgreSQLの場合、
カラム追加(Default制約なし)やカラム削除などは一瞬で終わるらしい。
一瞬で完了するなら排他ロックをとっても特に問題ない。(デッドロックには注意)

問題は、どうしても時間がかかってしまう変更(not null追加など)

どうすればいいか?

mysqlならオンラインでAlterできる仕組みが5.6以降あるらしい。

仕組みとしては、

  • 内部で別途、変更後構造のテーブルを構築
  • 変更前テーブルから変更後テーブルへデータをコピー。トリガーなどを使って変更前テーブルへの更新は変更後テーブルへも適用されるようになっており、データが常に同期された状態になる。
  • データ同期が完了した時点でテーブルを入れ替える

PostgreSQLにはこの仕組はない。
独自に同じことをすればよさそう?
(※pg_repackをつかえば自動で行えるかも?)

  • 変更後構造のテーブルを新規追加
  • データコピーとトリガーを使って変更前テーブルと変更後テーブルのデータ内容を同期
  • 同期が完了したタイミングでテーブルを入れ替え。

git submodule覚書

参考)
Git - サブモジュール

gitリポジトリをネストしたい場合がある。

プログラム作成中に汎用的なclassを作ったとき、githubに公開したいけど、メインのコードは公開したくない時。
もしくは、プログラム作成中にgithubで公開されているコードを使いたいけど、のちのち変更を取り込んだりしたいからgit管理しつつ(ただし、作成中プログラムのgitとして管理したいわけじゃない)コードに盛り込みたい時。

こんなときはgit submoduleを使うらしい。
※ただし、git監理が結構複雑になるのでなにか別の方法があればそうしたい気もする。
だいぶ慣れないと「gitで変更前に戻したのに実行時エラーになる!」みたいなことになって混乱しそう。

メインgitリポジトリへ、submoduleリポジトリの導入

(submoduleリポジトリを配置するディレクトリへ移動して)

git submodule add [リポジトリurl]
git commit(メインgitリポジトリへ「submoduleが追加された」というコミットを打つ)

既存gitリポジトリのブランチ切り替え

git checkout [特定のコミット]
git submodule update(updateをして初めてsubmoduleリポジトリが正しい状態へとcheckoutされる)

submoduleリポジトリの更新時

(submoduleのディレクトリへ移動して)
remoteの変更を取り込むなら

git pull 

もしくは 自分で変更したなら

git add
git commit 

(submoduleのディレクトリから出て)

git add
git commit(「submoduleが変更された」ということをcommitする)

submoduleリポジトリが入っているgitリポジトリをcloneするとき

git clone [リポジトリurl]
git submodule init
git submodule update

もしくは下記ならupdateまでやってくれる。

git clone --recursive [リポジトリurl]