動かざることバグの如し

近づきたいよ 君の理想に

kotlinのData Classでcustom getter/setterを実装する

結論からいうと色々カスタマイズしたいならData Classを使わずに普通のクラス作れって話

環境

  • kotlin 1.2

やりたいこと

kotlinには普通のクラスとは異なり値を格納するためだけのクラス、Dataクラスがよいうされている。変数を宣言するだけで自動でゲッターとセッターつけてくれて非常に便利なんだけど、getするときに〜の型に変換してほしいとか、setするタイミングで〜をつけてほしいとかある。

が、しかし

Data Classにgetter,setter()をカスタマイズできない。そこでもう1つ変数を用意する。

data class User(private val _name: String, val age: Int) {
    val name = "!!${_name}"
        get(): String {
            return "${field}!!"
        }
}


var u = User("taro", 30)
// u.name = !!taro!!

悪あがき感が否めないが。。。素直にデフォルトのclassでやるべきか

kotlin-Androidで文字列⇔日付の相互変換

コピペで再利用できるように

環境

本来、JavaレベルではJava SE8に追加されたtime APIが使えるのだが、Android上で使えるのAPIレベル26以上、つまりOreo以降になる。(誰もいないw

ので今回はベーシックなSimpleDateFormatを使う SimpleDateFormatの仕様はこちら

現在時刻を取得して文字列に変換

val df = SimpleDateFormat("yyyy年MM月dd日 HH:mm")
val message = df.format(Date())
Toast.makeText(this@MainActivity, message , Toast.LENGTH_SHORT).show()

文字列の日付をDate型に変換して文字列で表示

よくあるISO 8601形式をパースする

val date_str = "2018-06-16T13:00:00+09:00"
val df = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX")
val dt = df.parse(date_str)
val df2 = SimpleDateFormat("MM/dd")
val message = df2.format(dt)
Toast.makeText(this@MainActivity, message , Toast.LENGTH_SHORT).show()

例外キャッチする場合

val date_str = "2018-06-16T13:00:00+09:00"
val df = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX")
val dt = try { df.parse(date_str) } catch (t: Throwable) { null }
if (dt != null) {
    val df2 = SimpleDateFormat("MM/dd")
    val message = df2.format(dt)
    Toast.makeText(this@MainActivity, message , Toast.LENGTH_SHORT).show()

} else {
    val message = "date is invalid"
    Toast.makeText(this@MainActivity, message , Toast.LENGTH_SHORT).show()
}

Chromeが00000000とか大容量ファイルでディスクを消費している件

まじChrome先生戦犯でしょ。

発端

Macのディスク容量が結構圧迫してきたので調査していたら、Chromeがめちゃくちゃ容量食ってた

$cd ~/Library/Application\ Support/Google/Chrome/
$du -ch|tail
 16K    ./System Profile/data_reduction_proxy_leveldb
 20K    ./System Profile/Extension Rules
 20K    ./System Profile/Extension State
 20K    ./System Profile/Sync Data/LevelDB
 20K    ./System Profile/Sync Data
508K    ./System Profile
  0B    ./Webstore Downloads
  0B    ./WidevineCdm
 16G    .
 16G    total

16GBってなんやねん使いすぎでしょw

で、見てたら /Users/***/Library/Application Support/Google/Chrome/Default/File System/018/t/00の00000000というファイルが14GBも使用していた。

Chrome終了した状態で試しリネームしてChrome再起動しても問題なかったのでとりあえず消した。

なんだったんだ。。。

MySQLでバルクアップデートをする

MySQLでもbulk update ・・・的なことをしたかった話。

普通にアップデートするだけだと

UPDATE users SET yatin = 'taro' WHERE id = 1;
UPDATE users SET yatin = 'hanako' WHERE id = 2;

て書くが、1レコードごとに1クエリ走ってしまい、5万行を一括で更新するときとかだと以上に遅い。

そこでON DUPLICATE KEY UPDATE使えばいいじゃんって話になるのだが、

INSERT INTO users (id, name) 
VALUES(1,'taro'), (2, 'hanako') 
ON DUPLICATE KEY UPDATE name = VALUES(name);

IDが無かった場合はインサートされてしまうし、1つでもNOT NULLなカラムがあると指定しないとコケるので向いていない。

ってときはELT&FIELD構文が一番便利

ELT&FIELD構文

以下の例はID1,2をそれぞれtaro,hanakoにする例。複数カラムをそれぞれ更新することもできる

UPDATE users
   SET name = ELT(FIELD(id, 1, 2), 'taro', 'hanako') WHERE ID IN (1, 2)

参考リンク

Ubuntuの/bin/shはbashではなくdashとかやつ

めっちゃハマった。。

どういうこと

# ll /bin/sh
lrwxrwxrwx 1 root root 4 Feb 18  2016 /bin/sh -> dash*

は?????????

dash is

ashとかいうBourne互換シェルDebian版 だからd+ashでdash

厄介なのがBourne互換シェルを唄っているくせにbash等の構文の幾つかをサポートしていない点である。

たとえば

echo $RANDOM

というシェルスクリプトを適当に用意して/bin/bashで実行すると動く

/bin/bash main.sh 
6778

が、/bin/shにするととたんに動かなくなる。

/bin/sh main.sh 

これはshではなくdashが動いてしまっているせい。事実、CentOSのshなら動く

/bin/sh main.sh 
802

違い一覧よこせ