2014-01-17

Objective-C の NSMutableArray の簡単な作り方

Objective-C ではサイズを変更できない配列 (NSArray) と、サイズを変更できる配列 (NSMutableArray) がある。Objective-C の参考書を読むと、Array の作り方として次のようなコードが書いてある。

NSArray* array = [[NSArray alloc] init];
NSMutableArray* mutableArray = [[NSMutableArray alloc] init];

これは本当に初歩的な書き方。Objective-C 2.0 (今の iOS 開発なら、Objective-C 2.0 がデフォールトになってる) なら、もっと簡単な Array の作り方がある。

NSArray* array = @[];

Array は大きさを変えられないので、実際のコードでは次の様にデータを入れて初期化する。

NSArray* array = @[@"foo" @"bar" @"hoge"];

Array はこんなにシンプルな書き方があるのに、MutableArray にはないものか... と諦めていたら、簡単な方法を見つけた。mutableCopy を使う。

NSMutableArray* mutableArray = [@[] mutableCopy];

Array を作って mutableCopy で mutable 化する。なんとシンプルな!!

蛇足ながら初期値を持つ場合のコードは...

NSMutableArray* mutableArray = [@[@"foo" @"bar" @"hoge"] mutableCopy];

NSMutableArray はサイズ 0 のものを作って、アイテムを push していくからあまり使わないけどね。でも、シンプルな NSMutableArray の作り方は覚えておいて損はない。

2014-01-16

Ruby の正規表現マッチには名前が付けられる

こんなことをやろうと思った。

文字列に「集合場所 ○○」と記入されていたら、○○の部分を抜き出すコード。

最初に思いついたのが、こんなコード。

if /^集合場所 (.+)/ =~ string
  p Regexp.last_match(1)
end

これは何とも読みづらい。最近の Ruby はマッチする () に名前を付けられると聞いた。さっそく試してみる。

if /^集合場所 (?<meeting_place>.+)/ =~ string
  p meeting_place
end

これは見やすくなった!!

蛇足: リファクタリング

コードは一応完成したけれど、一応入力ミス対策も入れておく。集合場所を半角スペースではなく全角スペースやタブで書く人もいるかもしれない。

if /^集合場所[   ](?<meeting_place>.+)/ =~ string
  p meeting_place
end

半角スペース・全角スペース・タブが入ってるけど、見た目で分からない。その上、誰かがソースコードを tabify したらタブが消えてしまう。ここは空白を表す [[:blank:]] を使う。せっかくなので複数スペース対策も入れておこう。

if /^集合場所[[:blank:]]+(?<meeting_place>.+)/ =~ string
  p meeting_place
end

やあ、人によっては「空白区切り」と言っているのに「:」を使うかもしれない。最後にその対策も入れておく。

if /^集合場所[[:blank:]::]+(?<meeting_place>.+)/ =~ string
  p meeting_place
end

半角と全角のコロンも入れた。これで完成。ちょっと見栄えが悪いけど、マッチした文字列との対応が分かり易いのが良いね。

chef の Directory リソース

chef の Directory レシピは次のように書く。

directory /path/to/dir do
  action :create
end

ところが、これは mkdir /path/to/dir とするようなもので、/path/to/ までディレクトリーがある場合は良いけれど /path/ までしかディレクトリーがない場合は to ディレクトリーがないと言ってエラーになる。

mkdir -p /path/to/dir のように、深いディレクトリーもちゃんと作成したい。

そういう場合は、recursive true オプションを加える。

directory /path/to/dir do
  recursive true
  action :create
end

ハマッたので、メモ。

2014-01-09

remote で削除されたブランチをローカルにも反映する

Qiita にやり方が書いてあったんだけど、自分のブログにも書いとかないとすぐ忘れちゃうんでメモ。元ネタはこちら。

この記事が書いてる通り、リモートのリポジトリーでブランチを誰かが削除しても、ローカルにはブランチが残ってる。これは気持ち悪い。そこで、誰かがリモートでブランチを消したら、ローカル環境にも反映させたい。

remote が origin だとした場合、次のコマンドでローカルのブランチも消せる。

$ git remote prune origin

ちなみに、リモートのブランチを消す方法は次の通り:

$ git push origin :branch

消したいブランチ名の前に : (コロン) を置くのがコツ。

せっかくなので少し解説すると、git で branch を push する場合、次のようにする。

$ git push origin local-branch-name:remote-branch-name

つまり、ローカル・ブランチとリモート・ブランチの名前は変えられる。けど、普通、ブランチ名を変える必要はないので、こうなる。

$ git push origin branch-name:branch-name

branch-name を二回書くのは煩わしいので、上のコマンドは下のコマンドと同じという扱いになっている。

$ git push origin branch-name

さて、話は戻ってリモート・ブランチを消す方法。空のブランチをリモート・ブランチに push すればいい。「空のブランチ」は空白で良いので、結果、コロンをブランチ名の前に置いたらリモート・ブランチが削除できたようなコマンドが出来上がる。

$ git push origin :branch

以上。

Emacs の M-! にはコマンド補完が利く!!

Emacs ではワンライナー (一行だけのコマンド) を走らせるのに M-! が使える。コマンド名は shell-command。

M-! を打つとミニ・バッファーに Shell command: と表示されるので、任意のコマンドを入力する。「make」でも良いし、「gcc foo.c」でも良いし、「echo hello」でも良い。RET キーを押すとコマンドが実行され、結果が出力される。

この M-!。コマンド補完が利いたらどれほど便利か。そう思っていた時期が、ぼくにもありました。では、M-! にはコマンド補完が利くと? はい。M-! にはコマンド補完が利きます。

いつの間に... 知らなかったよ。

コマンド補完が利くと便利なのは、カレント・ディレクトリーに置いた自作スクリプトを走らせる時かな。

ぼくは、このブログの記事をエディターで書いて Blogger にコピペしている。書いた記事ファイルは git server にアップしている。一々、アップするのも面倒なので、こんなスクリプトを書いている。ファイル名は git-blog.sh。

#!/bin/sh
date=`date +%Y-%m-%d`
git add -u
git commit -m "blog entry $date"
git push origin master

変更を git add して、commit して、push する shell script。ブログの記事を書き終える度にターミナルからスクリプトを実行するのが面倒だった。でも、今は Emacs からコマンドを実行するのもたやすい。

M-! ./g<TAB>

これだけで git-blog.sh という長いコマンド名を打つことなくスクリプトを実行できる。Emacs 万歳!!