Life, Education, Death

プログラミング以外でも思ったことをつらつらと書きたい

Promiseの実装練習

翻訳: ”命令型のコールバック、関数型のプロミス: Node が逸した最大の機会” by James Coglan
これのコードを読んでいてイマイチ理解が出来なかったので、実行出来る形にコードを補完して写経してみた。

元記事のコードに出てくるPromiseクラスの完全版はたぶんこれ→ https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/promise.js


最後の方まで気づかなかったので、とりあえず簡単な自作Promiseクラスを実装したものをここに→ https://github.com/nilfs/promise-sample


値の依存関係に注目したプログラミングはもう少し練習して実践に生かして行きたいところ。


Node.jsは初めてだったけど、今回はサーバーコードじゃなかったし、firebug上でちょっと書くの余り変わらなかったな

Promiseの実装練習2

Objective-c版を実装し始めた。
C言語だと可変長引数の扱いどうしようとかトラブってなかなか進んでいない。一旦thenとresolve関数だけ実装してみた。

https://github.com/nilfs/promise-objc

メンバメソッドを呼ぶためにオブジェクトと関数ポインタ(セレクタ)を取っておく必要があってそれはNSInvocationというクラスを使うとうまくいく。

そもそも可変長引数のメソッドをどう扱おうと思ったときはここを参考にした

http://d.hatena.ne.jp/Kazzz/20120211/p1

NSInvocationというクラスの存在がわかったので少し光が見えてきたわけ。

NSInvocationクラスの使い方はここを参考にした

http://d.hatena.ne.jp/Kazzz/20120211/p1

まだ導入してないけど、このNSInvocationを生成するカテゴリは便利そう。
http://taoru.hateblo.jp/entry/20121119/1353290439


だんだんObjectiveCでも約束を守る実装が作れそうな気がしてきた。ObjCで出来るからC++でもどうにかなるかなぁ・・・。可変長引数を取っておく辺りのメモリ管理とか考えないとダメか

CAS(Compare And Swap)をしたいんだけど

Lock-freeにしたいところがあってobjective-cでどうやって書くか調べてみました。

#import
とimport文を書いて

    NSMutableArray * arrayA = [[NSMutableArray array] autorelease];
    NSMutableArray * arrayB = [[NSMutableArray array] autorelease];
    
    [arrayA addObject: [NSNumber numberWithInt:100]];
    [arrayA addObject: [NSNumber numberWithInt:200]];
    [arrayA addObject: [NSNumber numberWithInt:300]];
    
    NSLog( @"arrayA:%@ arrayB:%@", arrayA, arrayB );
    if ( OSAtomicCompareAndSwapPtr(arrayB, arrayA, (void * volatile *)&arrayB) ){
        printf("success");
    }
    NSLog( @"arrayA:%@ arrayB:%@", arrayA, arrayB );

という感じで、OSAtomicCompareAndSwapXXX関数を使えばいい。

メモリバリアあり版となし版があるようなので、そこは適宜。

他にどんな関数があるかはリファレンスを参照するとよさげ。

http://developer.apple.com/library/mac/#documentation/System/Reference/OSAtomic_header_reference/Reference/reference.html


ARCを有効にしているとidからvoid*への変換が許されないようなので、ARCを無効になるようにプロジェクトを設定するか
-fno-objc-arc
ってオプションをつけておかないとダメです。

マウスやキーボードの共有ツールで新しいものを見つけたので試してみました

Windowsマシンが増えたので、Synergyを入れようとぐぐっていたところ

Mouse without Borders
というアプリケーションを発見。解説はこちら

ダウンロードはこちら

インストールは、特に難しくなく接続するマシン名とセキュリティーコードを入力するだけですぐに繋がりました。
Windows同士だったらかなりオススメです。


2週間ほど使っていますが特にストレスはないです。一度だけ接続が切れることがありましたが、設定画面で再接続したら特に問題なく稼働しています。


特に便利なのが、Win+LでPCロックが出来ると思いますが、接続しているリモートマシンも一緒にロックする事が出来ます。
ロック忘れがなくなってよいですね。

あぁ管理者権限が消えてしまったよ

sudo実行時に、sudoerじゃないからsudoさせないよ。(user1 is not in the sudoers file. This incident will be reported.)
って警告が出てしまった場合は
間違えて管理者権限を消してしまった可能性があります。
(以下、Ubuntu 12.04 LTSでの対処法なので他のバージョンでは異なる可能性があります。)

まず、該当ユーザーのグループを確認しましょう。
Ubuntu 12.04では”sudo”というグループに属しているユーザーにsudo権限が付いています。
(ここは/etc/sudoersに書かれている設定に依存しているはずです)

groups

と打つと、自分が所属しているグループが表示されます。
ここにsudoがないとsudoを実行することができません。

1.他のsudo権限があるユーザーで直す

他のユーザーでログインをして

sudo gpasswd -a ユーザー名 sudo

というコマンドを実行すれば、無事sudo権限が与えられるはずです。


もし、どのユーザーにもsudo権限がない場合は他の方法で対応する必要があります。

2.LiveCDを使ってリカバリーモードにしてみる。

リカバリーモードで起動すると、読み取り専用で最初マウントされているので
fsckなど何か適当なモードを実行して、読み書き用で再マウントされるようにしてください。

その後、先ほどの画面で”root”を選択してRoot権限でコンソールを立ち上げてください。
立ち上がったら、

sudo gpasswd -a ユーザー名 sudo

で実行します。

参考

gpasswdの使い方など http://tobysoft.net/wiki/index.php?Ubuntu%2Fgroup%A4%CE%B4%C9%CD%FD%CA%FD%CB%A1

リカバリーモードについて画像付きで解説されています http://kledgeb.blogspot.jp/2012/08/ubuntu-1204_28.html

3.LiveCDを使ってUbuntuを起動させて無理やりに設定ファイルを変更する

2.同様にLiveCDを使います。Ubuntuをインストールせずに起動します。
起動後、Ubuntuがインストールされているドライブがマウントされているはずです(左側のタスクバーにHDDのアイコンがあるはず)
タスクバーの一番上のホームボタンを押して”Terminal”を起動します。
Vimが入っていなかったのでgeditで開きましたがなんでもいいと思います。)

sudo gedit /etc/group

でエディタを起動します。
グループ名:x:グループID:所属するユーザー
という書式なので、sudoというグループを検索します。
検索した末尾にユーザー名を追加して保存すればOKです。
(参考:グループファイルの見方について http://kazmax.zpp.jp/linux_beginner/etc_group.html

/etc/groupを変更後、PCを再起動すれば無事設定したユーザーでsudoが使えるようになります。

そもそも何で発生したのか・・・

グループを追加するつもりが、上書きしてしまったことが原因のようです。

グループ設定は再起動するまで反映されないようなので、しばらくの間気づきませんでした。

グループ設定を行うときは、上書きしないように気をつけましょう。

ゾンビになっているUITapGestureRecognizerを倒した

状況を説明すると

BのViewControllerでUITapGestureRecognizerを使ってUIImageViewをタップしたら、特定の動作をするように対応していた。

1〜5の順番で遷移させていくと、5のタイミングでクラッシュした。

NSZombieEnabledを有効にしたら、下のようなログが出ている状況。

*** -[UITapGestureRecognizer retain]: message sent to deallocated instance 0xf33ec00

調べた限りだと、↓と同じ現象のようだ。
iphone - Crash when using gesture recognizers in StoryBoard - Stack Overflow

Based on your steps to reproduce, this is a bug in UIKit. File a bug report. You can work around the bug by creating a strong outlet on SecondViewController and connecting it to the gesture recognizer. <del>Make sure you set the outlet to nil in viewDidUnload.</del>

ダミーでBのViewControllerにUITapGestureRecognizerのReferencing Outletsを接続して回避した。

UIKitのバグなのか、もっとスマートな回避方法があるかどうかがまだわかっていないが、一旦動いたのでこれでしばらくは・・・