2012年12月30日日曜日

「すごいHaskellたのしく学ぼう」9章 todo.hsのバグ修正など


「すごいHaskellたのしく学ぼう」でHaskellを勉強し始めてみた。通称すごいHな本と言われる本ですが、Hは変態言語の頭文字のHなのかなあと思うほどに自分にとっては新鮮な概念が多く、久しぶりに言語を勉強して脳がリフレッシュされていく感じがします。Hello Worldが3分の1くらい読み進まないと出てこない本です。説明が丁寧で初めてHaskellに触れる自分でも理解しやすいです。訳者が自分の大学学部時代の同じ学科の同級生らしく、感心している場合ではないなあと思う今日このごろ。

そして、原著はオンラインで読めたのだな。。。。
Learn You a Haskell for Great Good!

今日は、第9章のtodoリストのコードにバグらしきものをいくつか発見したので、誰かの役に立てばと書き記しておきます。

ちなみに、Haskellのシンタックスハイライトは下記をBlogのテンプレートに貼付けて使用しています。Bloggerで使用する場合は、CDATAセクションで囲まないとXMLエラーになります。
http://code.google.com/p/syntax-highlighter-brushes/source/browse/scripts/shBrushHaskell.js

本のコードで修正したのは以下の2点。ちなみに2点目はオンラインの原著ではすでに修正されていた。
  • removeで重複要素が存在する時に後の番号を指定すると、先の番号の方が削除されてしまう
  • 引数でファイル名を指定しているのに、"todo.txt"がハードコードされている

以下が修正コード。コメントアウト部分が元々の部分。

以下のコードだと最初に見つかった要素を削除してしまうため、todoTasksが[1,2,3,1,4,5]という状態の時に4番目にある"1"を削除した時に、1番目の1を削除してしまいます。
delete (todoTasks !! number) todoTasks

./todo remove todo.txt 4
-> Expected: [1,2,3,4,5]
-> Actual : [2,3,1,4,5]

読者への宿題になっているbumpも実装してファイル書き込み部分の重複をupdateTodoにまとめたのが以下。

2012年11月6日火曜日

(Amazon.comで)Kindle PaperWhite購入した

5ヶ月Blog書いてなかったんかいな。。。


日本に帰国している間に、Kindle PaperWhiteが会社に届いていた。9月の半ばに予約して10月下旬の配達。それを取りに行くためだけに土曜に会社に行ったのだけど、自席に置かれてなくてがっかりして帰ってきたのだけど、ようやく入手。配達追跡記録をWebで見てみると、サインした人の名前が表示されていたので(これ地味にすごい)その人をたずねたら受け取れた。寝る前に読むのに眼が疲れなさそうなのと、最初から日本語対応しているのでPaperWhiteを選択。U.S.で発売されてるKindle Fireは日本語入力するためにはちょっといじってroot権限取ったりしないといけないらしい。

買ったのは3Gモデル。3G無しが$119、3G付き$179(広告付き版。あとで$30払えば広告は除けて、最初に$20払っとけば最初から広告無し版になる)。3Gモデルを選択したのだけれど3GはAmazonのサービス全般とWikipedia(なぜWikipedia?)だけしかつながらない模様。これは、日本で発売された時も変わらない気がする。抜け道あったよ的な情報もあるけど、自分の環境ではもう使えなかった。
※ぐぬぬ。$1=80円とすると、11/19発売の日本版の方が安いではないか。。
  Wifi:(US:9520円、JP:8480円)、3G+Wifi:(US:14320円、JP:12980円)
  →Amazon「Kindle」を日本でも11月発売、「Kindleストア」は10月25日オープン


長年バックライト液晶の画面しか見ていなかったため、この画面はすごく新鮮。電源ボタンを押してロックすると、上記の広告が出てくるのだけどそれが時間がたっても消えない。液晶とちがって、静止画スクリーンセーバーは電力を消費しないかららしい。画面がマルチタッチ対応で、ホームボタンもなくて電源ボタンしかない点も男前。Amazonアカウントにひもづいているため、ワンタッチでぽんぽん本が買えてしまうのは危険。

しかし、漫画のカテゴリーで少女コミックや少年コミックに並んでボーズラブコミックス(なぜかこれだけ複数形)が堂々リストアップされているのはいかがなものかw。

とりあえず、この漫画が異常に評価高かったので買ってみた。
夕凪の街 桜の国 (Action comics) [Kindle版]
(でもこの記事書いててまだ読んでない)

参考にしたページいろいろ:
Kindle PaperWhite Official Site
海外からKindle日本の本を購入して、読む方法
アマゾンの電子書籍リーダーKindle Paperwhiteを速攻レビュー
日本版 Kindle Paperwhite・Fire/HD FAQ 【まとめ】

2012年6月3日日曜日

javascriptクイズ(解説編)

下記の記事の解説を試みてみる。

JavaScriptクイズ「x + 0 == x - 0」

筆者は7個まちがえて65/100点でございました。とはいえ、実際の動きを調べてみたら偶然結果が当たっていただけのこともあり、点数ほどは理解出来ていません。ちなみに、動作確認した処理系は、"node.js v0.7.5-pre"。

まずは、1問目の解説から。

まずは、左辺がどのように展開されるかの解説。
{}+0
  • ToPrimitive({}, PreferredType=Number)+0
    // No hint for PreferredType then default "Number".
    // See 8.6.2.6 [[DefaultValue]](hint).
  •     When the [[DefaultValue]] method of O is called with no hint, then it behaves as if the hint were Number
  • {}.toString()+0
    // See 8.6.2.6 [[DefaultValue]](hint)
        5. Call the [[Get]] method of object O with argument "toString".
    // ここ自信無い
  • '[object Object]'+0
  • '[object Object]'+0.toString()
    // Because Type(ToPrimitive({},PreferredType=Number)) is String.
    // See 11.6.1 The Addition operator (+ )
        7.If Type(Result(5)) is String or Type(Result(6)) is String, go to step 12
        12. Call ToString(Result(5)).
        13. Call ToString(Result(6)).
  • '[object Object]0'

うーん、しんどい。お次は、右辺。
{}-0

最後に、左辺と右辺の比較の解説
See 11.9.3 The Abstract Equality Comparison Algorithm.
'[object Object]0'==NaN
  • ToNumber('[object Object]0')==NaN
    // 1. If Type(x) is different from Type(y), go to step 14.
    // 17.If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x)== y.
  • NaN==NaN
  • false
    // 5.If x is NaN, return false.

うーん、これでもいくつかはしょってるけど、まじめに解説するとめっちゃ大変(どっか間違ってたら、ご指摘願います)。こっからはがしがしはしょっていきます。



[]+0==[]-0
  • [].toString()+0==ToNumber([])-0
  • ''+0==0-0
  • '0'==0
  • ToNumber('0')==0
  • 0==0
  • true
ポイントは、以下の2点かな。
  [].toString() returns ''
  ToNumber([]) returns 0



(function(){})+0==(function(){})-0
  • (function(){}).toString()+0==ToNumber((function(){}))-0
  • 'function (){}'+0==NaN-0
  • 'function (){}0'==NaN
  • ToNumber('function (){}0')==NaN
  • NaN==NaN
  • false
関数もオブジェクトのひとつ。あとは、1問目と同じ。



null+0==null-0
  • ToNumber(null)+0==ToNumber(null)-0
  • 0+0==0-0
  • 0==0
  • true
ToNumber(null) returns 0.
See 9.3 ToNumber.



undefined+0==undefined-0
  • ToNumber(undefined)+0==ToNumber(undefined)-0
  • NaN+0==NaN-0
  • NaN==NaN
  • false
ToNumber(undefined) returns NaN.
See 9.3 ToNumber.



Infinity+0==Infinity-0
  • Infinity==Infinity
  • true



Array+0==Array-0
  • Array.toString()+0==ToNumber(Array)-0
  • 'function Array() { [native code] }'+0==NaN-0
  • 'function Array() { [native code] }0'==NaN
  • ToNumber('function Array() { [native code] }0')==NaN
  • NaN==NaN
  • false
コンストラクタも関数オブジェクト。



0+0==0-0
  • true
何も言うまい。



false+0==false-0
  • ToNumber(false)+0==ToNumber(false)-0
  • 0+0==0-0
  • true
ToNumber(false) returns 0. (ToNumber(true) returns 1).
See 9.3 ToNumber.



NaN+0==NaN-0
  • NaN==NaN
  • false
See 11.6.3 Applying the Additive Operators ( +,- ) to Numbers
If either operand is NaN, the result is NaN.



""+0==""-0
  • ToString("")+ToString(0)==ToNumber("")-0
    // 7.If Type(Result(5)) is String or Type(Result(6)) is String, go to step 12.
    // 12. Call ToString(Result(5)).
    // 9.Call ToNumber(Result(6)).
  • ''+'0'==0-0
  • '0'==0
  • ToNumber('0')==0
  • 0==0
  • true
ToNumber("") returns 0.
See 9.3.1 ToNumber Applied to the String Type.
A StringNumericLiteral that is empty or contains only white space is converted to +0.



"a"+0=="a"-0
  • ToString("a")+ToString(0)==ToNumber("a")-0
  • 'a'+'0'==NaN-0
  • 'a'==NaN
  • ToNumber('a')==NaN
  • NaN==NaN
  • false



"0"+0=="0"-0
  • ToString("0")+ToString(0)==ToNumber("0")-0
  • '0'+'0'==0-0
  • '00'==0
  • ToNumber('00')==0
  • 0==0
  • true



"1"+0=="1"-0
  • ToString("1")+ToString(0)==ToNumber("1")-0
  • '1'+'0'==1-0
  • '10'==1
  • ToNumber('10')==1
  • 10==1
  • false



"0.1"+0=="0.1"-0
  • ToString("0.1")+ToString(0)==ToNumber("0.1")-0
  • '0.1'+'0'==0.1-0
  • '0.10'==0.1
  • ToNumber('0.10')==0.1
  • 0.1==0.1
  • true



"0x"+0=="0x"-0
  • ToString("0x")+ToString(0)==ToNumber("0x")-0
  • '0x'+'0'==NaN-0
  • '0x0'==NaN
  • ToNumber('0x0')==NaN
  • 0==NaN
  • false
'0x0' is HexIntegerLiteral.
See 9.3.1 ToNumber Applied to the String Type.



"."+0=="."-0
  • ToString(".")+ToString(0)==ToNumber(".")-0
  • '.'+'0'==NaN-0
  • '.0'==NaN
  • ToNumber('.0')==NaN
  • 0==NaN
  • false
ToNumber(".") returns NaN while ToNumber(".0") returns 0.
See 9.3.1 ToNumber Applied to the String Type.



" "+0==" "-0
  • ToString(" ")+ToString(0)==ToNumber(" ")-0
  • ' '+'0'==0-0
  • ' 0'==0
  • ToNumber(' 0')==0
  • 0==0
  • true
See 9.3.1 ToNumber Applied to the String Type.
StringNumericLiteral:::StrWhiteSpace(opt) StrNumericLiteral StrWhiteSpace(opt)
A StringNumericLiteral that is empty or contains only white space is converted to +0.



Array()+0==Array()-0
  • []+0==[]-0
  • あとは、2問目と同様。
  • [].toString()+0==ToNumber([])-0
  • ''+0==0-0
  • '0'==0
  • ToNumber('0')==0
  • 0==0
  • true
15.4.1 The Array Constructor Called as a Function
it creates and initialises a new Array object.
うーん、これは知らなかった。
See JavaScript: new無しで基本型のコンストラクタを呼んだ時の挙動.



(function(){}())+0==(function(){}())-0
  • undefined+0==undefined-0
  • あとは、5問目と同様。
  • ToNumber(undefined)+0==ToNumber(undefined)-0
  • NaN+0==NaN-0
  • NaN==NaN
  • false
12.9 The return Statement
ReturnStatement : return [no LineTerminator here] Expression(opt);
If Expression is omitted, the return value is undefined.


ここまで読んでくださったみなさま、ありがとうございました。
どっか間違ってるとこがあったら、ご指摘ください。
それにしても、20問の中にいろんなパターンが含まれていて、よくできてるなあ。

参考:
Standard ECMA-262 3rd Edition -December 1999
JavaScript: new無しで基本型のコンストラクタを呼んだ時の挙動
What is {} + {} in JavaScript?
[ ] == ![ ] の謎を自分でも解いてみた

2012年4月7日土曜日

Flexリストコントロールでのデザインパターン(とiOSのUITableViewとの比較)

最近、Flexのリストコントロール(データグリッド)をいじってて分かったことのメモ。

Flexのリストコントロール


Flexのリストコントロールとやらは、以下みたいなのがあります。
左から順番に「リストレイアウト」、「ドロップダウンリスト」、「データグリッド」。


んで、このリスト系コントロールというのが「データ駆動型コントロール」と呼ばれるもので使い方に癖があったりします。もうちょっと言うと、ひとつのコントロールの世界の中でMVCデザインパターンが適用されている。ざっくりとした関係は以下。


Viewコントロールの中に「レンダラー」と呼ばれる描画用オブジェクトが存在し、そこにControllerとしてのFlex君がModelオブジェクトを差し込んで描画する。ポイントとしては、レンダラーオブジェクトはユーザの可視領域分といくつかのバッファ分の数しか存在しない。

「レンダラーA」〜「レンダラーC」で「データ1」〜「データ3」が描画されているとして、例えばデータグリッドを下スクロールすると、それまで「データ1」を描画していた「レンダラーA」が使い回されて「データ4」を描画するようになったりする。ようするに、描画オブジェクトのリサイクルについてFlexが面倒を見てくれる。

それによって、100万のデータを画面で扱う時に見えてない99万9990ほど分のModelオブジェクト用の描画オブジェクトが節約される。

Flexのリストコントロールを独自拡張する時は、上記が分かってないとうまく描画されないことに悩んで、ことあるごとにFlexにとって天敵の全行再描画を実施して画面が重くなってしまう。

気をつけないといけないのは、Modelオブジェクトの中で描画用データも保持しておく必要があること。ユーザ操作で文字を赤くした場合に、その「文字が赤い」情報をModelオブジェクトで保持しておかないとそのデータを再描画した際に、文字色がデフォルト色に戻ってしまったりする。ModelというのはビジネスロジックのModelではなくあくまで描画アーキテクチャ上でのModelということ。

IListItemRendererインタフェースの"set data"メソッドをオーバーライドすることにより
ModelオブジェクトをViewコントロールに独自のロジックで設定することが可能になる。

このアーキテクチャのいま思いつくメリット/デメリットは以下。

メリット:
  • 描画オブジェクトのリサイクルをFlexに任せることができる
デメリット:
  • 設計思想を理解するのに時間がかかる
  • 同じリストコントロール上で複数種類のコントロールの使い分けがしづらい(1行目はラベルで2行目はチェックボックスとか)

Flexのレンダラーについては以下がよくまとまっていて勉強になりました。
itemRendererパート1:inline itemRenderer
itemRendererパート2:external itemRenderer
itemRendererパート3:Communication(データのやりとり)
itemRendererパート4:ステート&トランジション

あと、Adobeのヘルプ。
Flex3開発ガイド/Listコントロール

Adobeのヘルプは、量もAppleのほど多くなくてかつ分かりやすくてよく書かれていると思う。まあ、Appleはフレームワークのソースコードを公開してないからあんだけのドキュメントが要るのかもしれないけど。

iOSのUITableViewとの違い


一方で、iOSのUITableViewはちょっと違う。
UITableViewは以下みたいなiOS版リストコントロール。


こいつへのデータの割当ては以下のようにUITableViewDelegateプロトコルのtableView:cellForRowAtIndexPath:メソッドを実装したりする。


Flexのリストコントロールとの違いは、開発者がコードの中でヘルパーメソッドdequeueReusableCellWithIdentifierやらinitWithStyle:reuseIdentifier:やらを呼び出し自力で描画オブジェクトのリサイクルをすること。

意識する必要のあることはこちらの方が多いが、リサイクルするしないをオブジェクトの識別子文字列(上記の例だと@"MyIdentifier")によって開発者が決められるため、Flexリストコントロールのデメリットであげた「同じリストコントロール上で複数種類のコントロールの使い分け」が比較的しやすい(識別子文字列でそこを意識すれば良い)。

ようするに、少し手間がかかるけどこっちの方が好き勝手しやすそうだ。まあ自由には責任が伴うのが常なので、粗悪な設計の影響を受けやすいけど。

その他Flexについて


Flexは他にもプロパティ無効化(invalidateProperties)や描画無効化(invalidateDisplayList)などの非同期な描画アーキテクチャを採用していて、世の中的にはFlashオワコンな風潮だけどフレームワークの設計は非常におもしろい。iOSと違って、ソースが公開されているのも良いね。

あとは、以下を読んだりして勉強しました。
asでカスタムコンポーネント(1)
asでカスタムコンポーネント(2)
asでカスタムコンポーネント(3)

コアなのは、UIComponentクラスLayoutManagerクラス

2012年3月4日日曜日

ActionScript3のSetterがGetterを呼び出す?


「詳説 ActionScript 3.0」には下記の内容が書かれています。
setメソッドは、呼び出されると、それに対応するgetメソッドを常に呼び出し、getメソッドの戻り値を返します。
これによりプログラムでは、新しい値の設定後すぐにその値を使うことができます。
…<中略>…
値を返すsetメソッドの機能は便利に使える一方で、getメソッドに制限を加えています。
特にgetメソッドでは、内部的な変数の値の取得に必要な程度を超える作業は絶対に行うべきではありません。
…<中略>…
setメソッドによるgetメソッドの自動的な呼び出しによって、カウンタの記録の追跡が損なわれることになります。
引用:ActionScript3のsetメソッドの返り値

けれども、上記の引用元でも書かれているように、必ず呼ばれる訳ではなさそう。
自分の環境でも、SetterからGetterは呼ばれていなかった。
それは、OreillyのP79の例のようにSetterの戻り値を何かの値に代入したりして結果を評価しても同じだった。

この辺、FlexSDKのレイヤーとFlashPlayerのレイヤーとどちらに依存しているかはよく分からない。
ちなみに自分の環境は以下(Windows版でも今回書いているすべての結果は同じだった)。
Flex4.1A
Macintosh Flash Player 10.3 Plugin content debugger (Intel-based Macs)
FlashBuilder4.6(体験版)

ここでは、ブレイクポイント設定時にFlashBuilderがおかしな動きをして
あたかもSetterがGetterを呼んでいるかのような挙動に見えてはまったので
そこも含めて確認した結果をメモとして残しておく。

まずは、下記のコードを用意。
ポイントは、以下の2点。
・プロパティpropを用意し、そのGetterでpropCountをインクリメントしてコンソール出力
・execute()でGetterとSetterをそれぞれ呼び出し


まず、ブレイクポイントを設定しない時のexecute()実行時のコンソールは、以下となる。
start
GetterCalled:1
callGetter:0
callSetter
SetterCalled
end
やはり、Setterが呼ばれた時もGetterは呼ばれていない。
(自分の環境では、Oreillyの記述は嘘だったということになる)

ただし、ブレイクポイントを23行目に設定して
1行ずつ28行目まで下記のように変数値を確認しながら動かしてみる。

コンソール出力結果は、下記。Getter呼び出しが増えている(赤字が増えた分)。
GetterCalled:1
start
GetterCalled:2
GetterCalled:3
callGetter:0
GetterCalled:4
callSetter
GetterCalled:5
SetterCalled
GetterCalled:6
end
GetterCalled:7

これ、ちょうどブレイクポイントを設定して変数値を確認した回数だけGetterが呼ばれている。
プロパティpropの値をデバッガ上で見せたくて、FlashBuilderが値を表示するたびにGetterを呼び出しているようだ。
しかも、変数参照ビューをスクロールして画面に表示された瞬間にGetterを呼び出すという手の込みよう。

この時点ではまだGetterは呼び出されていない。
表示領域を少しずつ大きくして・・・propが表示された下記の瞬間に初めてGetterが呼び出される(いないいないばぁ的な)
(ここではいないいないばぁするためにダミーの変数を追加しています)

結論としては、このような変な動きをするケースがあるため、Oreillyにも書いてあるように
Getterの中ではオブジェクト内部で保持する値を更新するような副作用を伴う処理は厳禁ということで。

2012年2月26日日曜日

javascriptの配列sliceコピー

使い捨てコード用メモ。
javascriptで以下の方法で、配列を別インスタンスにして(いくつか注意点があるけど)sliceメソッドを使ってコピーできる。

単なる代入との違いは、以下で確認できる。
sliceコピーした配列には要素の削除が反映されていない。
別インスタンスとしてコピーされている。

ただし、あくまで配列が別インスタンスになっているだけであって
deep copyではないので、object型の要素は同じインスタンスを指している。
以下の3つ目のobject型の要素はvar bでも"hoge"から"fuga"へと変更されてしまっている。
他のプリミティブ型はimmutableなのでたまたま変更が跳ねていないだけ。

sliceメソッドを本来の目的でない使い方をしているのと制約があるのとで
使い捨てコードを書くとき以外は使わない方が良さそうだけど、便利そうなので備忘録としてメモっておく。

■参考:
http://www.gucch.net/programming/javascript/jqueryやprototype-jsでオブジェクトをディープコピーする/

2012年2月17日金曜日

node.jsをgithub経由でローカルにインストール


consoleでjavascriptを手軽に扱えるようにしようとnode.jsをインストール。
せっかくなので、githubからforkしてローカルにcloneしてみた。
環境:Mac OS X Lion, Xcodeインストール済み

上記のnodeのページで右上の「fork」ボタンをクリック。
画像は既にfork済み状態でキャプチャしたので、「Your Fork」ボタンになってしまっている。

ちょいと待ったら、自分のGithub上にリポジトリが出来るので
あとはそれをローカルにcloneしてインストール。コマンドは以下。


インストールは、結構時間かかった。
最後にsudoでmake installしないと、自分の場合はPermission Deniedになった。

nodeコマンドが使えるようになった!

2012年2月15日水曜日

Googleの入社問題(数字当てクイズ)


昨日、会社のリスクマネジメント研修とやらを受けさせられたのだが
その中で講師の人が講義の時間の間を埋めるのに以下の問題をGoogleの入社試験だと出題したのだった。
1
11
21
1211
111221
?
【?に入る数字をこたえよ】

自分は結局答えが分からなかったのだけど。
回答が分かれば、コードで出力する問題としては暇つぶしに手頃なサイズだったので以下のアプリで書いてみた。
Javascript-1

以下、ねたばれ注意



HTMLの中に埋め込む形式で書いたのだけど、HTMLの部分は本質ではないので省いている。
HTML付きでブラウザで表示するだけで回答が見れるコードは以下。
https://gist.github.com/1828081

iPhoneのソフトウェアキーボードでコード打ち込みながらdocument.write()するデバッグは辛かった・・・。
最初、自分でnumber型をresにpushしていながら
6行目で癖で===で比較していたため値は一致しても型不一致で期待通りに動いていなかったという\(^o^)/

以下、回答。一応、文字を白にしとくんで、見たい人は文字選択してください。
1
1 1
2 1
1 2 1 1
1 1 1 2 2 1
3 1 2 2 1 1
1 3 1 1 2 2 2 1
1 1 1 3 2 1 3 2 1 1
3 1 1 3 1 2 1 1 1 3 1 2 2 1
1 3 2 1 1 3 1 1 1 2 3 1 1 3 1 1 2 2 1 1

以下が回答を紹介しているページ。
http://ntakei.cocolog-nifty.com/pam/2006/04/post_231f.html

一言で言うと、文字と文字数を並べていくだけなんだけど、これってどこかで見たことある・・・と思って検索したら、正体は「ランレングス圧縮」だったのであった。
# 大学の情報理論の授業で習ったはず
# 久しぶりにハフマン符号化とか調べてしまった

連長圧縮(ランレングス圧縮、RLE:Run Length Encoding)
連長圧縮では、ある連続したデータを、そのデータ一つ分と連続した長さで表現することで圧縮している。
例えば、「A A A A A B B B B B B B B B A A A」は「A 5 B 9 A 3」と表せる。これは、Aが5回続き、そのあとにBが9回、そしてAが3回続いていることを表している(連続回数を、元のデータを表す符号の前に記録することもある。その場合、符号化した後は「5 A 9 B 3 A」と表される)。

講師の人は、Googleはこういう柔軟な発想が出来る人がごろごろいるのでしょうかねーと言っていた。
そういう発想の柔軟さもそうなのかもしれないけれど裏に隠れているコンピュータサイエンスの基礎理論を見抜いて解ける人もまたターゲットにしているのかも。

まあ、最近のシリコンバレーのジョブインタビューは(一時期流行った)こういうクイズめいた問題は実際の業務では役に立たん!とあまり出題されないらしいけど。

# 2012/2/19 Array.join()を使用するよう変更

2012年2月6日月曜日

GithubをXcodeのリモートリポジトリにする方法(コマンド使わずに)

Xcode4から標準インストールされているGit。
Githubをコマンドを使わずにリモートリポジトリとして指定する手順を説明している
良いページが見つからなかったので書いてみる。

前提

Xcodeプロジェクトが既にローカルGitリポジトリで管理されていること。
Githubにコマンドラインから接続可能なこと。
Version:4.2.1

主に以下の手順となる。
  • 1.Github上でリポジトリ作成
  • 2.Xcode上でリモートリポジトリ指定
  • 3.Xcode上でpush

1.Github上でリポジトリ作成

通常の手順でGithub上でリポジトリを作成する。

2.Xcode上でリポジトリ指定

ここからローカル作業。
Xcode上で下記の要領で"Repositories Organizer"を開く。

そして、自分のプロジェクトの"Remotes"を選択して、"Add Remote"を押下。
下記の要領で入力する。
  • Remote Name:Organizer上の表示名程度だと思ってる。詳しい方、教えてください。
  • Location: GithubのURI。git@github.com:ユーザ名/リポジトリ名.git
Locationは"https://..."でも行けるとどこかのサイトに書いてあったけど、試していない。


"Create"ボタンを押すと、以下の画面になる。何もせずに静かにOrganizerを閉じる。
最初、画面の下のパスワード等の入力フォームを入力しないといけないと思ってしまい
いろいろと入力してみるも何の反応も無く、Locationをいじったりして勝手にはまった。
しかし、パスワード等を入れなくても、以下の手順でpushまで出来た。

3.Xcode上でpush

下記のように"push..."を押す。

すると、下記のダイアログ登場。
そして、意外とこの画面で待つ。自分の場合、10秒くらい待った。
ここで待たされたせいで、設定が間違っていると勘違いして手戻った。

待ってると、下記の画面登場。さくっと"push"して完了。

全体的に、独りで勘違いして時間かかった。
Repositories Organizerはまだ安定しなくて、結構しょっちゅうCrashする。
今後の改善に期待。

NSNumberクラスとプリミティブ型との変換


元々はこの記事を書こうと思ってたんだった。
脱線してObjective-Cの整数と32bit64bitの記事が一個forkした。
まあ、この記事も元々はCoredataのNSManagedObjectのプロパティの型ではまったことによるforkです。

Objective-Cのコレクションクラス(NSArrayやNSDictionary)ではid型(オブジェクト型)しか扱えないため
NSIneger等のプリミティブ型を扱う際にはNSNumber型に変換する必要がある。
そこで、下記の相互変換についてメモとしてまとめておくことにした。
  • NSInteger
  • int
  • NSNumber

以下、基本的にMac-OS-X 64bit向け。
iOS環境では、NSIntegerの取る型が異なるため、NSLogのString Format Specifiersが異なる。
値が代入されていないと、%@でNSIntegerはエラーにならないが
値が代入されていると、"EXC_BAD_ACCESS"となって実行時エラーとなる。


初期値について


初期化していない状態での初期値は、NSNumberはオブジェクト型なので「nil」、intは「0」となる。
NSIntegerはオブジェクト型として評価すると「nil」、整数として評価すると「0」となる。


int <-> NSInteger


NSInteger -> int はキャストすれば良い。
キャストしないと警告が出るのは"Objective-Cの整数と32bit64bit"で書いた通り。

一方で、int -> NSIntegerはキャストは不要。
理由はざっくりな説明だと、NSIntegerがintをくるんでいるため
下位概念のものを上位概念のものに入れることになるから、かと。


NSInteger <-> NSNumber


NSInteger -> NSNumberについては、NSNumberクラスのメソッドを使用する。
クラスメソッドを使用するパターンとalloc initするパターンがある。

NSNumber -> NSIntegerについてもintegerValueメソッドでOK。


int <-> NSNumber


このパターンについては、NSInteger <-> NSNumberとメソッドが微妙に変わるだけ。



整数以外のfloatやdoubleも基本的には同じなので割愛。

サンプルプロジェクトを以下のGithubで公開。
https://github.com/k-ori/objc-nsnumber-primitive-convert-samples

xcodeからのGithub連携でいいサイトが無かったので、それも後で書く。

■参照ページ
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/Reference/Reference.html

http://peterszwach.blogspot.com/2011/03/github-xcode-4.html

Objective-Cの整数と32bit64bit


NSIneger等のスカラ型とNSNumber型の変換についてまとめようとしたんだけど
調べてるうちにObjective-Cのint型とNSInteger型、32bitと64bitの関係について
気づいたら調べていたのでまずはそこからまとめておく。

以下、特に注意書きしていない限りは、Mac-OS-X 64bit向けにビルドした結果。

まずは、NSInteger型をint型にキャストせずに代入すると以下の警告が出る。
Implicit conversion loses integer precision: 'NSInteger'(aka 'long') to 'int'

警告の理由は、NSIntegerの持ちうる値が32bitか64bitかは処理系依存だから。
int型変数に値を代入する時はプログラマが明示的にint(32bit)と宣言する必要がある。
そして、NSIntegerはlong型 "または" int型をtypedefしたもの。
(この"または"が処理系に依存する部分)

Foundation Data Types Reference

NSInteger

Used to describe an integer.

Discussion

When building 32-bit applications, NSInteger is a 32-bit integer. A 64-bit application treats NSInteger as a 64-bit integer.

Availability

Available in Mac OS X v10.5 and later.

Declared In

QTKitDefines.h

long型、int型といったプリミティブな型をNSIntegerにラップしてくれている。
NSInteger型を使用することで、32bit環境のコードを64bit環境に移植する時にコードを変更する必要がなくなる。

ちなみに、現時点のiOSデバイスのARM processorは(現時点で)32bit onlyだそうなのでNSIntegerでは64bit整数は扱えないそうです(@see iOS: 32bit or 64 bit? - DesignersTalk)。
OSX Lionだと64bit整数を扱える。

OSX 64bit用にビルドして下記のコードを動かすと、int型以外は正しく表示される。

NSLogに渡す際のformatter文字列を%ldにしないと正しく表示されないので注意。
int型は現在4バイト32ビットで、-2147483648〜2147483647 (約マイナス20億からプラス20億) の整数値を表すことができる。

2147483647を超えると、-2147483648に戻る。
よって、以下の通り2147483647を超えて1周半くらいして1410065408になる。
1410065408=10000000000-(2147483648*4)

ちなみに、上記と同じコードをiOS向けにビルドすると、結果が変わる。

32bit整数しか扱えないので、OSXでは正しく扱えていた値がオーバーフローしてしまっている。
ただ、コンパイラの優しいところは、ちゃんと明示的に大きな値を入れているときは警告を出してくれる。
warning: implicit conversion from 'long long' to 'NSInteger' (aka 'int') changes value from 10000000000 to 1410065408 [-Wconstant-conversion,3]
まあバグが発生する時は、だいたい巨大な値が外部リソースから実行時に入ってくる時なんだけど。



コンパイラ様の言う通りに「long long」型にしたら、iOSシミュレータ用でもちゃんと動いた。
NSLogのformatter文字列を%lldにしないとやっぱり正しく表示されないけど。
long修飾子をつけるとより多くのメモリ領域を確保する模様。

しかし、結局のところint型の取りうる範囲もコンパイラ依存な訳で
Apple様以外の環境なりコンパイラなりでいろいろと結果が変わるのだろうなあ。

■主な参照ページ
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html
http://stackoverflow.com/questions/8813799/warning-implicit-conversion-loses-integer-precision
http://www16.ocn.ne.jp/~maccocoa/objective_c/keyword/keyword1.html
http://www.designerstalk.com/forums/mobile/59128-ios-32bit-64-bit.html

2012年1月30日月曜日

マイdot.emacsを調査してみた


本当は作りたい物があったんだけど、自分のemacsにjavascriptモードが無かったためそれを追加した。でもあれ、そもそもemacs-lispっていつもサンプルから拾うだけであんまり中身知らないなあと思って調べてみた。

初めてemacsに出会ったのは大学1回生時の授業であるけど
emacs-lispに興味を持ったことは今までついぞ無かったのであった。

まず、自分の構成は以下
~/.emacs.d/
   init.el
   /site-lisp

ホームディレクトリ直下の".emacs.d"配下に設定を集めています。
こうすると、設定がディレクトリごとコピーできるのでポータブルになるとWEB+DB vol.58に書いてありました。site-lisp配下には外から取ってきたemacs-lispをぽいぽい入れていきます。
# あ、そういえばこれ買いました。神本。


内容ですが、長いので3部に分けます予定です(いつまでに書ききれるか分からんけど)。
  • 第1部:イントロダクション、load-path設定等
  • 第2部:メジャーモード等設定
  • 第3部:文字コードとか見た目の設定とかこまいとこ

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; load-path

まずはload-pathに関する設定から。たぶんここの設定はみんな似たり寄ったりだと思う。
S式のままだと関数と変数をぱっと見分けられないので、javascript風に変換してみる。


↓↓


完全に見た目の分かりやすさだけのために変換します。
(dynamic scopeとlexical scopeの)変数スコープの違い等の言語的特質は無視で。
スコープの話はこの機会に少し勉強したので、また別途まとめたい。

1行目:let句でローカル変数"default-directory"に値を束縛する。束縛する値は、expand-file-name関数の戻り値。expand-file-name関数は、文字列が表すパスを絶対パスに置き換えます。let句の構成は以下になり、最初のvarlist-to-bindで、変数に値を束縛します。"(hoge 1)":hogeという変数に1を設定します!みたいな感じで。そして、その後にその"hoge"を使用した処理を書くスタイルになるかと思います。
(let varlist-to-bind body...)
今回のvarlist-to-bind(束縛変数リスト)はこの"default-directory"だけ。今回のケースだと2行目以降がbody(実行文)にあたる。

2行目:add-to-list関数でリストに値をいれてるんだけど、この関数は値の重複を許さないので、動きとしてはSetに値をぶっこんでいることに近い。"load-path"という変数に、さきほど束縛したdefault-directoryを挿入しています。"load-path"というのは、Emacs が*.el や*.elc(emacs-lispをバイトコンパイルしたもの)を探す順を指定するための変数です。シェル変数の$PATHのイメージ。load-path、いっぱい入ってます。
("/Users/hoge/.emacs.d/site-lisp" "/usr/share/emacs/22.1/site-lisp" "/usr/share/emacs/site-lisp" "/usr/share/emac\
s/22.1/lisp" "/usr/share/emacs/22.1/lisp/url" "/usr/share/emacs/22.1/lisp/textmodes" "/usr/share/emacs/22.1/lisp/\
progmodes" "/usr/share/emacs/22.1/lisp/play" "/usr/share/emacs/22.1/lisp/obsolete" "/usr/share/emacs/22.1/lisp/ne\
t" "/usr/share/emacs/22.1/lisp/mh-e" "/usr/share/emacs/22.1/lisp/mail" ...)

3,4行目:normal-top-level-add-subdirs-to-load-pathという(長い!)関数が存在するかを確認して、存在したら呼び出す。この関数は、ディレクトリを再帰的に探索し、見つかったディレクトリを load-path に追加します。

これで、"~/.emacs.d/site-lisp"配下に追加した*.elやら*.elcやらが読み込まれるようになるということですね。何気ない顔してコピペ、というのはいい加減卒業しないとなあという今日この頃。

続きは、(あるかもしれない)第二部で。

.emacs.d、Githubに置いてみました。
https://github.com/k-ori/emacs.d

# syntax-highlight、amazonのiframeのバナー張ると動かないのか!
# http://blog.heartofsword.net/archives/794

2012年1月8日日曜日

githubとの遭遇


// k-ori@github

下記を参考にしながら、Github初めて触ってみました(アカウントは前から持ってたけど)。
ナウなヤングのためのgithub入門講座 -基本機能からdotfiles管理まで-

watch機能とやらが使えるらしく、下記を検索してさがして、とりあえずwatchしてみる。書かれている通りに!
GitHub人気レポジトリランキング Best50 全解説

followもofficialチュートリアル通りにやってみる。書かれている通りに。マニュアル人間です。
「お前このページに来るとは、さては初心者だなー」とか「お前は、なんでこんなクールガイをfollowしないんだい?」とか言われながら(ニュアンスは妄想です)。
Help.GitHub - Be Social

あと、gitのpushまでのコマンドを忘れたとき用に、addからpushまでのコマンドをシェルにしてpush。
自分で自分をpushするシェルがfirst pushです。
addからpushまで一気になんて・・・とか細かいことはいいんです。自分で自分をpushしてみたかっただけなんです。

fizz-buzz challenge


以下の記事を読んでいて、初めて見る単語「fizzbuzz問題」。
Scala的な考え方 - Scalaがとっつきにくいと思っている人へ
こういうものらしい。

http://ja.wikipedia.org/wiki/Fizz_Buzz
プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3で割り切れる場合は 「Fizz」(Bizz Buzz の場合は 「Bizz」)、5で割り切れる場合は 「Buzz」、両者で割り切れる場合は 「Fizz Buzz」 (Bizz Buzz の場合は 「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者や、ためらった者は脱落となる。
このゲームをコンピュータ画面に表示させるプログラムとして作成させることで、コードがかけないプログラマ志願者を見分ける手法を Jeff Atwood が FizzBuzz問題 (FizzBuzz Question)として提唱した。その提唱はインターネットの様々な場所で議論の対象になっている。
また、実際に「制限時間2分以内」「剰余(%記号等)を用いない」「1行でできる限り短く(ワンライナー)」等の縛りでゲーム条件を満たすコード記述の腕試しをする者が続出した。

その場で、自分で書いてみたコードは以下。
工夫点は、「3で割り切れる」というロジックと「5で割り切れる」というロジックが重複するので、その結果をキャッシュしたというだけヽ(`Д´#)ノ

調べてみたら、"FizzBuzz" = "Fizz" + "Buzz"であることを利用して短くまとめている回答もメジャーのよう。javaだとこんな感じ。


しかし、圧巻はPerl。短いなあ。$_で直前に評価した値が参照できる点が効いてるのか。



以下のページがよくまとまってて、引用させていただいた。
Fizz Buzz Test

しかし、中にはスタックトレースでFizzBuggする変態さんもいるようでw


Javaでちゃんと数字も表示されるFizzBuzz書いた

Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at javaapplication1.FizzBuzzNewClass.main(FizzBuzzNewClass.java:18)
Caused by: java.lang.StackOverflowError

at 8911.fizzbuzz(FizzBuzzNewClass.java:80)
at 8910.number(FizzBuzzNewClass.java:32)
at 8909.number(FizzBuzzNewClass.java:40)
at 8908.fizz(FizzBuzzNewClass.java:58)
at 8907.number(FizzBuzzNewClass.java:34)
at 8906.buzz(FizzBuzzNewClass.java:75)
at 8905.fizz(FizzBuzzNewClass.java:56)
at 8904.number(FizzBuzzNewClass.java:34)

ちなみに、この記事Hacker Schoolには、FizzBuzzCodeを応募時に貼付けさせている。

このボリューム、間違いなく3日坊...

2012年1月7日土曜日

syntaxHighlighter so cool

また、blogを作ってみた。何個目だろう。 今回は、syntaxHighlighterを使ってみたくて、作ってみた。



シンタックスハイライト、かわいいな! あとは、3日坊主にならないようにモチベーションを維持するだけです。

メモ
http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/