スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

libexifのLuaバインディングを公開した

libexifへのバインディング。ありそうでなかったので作った。
http://github.com/minoki/luaexif

スポンサーサイト

テーマ : プログラミング | ジャンル : コンピュータ

Dvorakを始めてみるテスト

QWERTYに不満があるわけではないが、気分で。

Macなら、ことえりの環境設定の“英字入力時のキーボード配列”を“Dvorak - Qwerty ⌘”にする。これだけ。

しかし、なぜかFirefoxでキーボードショートカットが効かなくなる。TextEditやFinderでは効くのに。
[追記] Firefoxだけじゃなかった。Mailやターミナルもだ、

JavaScriptでブロックスコープを実現する最速の方法

GreaseMonkeyのスクリプトを書いていたら、入れ子にしたfor文の内側と外側で同じ変数名を使ってしまい、無限ループになってFirefoxが固まった。JavaScriptにブロックスコープがあればこんなことは起こらなかったので、この仕様を決めた奴は氏ぬ全世界に謝罪するべきだと思う。

JavaScriptにはブロックスコープが無いのはよく知られた話だ。 以下のコードはコンソールに「0」を書き出す。

var x = 123;
{
  var x = 0;
}
console.log(x); // 0を出力

この問題に対する対処法もよく知られている。

var x = 123;
(function(){
  var x = 0;
})();
console.log(x); // 123を出力

さて、今日何となく「JavaScript ブロックスコープ」でググると、別の対処法を知った。

いくつかの対処法があるのは分かったが、実際、この中のどれが一番速いのだろうか。 new function(){}function(){}.call(new Object)とほぼ同じこと(返すものが違う)なのでnew Objectの分遅そうだ。

コードを書いて検証してみた。 まとめ:

  • Safariすげー
  • letがあればそれが一番速い
  • letがなければ (function(){})() が一番速い
  • new function(){} はやっぱり遅い
  • with(){} はその中間
  • みんな (function(){})() を使おう←もう使ってるよね
  • だれかletを(function(){})()に直すトランスレータを書いてくれ

以下、検証に使ったコードとその実行結果。

続きを読む

テーマ : プログラミング | ジャンル : コンピュータ

Objective-CのProtocolについて

Objective-Cのプロトコルはどう実装されているのか。

#include <stdio.h>
#include <objc/runtime.h>
#include <objc/Protocol.h>

@protocol SomeProtocol
- someMethod;
@end

int main() {
  Protocol *p = @protocol(SomeProtocol);
  printf("SomeProtocol: %p %s\n", p, protocol_getName(p));
}

@protocol(protocol_name)で、プロトコルの実体(Protocol *)を取得することができる。このコードをコンパイル、実行すると以下のようになる。

$ gcc test1.m -lobjc
$ ./a.out
SomeProtocol: 0x300c SomeProtocol

次に、@protocol(protocol_name)の代わりに、ランタイム関数であるobjc_getProtocol()を使ってみる。

#include <stdio.h>
#include <objc/runtime.h>
#include <objc/Protocol.h>

@protocol SomeProtocol
- someMethod;
@end

int main() {
  Protocol *p = objc_getProtocol("SomeProtocol");
  printf("SomeProtocol: %p %s\n", p, protocol_getName(p));
}

同じようにコンパイル、実行する。

$ gcc test2.m -lobjc
$ ./a.out
SomeProtocol: 0x0 nil

今度はnilが返ってきたようだ。このプロトコル(SomeProtocol)はどこでも使用されておらず、このプロトコルの実体が作られなかったようだ。

今度は、SomeProtocolに適合したクラスを宣言してみる。

#include <objc/Protocol.h>
#include <objc/runtime.h>
#include <stdio.h>

@protocol SomeProtocol
- someMethod;
@end

@interface SomeClass <SomeProtocol>
- someMethod;
@end

int main() {
  Protocol *p = objc_getProtocol("SomeProtocol");
  printf("SomeProtocol: %p %s\n", p, protocol_getName(p));
}
$ gcc test3.m -lobjc
$ ./a.out
SomeProtocol: 0x0 nil

今度もnilが返ってきた。宣言するだけでは不足なようだ。次はクラスの実装も書く。

#include <stdio.h>
#include <objc/runtime.h>
#include <objc/Protocol.h>

@protocol SomeProtocol
- someMethod;
@end

@interface SomeClass <SomeProtocol>
- someMethod;
@end

@implementation SomeClass
- someMethod { return nil; }
@end

int main() {
  Protocol *p = objc_getProtocol("SomeProtocol");
  printf("SomeProtocol: %p %s\n", p, protocol_getName(p));
}
$ gcc test4.m -lobjc
$ ./a.out
SomeProtocol: 0x30a4 SomeProtocol

取得できた。Class型のオブジェクトは、そのクラスが適合するプロトコルのリストを持つ(class_copyProtocolListで実行時に取得できる)ので、SomeProtocolの実体が作られたのだろう。

まとめ。Protocolの実体が作られる条件:

  • そのプロトコルに適合するクラス(カテゴリも?)の@implementationが書かれた
  • @protocol()で参照された

従って、どこからも参照されていないプロトコルを実行時にobjc_getProtocolで取得することはできない。

ちなみに、Protocolの実体はファイルごとに作られる。同じSomeProtocolであっても、あっちのファイル由来のものとこっちのファイル由来のものではアドレスが違う。protocol_isEqualで比較しよう。

テーマ : プログラミング | ジャンル : コンピュータ

プロフィール

minoki

Author:minoki
好きなプログラミング言語:
Haskell,Lua
GitHubアカウント
Twitter

最新記事
月別アーカイブ
カテゴリ
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。