bashで引数の配列の一つ後の要素を取り出す
即席で作ったシェルスクリプトのオプションの自前解析がしたくて。。
#!/bin/bash i=0 for OPT in "$@" do echo "index: $i OPT: $OPT OPTの一個後ろの要素 ${@:$(expr $i + 2):1}" # $i + 1 でないのは@の先頭は全要素を出力するため i=$(expr $i + 1) done
$ test.sh aa bbb c d index: 0 OPT: aa OPTの一個後ろの要素 bbb index: 1 OPT: bbb OPTの一個後ろの要素 c index: 2 OPT: c OPTの一個後ろの要素 d index: 3 OPT: d OPTの一個後ろの要素
Athenaのテーブル定義にファイル中に存在しない列を定義した場合の振る舞いについて
後からAthenaのテーブル定義に列を追加したい、みたいな場合に気になったので、メモ。
テーブル定義に存在する列で検索対象データ内で型が違うものは怒られますが、テーブル定義に存在して検索対象のデータに存在しない列についてはNULL扱いみたいでした。
以下試したクエリ。
CREATE EXTERNAL TABLE IF NOT EXISTS logs_with_absent ( `id` String, absent_str String, // 存在しない列 absent_int int // 存在しない列 ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' LOCATION 's3://woshidan-exmaple-test/athena_empty_key_test';
Query successful.
SELECT COUNT(*) FROM "mydatabase"."logs_with_absent" WHERE "logs_with_absent"."absent_str" IS NULL limit 10 ; => 1
SELECT COUNT(*) FROM "mydatabase"."logs_with_absent" WHERE "logs_with_absent"."absent_int" = 0 limit 10 ; => 0 SELECT COUNT(*) FROM "mydatabase"."logs_with_absent" WHERE "logs_with_absent"."absent_int" IS NULL limit 10 ; => 1
先週の反省会
- いまの日時
[NSDate date]
- 日付を扱うには
NSCalendaer
, 決まったフォーマットで文章にしたい場合はNSDateFormatter
NSDateFormatter
にセットするDateFormat
の文字列には時間に関係しない文字列(yyyy, MM, dd
みたいなもの以外 )が含まれている場合、[NSDateFormatter stringFromDate:]
の戻り値が空文字列となる
- 日付を扱うには
[[NSString alloc] initWithFormat:]
->[NSString stringWithFormat:]
- Javaではstreamのcloseはfinally節でやるのが定石
- closeもIOExceptionの可能性があるので、finallyの中でtry-catchする
try { InputStream is = ...; is.open() } catch (IOException ex1) { // ... } finally { try { is.close() } catch (IOException ex2) { // ... } }
- [Java] ループのブロックの中でしか使わない変数はそこで宣言した方がわかりやすそうだが、つどつど宣言することによるコスト増にならないか?
- JVMが最適化してしまうので、2010年くらいの段階で既にそんなことないらしい http://feather.cocolog-nifty.com/weblog/2010/05/post-a00a.html
- xcocdebuildでビルドしてる時、GUIのXCodeで他のアプリ開いてるとバグってxcodebuldのビルドこける
リモートのタグのコミットが欲しいときは git ls-remote --tags
$ git ls-remote --tags From git@github.com:woshidan/tag-test.git srcdiep0r4vns19wth7aoy399qv2or8or64zrkwd refs/tags/1.0.0 51eow33h7d87xiye3uunrcb6vl2hieourjd1pzy4 refs/tags/1.0.0^{} // git checkout refs/tags 1.0.0 で飛ぶコミット ubg7kxcgqoss7r4zewq103y58e6xj3dmo0ru5mp3 refs/tags/1.1.1 mx00rsw5psy4ge0fssf07j3wc9qjbcuo3dgm78n3 refs/tags/1.1.1^{} m91sf879ws8deyz1js219im2lpltghr4aqhv5mx9 refs/tags/1.2.0 wx2us06hq8trsloubhqllfaoo8my4qe2wthbgbrg refs/tags/1.2.0^{} 0ihu1zvz2z1qd94e0cwlk3ba2c88be9xjlsngjsh refs/tags/2.0.0 kh4hqgokh2uml5ingivvyd0ucvtcy85wmx6li6ii refs/tags/2.0.0^{}
BitBucketにgitでアクセス、あるいは新しいサイトでssh認証するときの鍵の登録と確認の手順
https://qiita.com/yyosuke/items/986dabc9906674e2ea97 を参考にSSHの公開鍵をBitBucketに登録。
~/.ssh/config
に bitbucket.org
に当該の秘密鍵を使ってアクセスするように設定する。
# サイトごとに鍵を分けた方が良い。。。 Host bitbucket.org HostName bitbucket.org IdentityFile ~/.ssh/bitbucket/id_rsa User git Port 22 TCPKeepAlive yes IdentitiesOnly yes
$ ssh -T bitbucket.org The authenticity of host 'bitbucket.org (104.192.143.2)' can't be established. RSA key fingerprint is SHA256:UvlgyNccfRyg8jrD8dzU2lwwd4dDWYbx4NfILUjQkKL(この値はダミー). Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'bitbucket.org,104.192.143.2' (RSA) to the list of known hosts. logged in as UserName. You can use git or hg to connect to Bitbucket. Shell access is disabled.
あとはほぼGitHubと同じで、remote
リポジトリを指定するときのホストが bitbucket.org
になっているだけ。
`NS_SWIFT_NAME` マクロでObjective-CのコードがSwiftからどう見えるか規定できる
Objective-Cで書いたメソッドのシグネチャはSwiftから呼び出す時にメソッド名の一部の単語がパラメータ名の一部へ変換されるものがある。
// Objective-C - (void)addToBox:(Item *)item;
// Swift 2.3 addToBox(item) // Swift 3.0 add(toBox: item)
この変換具合がSwift2系と3系で結構違う上に前置詞などを使った動詞の塊が切り取られて引数のラベルみたいに扱われてしまう。
すると、主に一番最初の引数の意味が違って見えることがある。たとえば、 上記の例の Swfit 3.0 のシグネチャでは toBox
というラベルがついてしまっているが、第一引数はItemのインスタンスであってBoxのインスタンスではないが、そういう風に見える。
なので、Objective-C + 複数のSwiftのバージョンに対応する必要がある場合はドキュメントなどのサンプルコードをどう書くか悩ましかったりする。
こういう場合、 NS_SWIFT_NAME
を使って Swift
ではこういうシグネチャで表示してほしい、という個別設定が可能。
- (void)addToBox:(Item *)item; NS_SWIFT_NAME(addToBox(item:));
参考
Swift3でCountdownLatchを作る、あるいはSemaphoreのtimeoutをSwift3で書く
テストの都合でラッチが欲しかったので、GCDのSemaphoreのラッパークラスを書こうと思ったんですね。
それで、 https://github.com/zhuhaow/CountdownLatch を参考にすれば割と簡単では! と思ったんですが、GCDの記法がSwift3で変わりすぎていて死ぬかと思った。のでメモ。
// 参考元: https://github.com/zhuhaow/CountdownLatch import Foundation class CountDownLatch { var count: Int private let dispatchQueue = DispatchQueue(label: "CountdownQueue") // 参考: https://qiita.com/codelynx/items/56ce2f91cd3f4f409aeb let semaphore = DispatchSemaphore(value: 0) let timeInSec : Int init?(count: Int, timeInSec: Int) { guard count > 0 else { return nil } self.count = count self.timeInSec = timeInSec } func countdown() { dispatchQueue.async { self.count -= 1 if self.count == 0 { self.semaphore.signal() } } } func await() -> Bool { // 参考: http://www.brilliantraven.com/code-snippets/grand-central-dispatch.html let result = semaphore.wait(timeout: DispatchTime.now() + DispatchTimeInterval.seconds(self.timeInSec)) if (result == .success) { return true } else { return false } } }
CouuntDownLatch
を使う側のコードは以下
func doTask() { let countDownLatch = CountDownLatch(count: 1, timeInSec: 30)! checkTimeoutBeforeCompletion(latch: countDownLatch) // なんか重い処理する countDownLatch.countdown() } func checkTimeoutBeforeCompletion(latch: CountDownLatch) { let queue = DispatchQueue(label: "background", attributes: .concurrent) queue.async { let processedOnTime = latch.await() if (processedOnTime) { NSLog("processed on time") } else { assertionFailure("遅いぞ!!!!") } } }