2011年7月30日
iTunesでRestoreするiOSファイルを選択する方法
やった後、すぐ忘れる操作の覚え書きシリーズ。
Restoreボタンを押すときに、Optionキーも押しておく。
そうすると.ipswファイルの選択画面が現われる。
2011年5月 6日
Xcode 4
連休中にXcode 4を入れたのですが。
PowerPC版が作れなくなってる!
とうとう切り捨てられちゃいましたか。我が家のG5。
というわけで、Xcode 3.2.6を追加インストール中。
2010年11月20日
Provisioning Profileの期限切れ更新操作方法
iOSアプリ開発用のProvisioning Profileが期限切れになった(なりそうになった)ときにいつも操作方法で悩む(前回どうやったか忘れてる)ので,3ヵ月後の自分に向けてメモ。
Profileの一覧画面で,更新対象のProfileの「Edit」→「Modify」を選ぶとプロパティ表示になるので(特に変更がなくても)「Submit」。
一覧画面では「Active」→「Pending」になるけど,1分ぐらいして表示更新すると再び「Active」に戻るので,「Download」で.mobileprovisionをダウンロードして,Xcodeにドラッグ&ドロップ,で完了。
2010年10月31日
iPhoneのキーボードを消すバー
Kautandeを使っていると,iPhoneのキーボードが消えなくなることがあります。
SDKドキュメントを見ると
Depending on how you configured the keyboard, you might need to add some additional controls to your user interface to facilitate the keyboard's dismissal.
プログラマがどのように設定するかにもよるが,もしかしたらキーボードを消すのを手助けする追加コントロールをユーザインターフェイスに加える必要があるかも知れない。
なんてことが書いてあるのですが,ナビゲーションバーに付けるとかもスペース的に苦しいし,テキストビューの上部・下部というのもいただけない感じ。
その辺に無理矢理追加するんじゃなくて,Safariでフォーム入力しようとすると現われるキーボードに付いている,あのボタン群。あれが欲しいというわけです。
それで,以前から,このボタン群,何とかして手に入んないかな〜って思っていたんです。
今日,ふと,改めてよくよく見てみると,キーボードの上部に完全に外付けのようなんですね。一緒にスクロールしてくるんでキーボードが拡張されているのか何かなのかと思ってましたが。
で,それだったら何かそれっぽいことが出来るんじゃないか?ということで,やってみました。
UIToolbarを用意して,UIKeyboardWillShow(&Hide)Notificationを受け取り,UIViewのanimationWithDuration系の処理で動かす,というようなものになります。
キーボードが下からスクロールしてくるのに合わせて,バーが上がってきますし,本体の回転にも追従します。
サンプルアプリのソースコードを置いておきます。
この中に入っているDismissKeyboardPadというクラスをアプリの先頭あたりで,[[DismissKeyboardPad alloc] init]; するだけで,すべてのテキスト入力部分にこのバーが付くようになります。
実際には,すべての箇所でこのバーが付かなくても良いケースもあるとは思いますが,参考にはなると思います。
1点だけ課題があって,それはキーボードが表示されるタイミングが,アプリ起動直後の1回目だけ遅く,それ以降は早い,ということで,そのせいで1回目だけ,ツールバーの表示タイミングがキーボードの表示タイミングとずれます(delay:0.0001fは,そのためのあがきです)。
WillShowではなくDidShowで引っかけた方が良いのかも知れません。
2010年10月27日
iOS4とDatePicker
忘れないうちにメモ。
DatePickerの初期化というか「今日」の設定を,例えばviewDidLoad:なんかでやっている場合,iOS4のマルチタスクに対応するとサスペンド〜レジュームの間に日付が変わることも充分あり得るので,「今日」が指している日付が当日とずれてしまいます。
かと言って,使っている最中に日付が変わった場合は,それに追従して「今日」が指す日付が変わると使い勝手が悪くなったり,ややこしいことになる可能性もあります。
レジュームのイベントを拾って設定し直す,というような処理が適切なのかも知れません。
2010年8月18日
続:iTunes ConnectのPrimary Languageの件
primary languageは,変えることが出来ないようなのです。
ところが,私のアプリは,いま,Jamaicaストアで英語で表示されるようになっているのです。もちろんprimary languageは日本語です。つまり,これは何か,そういうことをする方法がある,らしいのです。
次のエントリでは,そもそもいまどうなっているのか,何をやったらそうなったのか,「いまの状態」と「やったこと」「やってないこと」を整理したいと思います。
遅くなりましたが,これについて,まとめました。
まず,実際の表示がどうなっているかを表にまとめたのが以下になります。
サンプルの「TLogic.de」さんや「Apple」,「KatokichiSoft」さんのprimary languageがこの通りかどうかは確実ではないのですが,おそらくそうだろう,ということで挙げさせてもらっています。
| primary language | アプリに用意されているLocalizationバンドル |
対象App Store | 対象App Storeでの表示(文言・スクリーンショット) |
iTune Storeでの表示サンプル |
|---|---|---|---|---|
| 英語 | English.lprojのみ サンプルは「TLogic.de」さんの 「Magic Lights FREE」 |
日本 | 日本向けにLocalizationで追加していれば日本語,そうでなければ英語(primary language) | http://itunes.apple.com/jp/app/magic-lights-free/id370836315?mt=8 |
| iTunes ConnectでLocalizationの用意されている国・地域 | それぞれの国・地域向けに用意したもの | http://itunes.apple.com/de/app/magic-lights-free/id370836315?mt=8 | ||
| その他の国・地域(Rest of World) | 英語(primary language) | 基本的にUSの表示と同じ http://itunes.apple.com/tw/app/magic-lights-free/id370836315?mt=8 |
||
English.lproj+Japanese.lproj サンプルはAppleの「Remote」 |
日本 | 日本向けにLocalizationで追加していれば日本語,そうでなければ英語(primary language) | http://itunes.apple.com/jp/app/remote/id284417350?mt=8 | |
| iTunes ConnectでLocalizationの用意されている国・地域 | それぞれの国・地域向けに用意したもの | http://itunes.apple.com/de/app/remote/id284417350?mt=8 | ||
| その他の国・地域(Rest of World) | 英語(primary language) | 基本的にUSの表示と同じ |
||
| 日本語 | English.lprojのみ サンプルは「KatokichiSoft」さんの「Metronome PRO」 |
日本 | 日本語(primary language) | http://itunes.apple.com/jp/app/metronome-pro/id336335772?mt=8 |
| iTunes ConnectでLocalizationの用意されている国・地域 | それぞれの国・地域向けに用意したもの | http://itunes.apple.com/de/app/metronome-pro/id336335772?mt=8 | ||
| その他の国・地域(Rest of World) | 英語(English) | http://itunes.apple.com/tw/app/metronome-pro/id336335772?mt=8 | ||
English.lproj+Japanese.lproj サンプルは「KatokichiSoft」さんの「Mosquito Attack」 |
日本 | 日本語(primary language) | http://itunes.apple.com/jp/app/mosquito-attack/id310403489?mt=8 | |
| iTunes ConnectでLocalizationの用意されている国・地域 | それぞれの国・地域向けに用意したもの | http://itunes.apple.com/de/app/mosquito-attack/id310403489?mt=8 | ||
| その他の国・地域(Rest of World) | 日本語(primary language) | http://itunes.apple.com/tw/app/mosquito-attack/id310403489?mt=8 | ||
ワタシの場合 |
English.lproj+Japanese.lproj サンプルは「Shaka! Lite」 |
日本 | 日本語(primary language) | http://itunes.apple.com/jp/app/shaka-lite/id289913594?mt=8 |
| iTunes ConnectでLocalizationの用意されている国・地域 | それぞれの国・地域向けに用意したもの | http://itunes.apple.com/uk/app/shaka-lite/id289913594?mt=8 | ||
| それぞれの国・地域向けに用意していない場合は日本語(primary language) | http://itunes.apple.com/de/app/shaka-lite/id289913594?mt=8 | |||
| その他の国・地域(Rest of World) | 英語(English) | http://itunes.apple.com/tw/app/shaka-lite/id289913594?mt=8 |
基本的なルールは「iTunes ConnectのLocalizationで特定の国・地域向けに説明文・スクリーンショットを用意した場合は,その国・地域ではそれが使用されるが,それ以外ではprimary languageで表示される」と考えられますが,オプション的なルールがあるようにも見えます(色を着けてあるところ)。
で,結局のところ,primary languageが日本語でも,Rest of Worldで英語が表示されれば(=緑色のセルのところのようになれば),Localizationをしないといけない(=黄色のセルの状態になっちゃうので)という手間の問題は残るものの,大きな問題(Rest of WorldのApp Storeで日本語が表示されること)は回避できることになります。
「ワタシの場合」という行を見ると,それができています。なぜできているのか?
2008年の10月頃に,iTunes Connectから以下のようなメールをAppleに送っています。
I want to change my primary language for App Store (from Japanese to English).
I know that no method is prepared in iTunes Connect.
Is there another way to change it?
その後,色々情報を聞かれて答えたところ,
Thank you for your reply. We are currently reviewing your inquiry and will get back to you very soon.
というメールが来ました。ところが,これで変わったことは何もなかったのでした。
2009年の10月頃に再度フォローのメールを出したところ,お詫びの後に以下のように書かれた返事が来ました。
For further assistance with this inquiry please visit the FAQ in iTunes Connect and refer to the Localization section.
primary languageを変えてくれ,というお願いに対しては何も変わってなかった(Add New Applicationで追加したとき,Japaneseで入力しろ,と言われる)ので,何かシステムが変わったのか?という程度しか気にしていませんでした。
そして,2010年5月,新しいアプリがReady for SaleになったのでRest of Worldでの表示を確認してみましたが,やはり日本語で表示される。試しにShaka! Liteを見てみると,こちらはなぜか英語で表示される。アプリケーションごとに表示が違うのでした。
早速,今までのメールを引用しつつ,以下のようなメールを送りました。
There is NO localization (Additional Language) for Jamaica store, so I want to provide English description for my application.
Is there a proper way to do it?
返信は以下のようなものでした。
Please refer to the iTunes Connect User Guide for information regarding localization.
If you suspect your account is not working properly, please send an email to the appropriate team via the Contact Us section.
しかしながら,このそっけない返事とは裏腹に,Jamaica(すなわちRest of World)での表示は英語に切り替わりました。
ここからは推測ですが,
- 各アプリごとに,各国向けApp Storeでどの言語の文言・スクリーンショットを使うか,管理されている(アプリのバイナリやiTunes Connectでいじれる部分以外のところでAppleが管理)。
- primary languageは,1.のデフォルト値として扱われる。
- メールを出すと,手動で1.の値を書き換えてくれる。
- 次にアプリをリリースしても,primary languageが変わってはないので,もう一度手動で3.をしないとダメ。
お困りの方は,一度,メールを出してみるのが手かも知れません。
というか,primary languageを変えられるようにして欲しい,というか,実行ファイルのバンドルを見て表示を切り替えているぐらいなら,CFBundleDevelopmentRegionとか,何か新しいキーを追加するとかして,実行ファイル側で切り替えられるようにしたらいいのに,って思います。
ウェブログ: てぃーのiPhoneアプリ開発 : 2011年10月15日 00:30
2010年5月30日
iTunes ConnectのPrimary Languageの件
iTunes Connectでは,Localizationのタブで追加した言語の対象国以外のApp Storeでは,primary languageで表示される,という仕様があります。
そして,primary languageはiTunes Connectにアカウントを作ったあとの最初の1回のみしか設定できず,後から変更はできない,という制限があります。
また,Localizationのタブで,追加登録するにしても,当初の10カ国語ですら大変でしたが今のように18言語あると,かなり大変。特にコピペで済む説明文はともかく,スクリーンショットのアップロードし直しがかなり面倒です。
しかもLocalizationのタブで登録できるのは,まだ18言語だけで,そこで追加登録した言語が使われる対象国も少ないのです。この文章を打っている2010年5月末の段階で,iTunes Storeは90カ国版があり,18言語が使われる国は多めに見積もっても50カ国程度でしょうから,残りはprimary languageで表示されるのにまかすしかない,という状態です。
例えば初回登録時にprimary languageを日本語にしてしまうと,「Jamaica」のような国のApp Storeでは,日本語でアプリの説明が表示されることになります。Jamaicaにおける英語の通りやすさと日本語の通りやすさを比べれば,当然英語で表示したいところですが,そうは行きません。
で,今まで色々調べましたが,このprimary languageは,変えることが出来ないようなのです。私もこんなネタを書くくらいなので日本語で登録してしまったクチで,非常に困っています。
ところが,私のアプリは,いま,Jamaicaストアで英語で表示されるようになっているのです。もちろんprimary languageは日本語です。
つまり,これは何か,そういうことをする方法がある,らしいのです。
ところが私自身,何きっかけなのかが今ひとつよく分かってない,というのが問題です。
次のエントリでは,そもそもいまどうなっているのか,何をやったらそうなったのか,「いまの状態」と「やったこと」「やってないこと」を整理したいと思います。
2010年4月16日
iPhone SDKの例の改訂の件
色々盛り上がっています。
ジョブズ、iPhoneアプリの開発制限について直メールで回答の記事が一番,事実に近づいている,と思ってて良いんでしょうか。ジョブズとのメールのやりとりも載ってますし。
...って思ってて外れるってのがよくあるパターンです。
ともかく,色んなところで想像されているAppleの意図っていうのをまとめると,
1)メタプラットフォームを禁止したい。iPhone上で動く中間レイヤーができれば,そこにApple以外のApp Storeを作られてしまう可能性すらある。
2)iPhoneのユーザ体験をExcellentな状態に維持したい。中間レイヤーを使ったアプリはクソが混じることが多い。
だいたいこの2つなんですかね(もちろんAdobeがキライとかっていう話は除いて)。2)の延長線上にAndroidとの対比の話もある,ってぐらいで。
言い方の問題なんでしょうが「クソが混じることが多い」って話になると,中間レイヤーを使っている人たち/作っている人たちは腹立ちますよね...ってクソが混じるって言ったのは私ですか。済みません。
Human Interface Guidelineに沿う,ってのがあるべき姿だと思っていますし,モバイル機器なのでリソースも少ないってのを考えると,2)に対するAppleの懸念ってのはなんとなく分かります。特にMac時代のようにMac好きだけが開発をしている時代ではないですから「ユーザビリティ?関係ないぜ!生産性向上!原価低減!それこそがIT企業の経営だぜ!」みたいな人も多いでしょうし。
(もちろん,生産性向上と原価低減を軽視するわけではないです)
そうは言っても,最近のAppleはユーザ/開発者の過去の投資をちょっと軽視しすぎてる感,振り回す感はあります。どうだクールだろ?!ってのは分かるんですが。
規約を作ることで開発者にそっぽを向かれることも覚悟の上での決断でしょうから,こうなった以上はiPhone好き,Apple好きな開発者がより多く生まれるようなプラットフォームでありつづけることを期待します。
(私のiPhone 3Gは遅すぎるので速くして欲しいんですけど)
2009年10月18日
App Storeでシェアウェア方式ができるようになる件
金曜にメールを受信したらAppleからメールが来ていたわけです。
(特に個人でやる場合には)課金制って大変,ってことで,ろくに興味もなかったIn App Purchaseですが「Lite版を作らなくてよくなるよ」って言われては,調べようという気にもなろうというもの。
月額課金の話がHMDTさんのとこに色々書いてあったけど,そういうレベルじゃなくて,単に「30日無料で使えるから気に入ったら買ってね」方式も,今まではできなかったので,もしかしたらそれが実現できそうです。
結局,カジュアルハックの問題は残りますし,もしかしたら,いくら無料とは言え,30日経ったら使えなくなる,という形式をApp Storeの審査が許してくれないのでは?という不安はありますが。
こんにちは。
コメント欄から失礼致します。
神奈川在住の31歳男性です。
ひとつ質問させて頂いてもよろしいでしょうか。
現在、Late2008 MacBookPro 15" SnowLeopardを使用しており、
以前、kabeya様が作られていた「GlueWindow」のようなアプリを探しているのですが、
なかなか見つからないでいます。
そこで質問させて頂きたいのですが、
GlueWindowをOSX用に開発する予定はありますでしょうか?
または作成して頂く事は可能でしょうか?
個人の為の制作は現実的ではないと思いますが、
シェアアプリとして公開いただきましたときには、
1000円〜2000円であれば、是非購入させていただきたいと思っております。
ご一考いただけると幸いです。
突然のコメントにて失礼致しました。
よろしくお願い致します。
DENさん,こんにちは。
ずいぶん前に「Finderのウィンドウ」という記事を書いています。
SnowLeopardはFinderがCarbonからCocoaベースになった,というような話を聞いたような聞かなかったような気がしますが(最近,うとくてすみません),ウィンドウの位置は保持されているんでしょうか。
どちらにしても,あと何ヶ月かは相当忙しいのでアレですが。
投稿者: kabeya : 2009年11月24日 05:162008年11月12日
あなたの会社が中期計画を達成できない理由
どこの会社でも,あるいはちっちゃな部門でも,およそ業績目標値ってのは持っていると思います。今期の目標値以外にも「第n期中期計画」みたいな感じで,3〜4年ぐらいのスパンの計画もあるんじゃないかと思います。
これって皆さんのとこではどのように扱われているのでしょうか。
本筋に入る前に,ちょっと事前の整理ですが,皆さんは「見積もり」という言葉,特にプロジェクトにおける期間や費用の「見積もり」をどう捉えているでしょうか。
見積もる,というのは,ワタシのMacに入っている国語辞書によりますと
み‐つも•る【見積(も)る】
〘動ラ五(四)〙
1 目分量や心づもりではかっておおよその見当をつける。目算する。「入場者数を--•る」
2 工事や製品などの、原価•日数•経費などを前もって計算して出す。「経費を--•る」「工事を--•る」
と書いてあります。
しかし,2の「原価•日数•経費などを前もって計算して出す」というのは不正確です(「出す」って何だろう,というのは置いても)。もし本当に原価・日数・経費などが計算できるのであれば,それは「見積もる」というよりは「精算する」です。
見積もりは「原価・日数・経費などが,どれぐらいまでなら自分が耐えられ,かつ顧客も耐えられるか」について,おおよその見当をつけることです。原価・日数・経費そのものについて見当をつけて「見積書」を出しているわけではありません。
「見積書」は「計算書」とは異なり,報告をしているのではなく,「約束」をしているのです。約束なので,仕方ないと認めてくれるような合理的な理由が発生しない限り,見積書の内容は守るのが原則です(IT業界では,その「合理的」の扱いで色々もめるわけです。かくいうワタシも,叩かれるとホコリが出てしまう身ですが...)。
この辺りの話は「ソフトウェア見積り 人月の暗黙知を解き明かす」が詳しいので,まだ読んでない方はぜひ読んでみてください。
さて,プロジェクトの見積もりです。
ワタシのようなソフトウェア系の人は経験的によく知っているし,前述の本にも書いてある話ですが,「プログラマに見積もりを依頼すると(なぜか)最良値に近い値を出してしまう」という法則があります。
特に細かく分けて見積もりをすると,すべてが最良値で出てきてしまい,それらを積み上げると大変「良い」,つまり「安くて早くて品質の良い」見積もりになってしまいます。
しかし,その見積もりはすべてをぬかりなく,かつ運良く進められた場合にのみ実行可能な値です。ちょっとした前提の狂いやトラブルで大きく外れてしまうことがあります。
そうした「最良値の積み上げ」を防ぐため,プロジェクトマネージメントの本や講習では「3点見積もり」が薦められています。
つまり,細分化した個々の範囲を,最良値・最尤値(最ももっともらしい値)・最悪値の3点で見積もり,トータルとしては最悪どれぐらいか,最良でどれぐらいか,最もあり得そうな値はどれぐらいか,を計算します。そして,最良と最悪の間を小さくしていくためにどんな情報や対策が必要かを検討し,できることを順次やっていきます。
この3点から1点の値を出す方法については,いろいろな考え方・やり方があると思います。前述の本などを参考にしてみてください。
と,ここまでが見積もりの話です。
そしていよいよ本題の中期計画です。
皆さんのところでは中期計画は「目標」でしょうか「約束」でしょうか。
ワタシは,もし中期計画が守られるべきものであれば,やはり「約束」として考えるべきだと思います。
そして「見積もり」と同じく,充分推測可能な範囲にまで細分化して,3点で値を見積もるべきではないでしょうか。下のレベルから上のレベルに「計画値」として1点あげる場合も原則は3点出し,上のレベルでもやはり3点で集計した上で1点に絞るべきではないでしょうか。
例えば,不確実性の高い新規事業と,ある程度安定している過去からの継続事業では,同じ1点だけ上がってきた数値だと言っても,信頼性が異なります。これらを1点で積み上げていくと,いくら個別の事業レベルでは3点見積もりをしているとは言え,全事業トータルとして信頼性の高い「約束」ができるとは言えないと思います。
エイヤ!で出した突拍子もない数値を「元気がいい数字だな,おい」みたいな呑気なことを言っているようだと,おそらくその数値は守られないんじゃないかと思います。
裏付けのない「元気がいい数字がほめられる」風潮は,場合によっては「計画は守らなくてもOK」「深く考えずに数字を出してもOK」という考えにつながったり,「どうせ結果は同じなんだから,ほめられた方が得」というなんだか訳の分からない理屈につながったりするのではないかという気がしています。
「元気のない,小さくまとまった数字のほうが良い」と言うつもりは全くありませんが,どの数字がある程度読めてて,どの数字のチャレンジ度が高いのかは,ちゃんと把握しておく必要があると思います。
ちなみに中期計画が「目標」となってしまっていて,「約束」と言えるのは「予算」だけというようなところは,目標の実現に向かって「計画」を立てる必要があると思います(中期計画なんだから「計画」でないと困ります)。そして計画を実行しつつ見直しつつ,目標を実現していくべきと思います。
計画と言いながら,施策が「〜の検討」とか「〜の強化」程度の,あまり具体性のない「掛け声」だけで埋まっている中期計画だったりすると,やっぱり「目標」のままで終わってしまうのではないでしょうか。
必要な費用・期間・体制・資源と得られる効果を(誤差は大きくても)見積もり,それぞれの信頼度を3点で評価していく,そして,常に信頼度を上げる努力をして,値を見直していく,ということが重要な気がします。
などと偉そうに書いちゃいましたが,言うほど簡単にはできないのも確かで,会社の人にこの文章を読まれたら「お前はできとらんやないか」ってツッコミで大変なことになります(書かなきゃいいんですが)。
2008年11月 3日
UITabBarControllerと初期化
ハマったので,メモしておきます。
UITabBarControllerはInterface Builderで設定できますが,この場合,UIViewController(の派生クラス)のinitWithNibName:bundle:は呼ばれず,initWithCoder:が呼ばれます。
ドキュメントにはinitWithNibName:bundle:をオーバーライドしろ,と書いてあるけど,それはコードでUITabBarController/UIViewController(の派生クラス)を構築する場合。
使い方が両方考えられるような場合は,別の初期化メソッドを用意しておいて,initWithCoder:とinitWithNibName:bundle:の両方から呼び出すようにしておいたほうが良いのかも知れません。
2008年10月22日
NDAが解除されるのか?の件
within a week or so ってことなので,なんか下書きでもしときますか(つって何もしないというのがありがちなパターンだけど)
なげぇ1週間だ。
でもってやっぱり何もしてないけど。
2008年10月21日
App StoreのNewに載ってる件
どういう基準なのか,てんで分からないんだけど,App Storeの「New」にShaka! Liteが載ってる。
ダウンロード数のレポートを見ると,10/14までは100〜200で推移してたのが,10/15以降800〜1000になったので,10/15に掲載されたみたい。
てゆうか,リリースから1ヵ月経って「New」に載るってのは,ユーザさんには申し訳ない気がする。
反面,もしこれが有料アプリで,仮にワタシがそれで生活をたてようとか,会社を立ち上げようと考えていたなら,1ヵ月経ってリリース日順では3〜4ページ以降になってしまうこのタイミングでの引っ張り上げは,非常に非常に嬉しく思えるはず。
基準がもう少し明確だともっと良いはずなんだけど...。
2008年10月 3日
App StoreはKagi.comではない?
なんだろう,おそらくは(自分自身を含め)開発者側の認識不足から来ているんじゃないかなーって思う。
上記の続きなんだけど。
App Storeに並んでいるアプリというのは,たぶんシェアウェアとは違うものなんじゃないか(主に開発側にとって)。
PCでシェアウェアを(お金を払って)使うユーザとApp Storeでアプリを買って使うユーザは,おそらく相当ユーザ層が異なる。それぞれのユーザが,お金を払ったアプリに対して期待するレベルというのも,多少は違うんじゃないかなと思う。
何より,1曲200円で提供されているプロの楽曲と簡単に費用対効果が比較されてしまう。
現在,開発者の参入が相次いでいるが,いずれは淘汰が進む。「くだらないアプリでもうかったとしても,それは初めだけ。開発者は,ここからどうやって頭一つ抜け出すかを考える必要がある。ユーザーは品質にはシビアだ」(ユビキタスエンターテインメントの清水社長)。
ワタシは,淘汰は進まないと踏んでる派で,くだらないアプリはずっと生まれつづけ,そしてくだらないアプリでもうかる人はいなくなんないような気はしてるんだけど,最後の「ユーザは品質にはシビア」には同意(←えらそうに)。
そんなこんなで,App Storeにアプリを並べようと思ってる開発者は(特に,今まで「良かったら使ってみて感想聞かせてよ」的スタンスでオンラインソフトを公開してきた人は),「ユーザは品質にはシビア」ってのを意識しておくと,リリース後のモチベーションが保ちやすいんじゃないかなって。
フジモトさんの「プログラマを笑え」という本に「気に入らなくて読まないのはそっちの勝手だが,わざわざそれを知らされると気分が悪い」的なことが書いてあったけど,「気に入らねー」ってコメントも多いから,うっかり読むとガックリしちゃうこともある。
だからってマイナス意見をなるべく書いて欲しくないってことでもなくて,「こういう場合に動きません」とか「反応がイマイチ」「音がウソくさい」「音量が調整できないのが×」など,こう,開発者として(耳は痛いけど)役に立つマイナス指摘というのもあるわけで(これもフジモトさんの本にも書いてあった話だ),だから1つ星とかの低い評価もユーザだけでなく開発者にも有用なレビューだと思うし,読まないワケにもいかない。
オンラインソフトを配布してて,こういうレビューシステムがどっかに集約されてることなんて他にないから,普通はスーパー有名なソフトでもない限り「気に入らねー」レベルの意見が耳に入る(目につく)ことはないんだけど,App Storeはあり得る。というかめちゃめちゃありまくる。
とにかく,App Storeからはいろんな意味で目が離せませんな。
Wii Musicの件
スーパーマリオの開発者としても知られる任天堂 専務取締役の宮本茂氏が、10月2日に開かれた同社のイベント「任天堂カンファレンス2008秋」において、自身が手がけたWii向けの新作ゲーム「Wii Music」を実演して見せた。その様子を動画で紹介する。
CMで見て「うぉー!」とか思ってたワケだけど,これ,上達するとちゃんと狙った通りに曲が弾けるようになるんかね。
App Storeで,Musicカテゴリのアプリを見ていると,レビューに書いてあることって「開発者の思惑とは(おそらく)違うだろう」って思うことが多い。
それは「本当のギターのようには弾けない」あるいは「ドラマーに言わせると...」というような指摘。
この類いの指摘が非常に多いのは,なんだろう,おそらくは(自分自身を含め)開発者側の認識不足から来ているんじゃないかなーって思う。
音系アプリにユーザが期待するのは「練習したら上達すること」なんじゃないのかしら。もし音系を目指すなら,楽器系かそうじゃないのかをユーザに対して明確に示しておく必要を感じる。
もし仮に,リモコン振ったら鳴るだけ,あんまりコントロールできず上達しないってのだったら,AustraliaのApp StoreのShaka! Liteに対するレビューにある「Pretty funny app, useless but good for a few laughs」(かなりバカバカしいアプリ,役に立たないけど,薄ら笑いを浮かべるのにはいい)という指摘がまんま当てはまってしまう。もちろん,我ら(誰らよ?)が任天堂のやることなので,そんなはずはないとは思ってるけど。
しかし「useless but good for a few laughs」は,皮肉にして言い得て妙,それこそ「うまいことゆうたな」という気がしますな。
2008年10月 2日
NDA解除の件
やっと。
within a week or so ってことなので,なんか下書きでもしときますか(つって何もしないというのがありがちなパターンだけど)。
あと,気になってるのは,逆の文言ね。
「unreleased software and features will remain under NDA until they are released.」
むしろ今まではunreleased software(8月中頃時点に置き換えてみると,iPhone OS 2.1に相当)って,こっちはどういうものなのか,いつリリースされるのか知らんかった訳でね(2.1リリース前,むしろ2.0.2ですら動作確認してなかったShaka! Liteが2.1でも動いてよかったよかったてなもんで),むしろunreleased softwareのほうは,NDA付きかつ有料subscriptionデベロッパ限定とかで全然かまわないので早めに教えて欲しいって思いませんかそうですか。
まあ有料の場合,そのプログラムがいくらなのかによってワタシのような日曜プログラマも遊びに加われるかどうか決まるワケだけど(飲み代1〜2回分ぐらいを希望)。
2008年9月22日
加速度センサって何を測ってるの?
こう,加速度センサを使ったソフトをリリースしておいて何なんだって感じだけど,いったいiPhoneの(まあWiiリモコンでもいいんだけど)加速度センサっていったい何の加速をはかってるワケ?
iPhone本体を停止(あるいは等速運動)させていても,加速度センサは1.0Gを示すのね。っつーことは,加速度センサが測っているのは,本体の加速度ではないワケ。
また,下に振ると重力と逆方向に加速度値が変化する。
いったい何の加速度なの?
ってことで調べると,
iPhoneの中にある加速度センサーは、シリコンの重り、これを支えるシリコンのばね、そして電流という3つの要素を利用したもの。
って書いてある。そういうことか。
加速度センサが返す値は,おもりに繋がっているバネの長さ,ということなのね。おもりの加速度ですらない。測っているのは「加速度ではなく,バネの長さ」。
おもりに働く力とバネの力が釣り合うあるところを測っているので,確かに加速度を測っているんだけど,実際にはiPhoneもおもりも加速はしてなくても値は出る。
バネの長さだから,iPhoneが停止していてもセンサ値として1.0(または-1.0)が返る。
静止状態から重力方向に振ると,おもりは慣性によって静止したままでいようとするけど,おもり以外の部分(iPhone)は下に向かうので,おもりとiPhoneの距離=バネの長さは縮み,センサ値は1.0より小さくなる(速ければ,どんどん小さくなっていってもっと速ければ0を超えて逆の符号になる)。
ただしそのうち,どこかでおもりもバネに引っ張られて下に動き始める。
振り下ろすのをやめる(iPhoneを止めようとする)と,iPhoneは止まるけど,おもりは慣性によりまだ下に動こうとして,今度は重力方向にどんどんバネが伸びる。で,重力と同じ方向にセンサ値がどんどん増加する。
で,どこかでバネに引っ張られる格好で止まって,上に戻り始める。
バネなので,戻るときに戻りすぎるはずなんだけど,このセンサ,ほとんどその振り戻しがないのね。そうでないと困るんでいいんだけど,なんでだろ。おもりが軽い,ということもあるんだろうけど,その割りにはセンサが鋭敏。粘性の高い液体か何かで埋めてるんだろか。
2008年9月16日
App Storeのカスタマレビューについて
今回 Shaka! Liteをリリースして,特に思ったのが,最初につくレビューってすんごく大事だなってこと。
msk2さんの的確なコメントのおかげで,なんつーか,いい感じにきてます。
USのほうの,HugoisPianoRockさんのコメントも,いい感じです。
決して星が多いわけではないんだけど,こう,アプリを育てようってのが伝わります。
あとは,それについて,技術的なコメントなんかが書けるといいんだけど...。
NDAってどうなるんでしょ。
2008年9月15日
App Storeに並べてもらってみて。
App Storeでコメントというかレビューが付くのが楽しい。
で,ついつい他の国では何言われてるんかな?つって,各国のApp Storeをのぞいててのけぞった!
iTunesConnect登録時の言語が日本語になっていると,App Storeでは日本語で表示されるのね。ほんでもって変える方法がない!
しかたなしに各国向けにローカライズ(というか各国語のローカライズページに英語で書込)するんだけど,韓国語とかローカライズできない言語もあって,なんだかなと。
Info.plistにデフォルトの開発ロケールがあるので,それを見てくれれば良いような気がするんだけど(ってShaka! Liteを確認したら日本語になってた!←あかんやん)。
他の国のApp Storeのコメントも,「英語で表示されるぞ!」みたいなのとか,結構,言葉の問題に関連するコメントが多いので,世界で公開するには,なんつーか,自分とこでのテスト+iTunesConnectでの設定確認が重要ですな。
日本語で登録しても,プライマリ画像には(もし世界中での配布ってのを優先させたいなら)日本語がない画像を登録するほうが良いような気がする。
しかし,いったんiTunesConnectにデフォルト=「日本語」で登録しちゃった場合は,どうするんだろ。改善されるのを待つのか。
2008年9月12日
パクる人2
以前にXO: パクる人ってエントリーで,オープンソースのソフトウェアをほぼそのまんま自分のソフトとして公開する人に「なんなんだ」って突っ込んだけど,最近(ま,ちょっと前だけど)iPhone SDKのサンプルコードをそのまま公開している人がいて,なんなんだと。
それは「Metronome」「Crash Landing」などを公開しているMarketWall.comという人(会社か)。
SDKをダウンロードした人なら,同じく公開されている水平器も思い当たるはず(こっちは見た感じ,相当改悪されてそうなので問題なさそうだけど。要は,MetronomeもCrash LandingもA Free Level[=BubbleLevel]もSDKに入ってて,App Storeで公開される前から知ってるわけで)。
Metronomeで思ったのは
- それでも一般ユーザからの評価は高い
- つーことは,Appleのサンプル自体はよくできている
- メトロノームは色々出てて,もちろん,このサンプルをベースもしくは参考に作られたと思われるんだけど,一般ユーザはベースとなったMetronomeを知らない
- Apple自体が公開しておいても良いのでは?
あたり。
SDKのサンプルが単に公開されてるってだけでなくて,ちゃんとAppleのレビューを経てApp Storeに並んでいるっていうのが,すごく不思議。
確かに以前ワタシが翻訳した「Appleのサンプルプログラムに付いているライセンス条項(和訳)」と同じ条項がついているので,ちょっと変えて再配布するのには「Apple」の名前を出さなくていいんだけど。
好意的に解釈すれば
- AppleがMetronomeを公開しないのであれば,俺が公開してやる
- でもApp Storeに並べるには,最低でもApp Store配布用のProfileをかます必要があり,そうするためには,自分のプロファイルをプロジェクトファイルに追加する(そのままでは配布できない)
- 改変がなければむしろApple Softwareだと明記できるが,多少なりとも改変する以上,Appleの許可なく配布はできない
じゃ,しょうがないのかね,となるけどね。
2008年9月 8日
App Storeでリジェクトされる
App Storeにアップロードしてたんだけど,今朝リジェクト通知があった。
てゆうか,日曜日にレビューということで,ご苦労様です→Appleの皆様。
リジェクト内容は,完全にこちらのミス,しかも単純ミス。
ほんとに済みません。
さっそく修正版をアップロード。
アップロードは日本時間の31日朝早く(30日の深夜)だったので,レビューまでちょうど1週間ぐらい待つ感じなんかな。
次はどれぐらい待つのかな,と。
2008年9月 4日
App Storeアップロード後は?
App Storeアップロード後,In Reviewのまま4日ほど過ぎた。
テストとかしてるはずなんだけど,どうなってるのか分からんのでつらいですな。
1つ思ったのが,サポート用のWebページが作ってあるんで,それのアクセスログを見て,誰か自分以外の人がそこにアクセスしてる気配があれば,ほんとにテストに入ったんだと分かるんじゃね?ってこと。
さっそく見てみたけど,自分ばっかり。
まだテストに入ってなさげ。
で,Softbank MobileのIPアドレスって,panda-world.ne.jpってなるのね。
2008年9月 1日
App Storeに登録挑戦中
とりあえず無料アプリをApp Storeに登録(アップロード)。
これからAppleでレビュー(テスト)されてから公開される,はずなんだけど。
どれぐらいかかるのかしら。
有料アプリにも挑戦したいけど,税金の手続きやら何やらでめげそう。
2008年8月13日
とりあえず最初のアプリ
簡単な既存の自作アプリをベースに練習ってことで,まずはiPhone版利息計算機が動くところまでできました。
英語環境と日本語環境で表示名や通貨単位が変わるというところまでやって,いったん終了。App Storeに並べるような代物でもないので,自分のiPhoneだけにインストール(使う場面はほとんどないんだけど)。
先週末の本体交換の件,まだ原因は分からず。
実はその前の日に,SDKのサンプルアプリをビルド&インストールしてみて,丸1日普通に使ってたんだけど,そんときは何もなかったのね。
App Storeからダウンロードしたアプリをインストールしようとしたら,再起動がかかってディアクティベートされた。
分かった(分かっている)ことは,
1)iPhone本体のUDIDが変わった(何かのハック対策?)
2)ソフトバンクショップにもiTunes以外のツールがない
サンプルアプリの作り方(とかインストール方法)が悪かったのかも知れないってことで,うっかりまたディアクティベートされちゃわないか,おそるおそる開発中。
自作アプリのせいでディアクティベートされるのか?ってADCのTechSupportにメールを出したところ,「何が起こったのか特定しかねますが,開発をするうえで頻繁にバックアップするのは必要な心構えです」とのお言葉。
この答えから推測するに,アプリのビルド/設定/インストール方法などが問題でディアクティベートされる,というのは基本的には予期されてない事態,ということでしょう。
なんつーか,アップルの(サポートの)人も,ソフトバンクの人も,我々のような日曜プログラマも(もちろん本職プログラマも?),なかなか大変です。
2007年11月 4日
再:CarbonかCocoaか?
HMDTさんのところに,
Mac OS Xでもっともよく使われるアプリケーションは、Carbonです。
というのがあって,「cocoa carbon」でググってみると自分の書いた以下のエントリがWikipediaの次につける始末だったので,改めて調査。
たぶん「CarbonかCocoaか」っていうキーワードで認識している人が多いと思うんだけど、実際は結構複雑
上記のエントリにも書いたとおり,Carbon APIとCocoa APIは,どっちかしか呼べないものではなくて,相互に呼べるのね。
なので,CarbonかCocoaかを判定するのは一体何なのか?というのを調べてみた。
判定の基準は,HMDTさんのところにもあるようにGetProcessInformationというCarbon APIを使用して調べる。
(GUIを付けたツールを「CarbonOrCocoa」という名前で作成したので,欲しい人はどうぞ。ちなみにこのツールも,Carbon APIは使ってますが,Cocoaです)
まず,Xcode 2.4.1で新規プロジェクトを作成。選ぶのは「Carbon Application」。
main.nibというのとmain.cというのが含まれたプロジェクトが生成される。
さっそくビルドして実行して,CarbonOrCocoaで確認すると,当然「Carbon」と判定される。
じゃ,自動生成された以下のmain関数で実行されている何がCarbon判定を引き起こすのか?を調べてみる。
int main(int argc, char* argv[])
{
OSStatus err;
static const EventTypeSpec kAppEvents[] =
{
{ kEventClassCommand, kEventCommandProcess }
};
err = CreateNibReference( CFSTR("main"), &sNibRef );
require_noerr( err, CantGetNibRef );
err = SetMenuBarFromNib( sNibRef, CFSTR("MenuBar") );
require_noerr( err, CantSetMenuBar );
InstallApplicationEventHandler( NewEventHandlerUPP( AppEventHandler ),
GetEventTypeCount( kAppEvents ), kAppEvents,
0, NULL );
HandleNew();
RunApplicationEventLoop();
CantSetMenuBar:
CantGetNibRef:
return err;
}
この中の関数呼び出しは5個あって,順に省略していってどこでCocoaになるのかを調べる。
(RunApplicationEventLoop()は省略するとアプリがすぐに終了してしまうため,省略できない。
で,代わりにCocoaのイベントループであるところのNSApplicationMain(argc, (const char **)argv);と差し替える。
ただし,プロジェクトにCocoa.frameworkを追加し,ターゲットのプロパティで,主要クラスのところに「NSApplication」を指定しておく必要がある)。
すると以下が分かる。
- NSApplicationMainを使っても,UI要素がCarbon Nibから生成される場合はCarbonと見なされる
- RunApplicationEventLoopを使うとUI要素がなくてもCarbonと見なされる
- UI要素を生成せずに,NSApplicationMainに入るとCocoaと見なされる
では,CocoaからCarbon Nibを使ってメニューやウィンドウを生成するとどうなるの?ということで,今度はXcodeでCocoa Applicationを選んで新規プロジェクトを作成。
NSApplicationの派生クラスMyApplicationを作って,主要クラスとして設定し,そのawakeFromNibにさっきのmain()の中身のうち,RunApplicationEventLoop()以外をコピペ。
それで実行すると,メインメニューやウィンドウはCarbon Nibから生成されたCarbonのメニューやウィンドウなんだけど,CarbonOrCocoaでの判定は「Cocoa」になる。
以上の調査結果をまとめると,
- イベントループ前にUI要素が生成されていれば,そのUI要素がCarbon APIで作られたものならCarbonアプリ,Cocoa APIで作られたものならCocoaアプリと判定される
- イベントループ前にUI要素が生成されてなければ,イベントループがRunApplicationEventLoop(=CarbonのイベントループAPI)ならCarbonアプリ,NSApplicationMain(というかNSRunLoop?)ならCocoaアプリと判定される
となる。
ちなみに,CarbonのプロジェクトのHandleNew()で,CocoaのNibファイルからNSWindowを生成するようにすることももちろんできる。
その場合でも,NSApplicationMainより前にメインメニューをCarbon Nibから作っちゃうと,やはりCarbonアプリと見なされる。
で,CarbonとCocoaを混ぜることができるわけなので,ならばFinderとiTunesがどの程度Carbonなのかというと,
nm /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder
nm /Applications/iTunes.app/Contents/MacOS/iTunes
で調べると,少なくともTigerのFinder/iTunesはCocoa APIを一切利用してない,ということが分かる。
Leopardではどうかね。
で,HMDTさんの「Mac OS Xでもっともよく使われるアプリケーションは、Carbonです」というところに戻る。
実際に,TigerでAppleのアプリを起動してCarbonOrCocoaで見たのが以下。

こうしてみると,もはやAppleのリリースするアプリケーションでCarbonなのはFinderとiTunesしかない(あとDVD周り)。
iTunesはWindows版のCOM実装を外す訳にはいかないだろうし,Mac版とWindows版でコードを2つに分ける,なんてこともしないだろうから(むしろWindows版のテストをしていないという見方もあるぐらいだし),C++での実装は続くんじゃないだろうか。
Finderは,徐々にCocoa化していくことは可能と思うけど,ただ,もしAppleのアプリがすべてCocoaになったらCore FoundationとかCarbon APIはテストされなくなるんじゃないかという気がする。
Carbon API最後の砦としてのFinder。
2007年10月29日
Xcode 3.0
Xcode 3.0 is the Mac OS X 10.5 (Leopard) developer tool set, including the Xcode IDE, Dashcode, Instruments, Interface Builder 3, and the rest of the developer tools.
ダウンロードしようとして1.1GBにおののく。
今日のところは勘弁しといたるわ。
しかしあれだ,久しぶりにADC Membershipにログインしたら,Apple IDがiTunesと共用されているせいで文字化けしてて,Profileの更新を求められた。
「すべて半角英数字でご記入ください。(日本語で入力すると正しく登録されません)」などという画像が貼ってあるんだけど,ここで変えてもiTunesのほうでProfileをメンテするとどうしても「State/Province」のところが郵便番号から「神奈川県」になってしまって,ADCに戻ったら文字化けしてるのね(それ以外は打ったとおりになるんだけど)。
2007年10月27日
Leopardの件
Leopardがリリースされましたな。
かくいうワタシはというと,なぜか今頃Quartz Composerにハマってます。
With the QC Plugin API, you can go even further
and create your own custom patches by using Xcode.
パッチを自分で作れるようになる,ということでこれは楽しそう!
Objective-C 2.0もいいんだけど,
If you're writing new applications for Leopard, you should make full use of the new features in Objective-C 2.0 to write modern Cocoa applications. On the other hand, if you still need to support older versions of Mac OS X, you can code as you always have using Objective-C 1.0 features and your application will run unchanged on Leopard.
つねづね思うんだけど,Microsoftがなんだかんだ言っても,基盤になると思われる機能を前のバージョンのOSでも使えるようにしてくれる一方で,Appleはほんと,前のバージョンのOSをばっさり切り捨てるよね。
「if you still need to support older versions of Mac OS X」って。
完全な顧客限定アプリ(個別開発アプリ)か,超キラーアプリしか,Leopard限定なんてことはできんでしょ。
2007年8月19日
オープンソースと業務アプリ
仕事では業務アプリを作ってるんだけど,顧客ごとにどうしてもカスタマイズが発生してしまって,ソースツリーが枝分かれだらけになったり,パラメタが増えまくったりしてしまうんで困ってる。
他の人たちはどうしてるんかなぁと思って,「オープンソース 業務アプリ」とかで検索すると,「そろそろ普及か?」みたいな記事ばっかりで,なんつーか「普及しまくってます」というのが意外と少ない。
普及しつつある分野はCRMとSFAらしいんだけど(これも良くは分からんのだけど),その辺りの分野と,例えば受発注や在庫管理,生産管理なんかはやはりというか普及度が異なる。
受発注とか在庫管理とかっていうのは,ほんとに会社ごとに(というのは大げさか。業種ごとに,というほうが正しいかも)やり方やモデルが異なるので,例えばあるERPパッケージを導入する,といってもどの業種にも同じパッケージで済む,という可能性は低いのね。
もっとも有名な商用ERPパッケージ(と思われる)SAP社のR/3なんかは,パラメータが死ぬほど存在し,特定業種向けのパラメータセットを「テンプレート」として販売しているベンダもあるぐらいだし,それでなお,ほとんどの顧客企業はなにがしか手を加えて使っているのではないかと思われる。
つまり業務アプリにパッケージを使うというのはそんだけ難しいってことだと思うのね。
つーことは,例えば,あるオープンソースのERPパッケージがあったとしても,ほとんどの場合は,なにがしか手を入れないと自社のモデルに合わない,という可能性が高い。
そのうえで,何とか(手を入れてでも)使いたいという場合,どういう方法が採れるかというと
- 自社で手を入れて,今後の改善はすべて自社で行なう(外注先に頼む場合も含む)
- 自社で手を入れたものを,本家の方に(パラメータか何かで切り分ける形で)取り込んでもらう
- 自社で手を入れて,本家からフォークしたプロジェクトを始める
などが考えられる。
まず,すべて自社でメンテしていく(つまりはほとんど自社開発と同じ)場合は,よほど自社の開発能力が低いのでない限り,自社で最初から開発した方が自社によりマッチする可能性が高いんじゃなかろうか。開発能力が低いのであれば,自社でメンテしていくという選択肢はないような気がする。いずれにしても自社だけでメンテするとなれば,コストは相当にかかりそう。
つぎに,本家が取り込む案だけど,この辺の業務アプリでは,データの主キー自体が企業や業種によって違うことが多いので,なかなか汎用的なデータモデルを作ることが難しい。キーをパラメータで切り替えるというのも,ソフトウェアの構造上はあまりいい感じにはならんと思う。ワタシが本家のメンテナだったら,そういう得体の知れない拡張は取り込みたくない。
ただ,もし本家の作りが,プラグイン多用型になっている場合は,もしかしたらcontribみたいな感じで,本体とは別に,検証対象外だけど使いたい人が使う,みたいな寄せ集め方ができるかも知れない。
そうなると,どっちかというと本家はフレームワークで,contribが業種別サンプルアプリのようなイメージに近くなる。
最後の,フォークしたプロジェクトを始める,っつーのは,なかなか大変。なので,おそらくは,そういうフォークしたプロジェクトをやっている(やってくれる)会社にお願いするしかないのではないかと思うのね。
複数社でメンテコストが分担できれば,メリットも出やすいし。
ただ,こういうふうにフォークしてしまう場合は,どうしても「由来が一緒なだけの別プロジェクト」となってしまうのは仕方がないんだろね。
で,ここまではどっちかというと,既存の業務アプリパッケージのイメージに基づいた想定。
だけど実際には,どんなにデータモデルが異なったり,手順が異なったりしても,例えば「在庫管理」の本質が変わったりはしないし,おそらくは「在庫管理」の機能も大きく異なることはないはず。
ということは,何がキーで,どの順で何をするかさえはっきりすれば,おそらくは在庫管理システムは自動生成できるんじゃないかという気もするわけなのね。ソフトウェアファクトリじゃないけど。
すでに自動生成ツールっていうのは数多く存在するし,珍しい話ではないんだけど,オープンソースで特定業務向けシステムを自動生成するツールっていうのはあまり見たことがないので,もしかするとそういうのが今後増えてくるという可能性はある。もしそんなのが増えたら,ワタシは何をしてメシを食っていこうかね。
そんな感じで色々考えたことを改めてまとめると,業務アプリのパッケージというのは,
- 特定の業種に特化し,他の業種のことは考えない。別の業種向けにフォークしたら別プロジェクトとして進化する
- 業務アプリ開発フレームワーク/プラットフォームとして進化する
- 在庫管理システム生成ウィザードパッケージみたいなウィザードソフトウェアとして進化する
というあたりで落ち着くんだろう,と思う。
フォークは,ある程度ユーザ数がいないと維持できないと思われるので,業種ごとの差が少なかったり,あるいは逆に特定業種へのヒット率がやたら高かったりしたらそれで落ち着きそう。
フレームワークとかプラットフォームとかっていうと,最終的にはR/3のようになってしまう気もするんで,その形態にとどまるのは難しくて,いずれはフォークしていくんじゃないかと想定。
本命は「ウィザード」だとにらんでるんだけど。
まあいずれにしてもオープンソース業務アプリの広範な普及にはまだ少しかかりそうな気がするのね。
2007年3月12日
アクセシビリティに関するデザインパターン
以前からprivateよりきつい可視性がほしいなぁと思ってたけど,その原因,なんでそんなものが欲しいかというのとその対策とがやっと分かった,というか分かってたけど明確に意識できた。
仕事でソフトウェアを作っていると,当然複数人で開発することになって,かつ最初に開発した人とメンテナンスする人が違うというのが当たり前になるわけで。
クラスのメンバ変数がprivateになっていないというのは保守性の面からみて論外としても,privateになっていてすら,そのクラスをメンテする人の腕(or性格?)によってはめちゃくちゃな使い方をされることが多いのね。
例えばよくあるものとして,計算コストがかかるデータをキャッシュする変数を追加したような場合。
キャッシュなので更新のタイミングというのは非常に重要なんだけど,メンテのつど,間違えずにプログラム修正していくのは難しいわけで。緊急の修正とかの場合になると,ある前提のもとでのみちゃんと動作する,みたいな修正をしてしまうことも,まあ実際のところ少なくない。
難しいコードに「~は~なので~のときは~すること」みたいなコメントをつけると,何年かするうちにそのコメントどおりにしていないコードも紛れ込み,コメントがウソになってしまって結局何なのかよく分からなくなるということも多い。
なので,更新が難しい変数は,できるだけ簡単に触らせないというか,特定のメソッドからのみいじれるようにしないといかんなぁと思ってて,だからprivateよりきつい制限,それこそ特定のメソッドからしかアクセスできない(.NETでの属性みたいなもの)が欲しいなあということだったんだけど。
よくよく考えたら,そういう変数は新たにクラスを作ってそこにメソッドをまとめてしまえばよかった。
保守でむちゃくちゃにならないために機能を分けてアクセス制御するパターン。
2006年12月20日
ソフト開発者の「横暴」?
「私の母親は80代だが,母親にとって,ワープロ・ソフトを使う目的は,良い文書を書いて,印刷して,誰かに読んでもらうこと。同じ目的を持つ人はかなり多いはず。なのに,印刷というコマンドは表には書かれていない。かろうじて,印刷のアイコンが小さく表に出ているだけ。これは『開発者の横暴』だ」。
最近,自宅で(も)Visual C# (Express Edition)をいじってる。
Visual Stduioを使っている人は分かると思うんだけど,なんでバージョンアップのたびにデフォルトのキーバインドが変わるんだろ。
(というかVisual Stduio 2005の場合,C#とC++ですら,デフォルトキーバインドが違ってて,例えばソリューションのビルドがF6とF7で違う,とかがある。いくら元々別製品とはいえ,それぐらいは何とかしてほしい)
ともかく,過去の知識や経験は財産・資産であって,やはりそれを活かせるようにしたApple Human Interface Guidelineは偉いわけで,通常,印刷できそうなアプリケーションをインストールしたあと,印刷メニューを探し回らなくても印刷メニューを見つけられるのは(場合によっては,ショートカットキーで印刷できさえするのは),まさにガイドラインのあるおかげ。
新しいインターフェイスがダメとは言わないものの,もしそれがほんとに良いインターフェイスなら,標準化を進めてもらわないと困る。自分だけが「これのほうがいいっしょ?」みたいなこと言っても困っちゃうのね。
今はファイルメニューの中に「印刷」がなければ印刷できないと分かるんだけど,開発者がそれぞれ勝手に「こっちのほうが分かりやすい」とかっていろんなことやり始めたら,できないことが何なのかも明確にする必要がでてくる。
標準化されないインターフェイスは,本質的には良くても結局は異端児で使いづらいモノになっちゃうと思うのね。
標準化する力という点で,AppleやMicrosoftがやっていいことと,名もない開発者がやっていいことは違うわけで。
で,VS2005に戻って。
なんでCtrl+Wがコマンドプリフィクス(2番目のキーを待つショートカットキー)になってるの…。しかもキーのカスタマイズがしづらいことしづらいこと。
新しいウィンドウは開かなくていいから,今見えているウィンドウを閉じさせて欲しい。
2006年11月20日
続:NSTableViewのダブルクリック
今回はとりあえず,NSTableViewのダブルクリック問題に気が付かなかったことにして,次に進みます。
次に進んだんだけど,気付く気付く。
とにかく,NSTableViewのmouseDown:実装が奇妙な動きをするので,ここは一つオーバーライドするか,と挑んだのはいいんだけど,これが厳しかった。
mouseDown:をオーバーライドしても,クリックされたセルに値を始め何から何までちゃんと設定されてなくて,そのままtrackMouse:inRect:ofView:untilMouseUp:を呼んでもダメ。
どうも中を追ってくと,_NXSetCellParamというのが現われて,これが各種の設定を行なっているらしい。
紆余曲折を経て,最終的にたどり着いた回避策は,
「mouseDown:の引数でもらったマウスダウンイベントを,クリック数を1にして複製し,オリジナルのmouseDown:に渡してやる」
だった。
こんな感じ。
- (void)mouseDown:(NSEvent*)inEvent
{
NSEvent* event = [NSEvent mouseEventWithType:[inEvent type]
location:[inEvent locationInWindow]
modifierFlags:[inEvent modifierFlags]
timestamp:[inEvent timestamp]
windowNumber:[inEvent windowNumber]
context:[inEvent context]
eventNumber:[inEvent eventNumber]
clickCount:1
pressure:[inEvent pressure]];
[super mouseDown:event];
}
なんだかね。
あと,編集可能なセルの場合はもうちょっと工夫が必要かも。
2006年11月13日
アラートのボタン
Macでもアクセシビリティの関係で,いつからか,ダイアログのボタンにフォーカスの枠が付くようになってるんだけど。
今日,たまたまNSAlert(これ,実は10.3からなのね,知らんかった)で初めて2つボタン(OK,Cancel)を使おうとして,何やら違和感が。
要はCancelのほうにフォーカスがあるんだけど,Returnキーを押すと,どっちが入るん?
答えは,
Return→OK
Esc→Cancel
Space→Cancel
実際のところ,Return(Enter)でデフォルトボタン,Spaceでフォーカスコントロールにキーが入る,というのはWindowsも同じ。
だけど
・デフォルトボタンが,Macでは強調されすぎてる。Windowsは意外と控えめ。
・WindowsはOKが左にあるので,こういうケースではデフォルトボタンに最初にフォーカスが当たる。MacではOKが右なのでデフォルトボタンとフォーカスコントロールが違うことが多い。
って感じで,WindowsのほうはMacほど違和感がない。
慣れのような気もするけど。
> フルキーボードアクセスがOnになっているときだけ
確かにその通りでした。
Macだとタブオーダを意識してないので,フルキーボードアクセスをOnにしたとき,びっくりしますね
2006年11月12日
PantherとTiger
友の会のメーリングリストで,松本さんに以下のサイトを教えてもらう。
Omni Software Update Statistics
Tigerは97.4%,Intel Macは56%らしい。
いくらMacユーザが新しもの好きとは言え,PowerPCのほうがすでに少数派になってるってことはないだろう。
ってことで,とりあえず,自分とこのWebサイトのアクセスログを集計してみた。
集計方法は,ログ見て分かること,ということで以下のような感じに。
・OSのバージョン→Safariのバージョンで判断
・CPUタイプ→Safari,FirefoxはログにIntel Mac/PPC Macのいずれかを出力するようなので,それで判断(実際にはIntel Mac,PPC Macのいずれかが入っていたらカウント)
・同じIPアドレスからのアクセスは期間内で最終のもののみカウント
・期間は9月,10月,11月(11/10まで)の3つに分けて集計
結果
| OSバージョン | 2006/09 |
2006/10 |
2006/11(〜11/10) |
| 10.2(Safari/1xx) | 5.6% |
3.2% |
2.9% |
| 10.3(Safari/3xx) | 15.4% |
11.3% |
17.3% |
| 10.4(Safari/4xx) | 79.4% |
85.1% |
79.8% |
| CPU | 2006/09 |
2006/10 |
2006/11(〜11/10) |
| PowerPC | 85.6% |
79.3% |
83.8% |
| Intel | 14.4% |
20.6% |
16.2% |
母数が少ないので誤差もでかいんだけど,およそ以下のようなことが言えるんではないかと思う。
・10.3以前のバージョンを使っているのは2割。8割程度は10.4を使用。
・Intel Macは15%〜20%程度。もちろんこれは今後,徐々に増えていくはず。
1割〜2割というのをどう考えるのか,なんだけど。
思ったより少ない,という気が一瞬したけど,よくよく考えてみれば,それぐらいの数字を期待してたというか想定してた気もする。
2006年11月 9日
NSAttributedStringの描画サイズを取得する(2)
調べてみたら,そのものずばりのコードがリファレンスにあった。
You can pass these values into a function with a declaration such as the following:
float heightForStringDrawing(NSString *myString, NSFont *myFont,
float myWidth);
てゆうか,ここに書くなら最初から用意しておけ,という気がする。
で,結局何がやりたかったかというと,NSTableViewでセルの真ん中に文字列を表示したい,というだけなんだけど。こんなに苦労するとは思わなかった。
サンプル作ったのでどうぞ。
2006年11月 8日
NSAttributedStringの描画サイズを取得する
.NET Frameworkで言うところの,System.Drawing.Graphics.MeasureStringに相当するモノを探してたんだけど…。
boundingRectWithSize:options:で取得できるらしい,というところまでは分かったんだけど,これなぜか10.4以降でのみサポート。
単にsizeをやっただけだと横幅指定できないので,LineBreakStyleとか指定した場合に高さがどれだけになるか分からない。
(たかが文字列の描画サイズが取得できないだけで)10.4以降に対象を絞るか,10.3以前(といってもたぶん10.3.9だけサポートということにはなると思うけど)NSLayoutManagerを使ってちまちまやるか,という選択になれば,仕方なく後者にせざるを得ないところ。
CoreDataとかWebKitとかもそうなんだけど,MacOSの場合,Windowsと違って,良さげな機能は最新バージョンでしかサポートされてなくて,簡単に手を出せないのがつらいよなぁ。CoreDataを使うなら(そんなところを10.4以降と10.3以前と分けてコーディングなんてできないから)10.3以前は完全に切り捨てないといかんからね。
.NET Framework 2.0はWindows 2000でも動く,ってあたりはAppleもMicrosoftを見習って欲しい。OSの新機能(128bitの暗号化とか)がInternet Explorerに含まれてリリースされるというのは見習うべきかどうかよく分かんないけど。
2006年11月 5日
Xcode 2.4.1をインストールした
前から出てるエラーがそろそろ出なくなるかと思ってたけど,まだ出てる。
File: /SourceCache/DevToolsBase/DevToolsBase-762/pbxcore/Target.subproj/PBXTarget.m
Line: 1480
Object:
Method: buildSettings
Don't invoke this method when build configurations are enabled.
なんだろ,これ。
プロジェクトテンプレートでCocoa Applicationを選んで作ったプロジェクトでも発生。というか,このテンプレートだから発生?
2006年11月 3日
NSStringの省略描画
覚え書き。
文字列を描画するとき,枠の中に入らない場合があって,折り返すかちょんぎるか省略するか,ってなる。
NSStringのdrawInRect:withAttributes:で描くとデフォルトでは折り返されてしまうので,ちょんぎるか省略する場合はwithAttributes:に
NSMutableParagraphStyle* lineBreakStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
[lineBreakStyle setLineBreakMode:NSLineBreakByTruncatingTail];
NSDictionary* attrib = [NSDictionary dictionaryWithObjectsAndKeys:lineBreakStyle, NSParagraphStyleAttributeName, nil];
のような感じで作ったattribを指定する。
NSLineBreakBy…は,折り返すのもちょん切るのも省略(頭・ケツ・真ん中)もある。
もちろんNSAttributedStringに設定してやってもOK。
ellipsisとtruncateというキーワードでは探しても見つからないんで,そういう機能はないのかと思いました(ググったら「1文字ずつ幅を計算して自分で省略するんだよハハハ」のようなのしか見つからず,マジか?!状態でした)。
NSURLDownloadのsuggestedFilename(2)
覚え書き。
NSURLDownloadのsetDestination:allowOverride:でNOを指定すると,例えばindex.htmlをダウンロードしようとして,保存先にindex.htmlが存在すれば,勝手にindex-1.htmlという名前で保存してくれる。
mysoftware_4.4.2.dmgの場合,それがすでに存在するとき,mysoftware_4-1.4.2.dmgになる。一瞬,あれ古いバージョンがダウンロードしてあったんだ?とか勘違いしてしまうけど,要は最初のピリオドの前に-連番が付く。
この仕様の場合,mysoftware.dmg.gzはmysoftware-1.dmg.gzになる。
これを.dmg-1.gzにされると,gunzipしたときに.dmg-1になってしまい,アイコンがディスクイメージのそれにならなくなっちゃうので,これはこれでいいはず。
どっちかというと,ファイル名を付ける側がmysoftware_4_4_2.dmgとかmysoftware-4-4-2.dmgみたいな感じでピリオドを入れないようにしとくべき,という気がする。
ところで初めて気が付いたけど,Finderはmysoftware.dmg.gzのような感じでピリオドが2つ以上つくと,拡張子を隠せないのね。セキュリティ関係の制限かな
2006年11月 2日
NSTableViewで列数変更
覚え書き。
Autosave Nameに値が設定してある場合,列数を変更しても,実行すると元の列数で表示される。
バージョンアップ時には要注意。
追記:
要注意とは書いたものの,じゃ,何をどう注意するかというか,どうやって回避するのかって,ねぇ。
結局,「列数を変えた場合は,Autosave Nameを変える」ぐらいしか思いつかず。
2006年11月 1日
NSTableViewのダブルクリック
NSCellがダブルクリックを拾えないのは,NSTableViewのmouseDown:の実装がダブルクリックを変に(?)扱っているせいではないかと思われる。
NSTableViewがダブルクリックを拾った時点で,delegate用にtableView:shouldEditTableColumn:row:を呼び出すはずで,delegateがなければそのままNSCellにクリックを渡してくれればよいものの,delegateがなければそのまま(イベントをdequeして)無視,のような感じになっているのではないかと想定。
想定は外れてて,NSTableColumnのisEditableがYESの場合,データの編集が始まり(この辺は検証してない),NOの場合は,NSTableViewのターゲットに対してクリックの時と同様にアクションメッセージが送信される,ということらしい。
しかし,動きを見てみると,mouseDown:には3回連続だろうが4回連続だろうがちゃんと入ってきているのに,NSTableViewのターゲットには1回目と2回目しかアクションが来ないのね。
NSButtonCellをPush Buttonにしてテーブルに貼り付けて,カラムのEditableチェックボックスをオフにした場合,連続して3回クリックすると,1回目は普通に反転してアクションも実行され,2回目は反転せずにアクションが実行され,3回目は何も起こらないという,非常に間抜けな感じになってしまう(Editableチェックボックスをオンにした場合は2回目以降何も起こらない)。
NSDatePickerCellを使うと連続クリックが入らないのでさらにイヤーン感が増す。
シングルクリックとダブルクリックの区別がつかないというのもいやらしい…と思ってたら,Tigerから追加されたバインディングがあるとのこと。
NSTableView now has doubleClickArgument/doubleClickTarget bindings that work the same way as the argument/target bindings of buttons - the bindings are used to trigger a method invocation on a double-click in the table view.
どっちみち3回目以降のクリックは入らないので,NSDatePickerCellがヤな感じなのは変わらんけど。
それにこのドキュメントを見ると,NSTableViewの動作がPantherとTigerで結構違うようで,Tigerで動いたからといってPantherでもイイ感じに動くとは限らないのね。
今回はとりあえず,NSTableViewのダブルクリック問題に気が付かなかったことにして,次に進みます。
2006年10月31日
suggestedFilename
覚え書き。
NSURLResponseは,http://localhost/~kabeya(最後のスラッシュなし)に対して,suggestedFilenameに"~kabeya"を返してくる。
ちなみにhttp://localhost/~kabeya/に対しては~kabeya.htmlを返してくる(index.htmlとかでHTMLが返る場合)。
一方,NSURLDownloadの場合,download:decideDestinationWithSuggestedFilename:で,http://localhost/~kabeyaでもhttp://localhost/~kabeya/でも,ともに~kabeya.htmlを返してくる。
どうもNSURLConnectionとNSURLResponseを使った場合,前者(スラッシュなし)のときには0バイトでconnectionDidFinishLoading:が呼ばれるようで,それが関係している気がする。これはApacheの設定に関係するかも。
違いも微妙なんだけど,いずれにしてもファイル名をチルダ付きで返すのはやめて欲しい。ローカルなら展開すればいいんだけど,そうじゃないんだし。
NSCellの派生クラス(3)
NSTableViewにNSCell(の派生クラス?)を貼り付けた場合,ダブルクリックのときは(1回目のクリックしか)NSCellのtrackMouse:inRect:ofView:untilMouseUp:が呼び出されない。
NSTableViewを派生させて,mouseDown:にNSLogを噛ませると,NSTableView側のmouseDown:には2回目のクリックも来ている様子。
デバッガで見る限り,NSTableViewのmouseDown:からNSCellのtrackMouse:inRect:ofView:untilMouseUp:が直接呼び出されているようなので,NSCellがダブルクリックを拾えないのは,NSTableViewのmouseDown:の実装がダブルクリックを変に(?)扱っているせいではないかと思われる。
NSTableViewがダブルクリックを拾った時点で,delegate用にtableView:shouldEditTableColumn:row:を呼び出すはずで,delegateがなければそのままNSCellにクリックを渡してくれればよいものの,delegateがなければそのまま(イベントをdequeして)無視,のような感じになっているのではないかと想定。
今日はこの辺で。
酔ってるし。
2006年10月29日
NSCellの派生クラス(2)
覚え書き。
NSCellの派生クラスでtrackMouse:inRect:ofView:untilMouseUp:をオーバーライドするとき,[self controlView]で返ってくるNSViewと引数でもらうNSViewが違う。
うっかり[self controlView]で得たViewにupdateCell:をやっても更新が走らない。
引数でもらったNSViewにupdateCell:するのが正解。
AppleのClockCellサンプルは,確かにそうなってるんだけど,コピペしてくる場所を間違えたら全然更新されず,悩みました。
2006年10月28日
NSCellの派生クラス
覚え書き。
NSCellの派生クラスを作るとき,インスタンス変数としてオブジェクトを持たせて,かつdeallocでそれらをreleaseしちゃうような場合。
copyWithZoneもオーバーライドして,その辺のオブジェクトをコピーするかretainするかしとかないと,途中で異常終了する。
異常終了するのに原因が分からず苦労しました。
…コンストラクタが欲しいです。
2006年8月 1日
Finderのウィンドウ
で思ったのは,GlueWindow Xを作ってみようか,ということ。
GlueWindowは松原卓二氏(松原園長)がGluWIndowINITとしてMacPowerの「キョービのプログラマはそんなもんスか?」で公開し,その後,ワタシがGlueWindowという名前で改造し,さらに,松原氏がSimpleGW INITという名前で改良版をリリースされたというもの(松原さん,すみませんでした)。
これ,Finderってウィンドウの位置覚えるんだっけ,どうだっけ?確か10.0とかの頃はむちゃくちゃだったはず,と。
MacOS 9までのFinderは,(Finderの)ウィンドウの位置を覚えてた。なので,すっきり並べるといつまでもすっきりしたウィンドウが楽しめるという特徴があった。これはWindowsでは味わえないし,MacOS Xでも味わえない…と思ってた。
改めて確認すると…。
なんじゃこりゃ。ウィンドウがどこに開くか,ルールが全然分からん。バグですか仕様ですか仕様だとしたらどんな仕様ですか。
知ってる方教えてください。
2006年6月21日
HMDT 3rd Editionを買ってきた件
mkinoさんのHappy Macintosh Developing Time Third Editionを買ってきた。
よくよく内容を見ると,Third Editionとあるものの改訂版ではなくて続編なのね。
この名前の付け方だと,前作,前々作が店頭から消えてしまうのではないかと心配。
2006年3月28日
計算機の件
関根さんにご指摘いただいて,久しぶりにウチでコードを書こうかと。
なんか旧バージョンをデバッグ実行するとアクセスバイオレーションが発生するので,いろいろ環境を見直したりしてたんだけど。
びっくりしたのが,MacOS X標準の計算機。
いつの間にかプログラマモードがついてるのね。
10.3にはなかったのでTigerからなんかな。
ウェブログ: XO : 2006年5月11日 00:21
2006年2月22日
Software Factories
けっこう前の話だけど,Microsoft Developer Conference 2006 (2/2-3@パシフィコ)に行ってきた。
C# 3.0とか,色々面白い話はあったんだけど,なかでもSoftware Factoriesという考え方が紹介されていたのが興味深かった(関連しそうな話:「モデル駆動」の本当の意味)。
特に「今までは汎用化しすぎてた」って言ってたのはとても共感できる。
「対象ドメインを絞ることで流用性が高まる」,っていうのは非常に納得がいく。
また,「ソフトウェアというのは,プログラムだけでなくて,仕様書やら設計書やらすべてを含む」,っていうのも,それとなく思ってはいたことなんだけど,こう,改めて言葉にされると,なるほどなぁという感じ。
なんてゆうか,特にものすごく目新しいことを言っているわけではないんだけど,言葉にすると新鮮だね。
ただ,やっぱり,「ソフトウェア開発」を「製造ラインで製造する」っていうのと対比させるのは,なんだかなぁって思うわけで。
くどいけど,やっぱり「ソフトウェア開発」っていう名前の通り,「製造」ではなく,「製品開発」と比較するべき。
携帯やデジカメなどの新機種が次々と開発できるのはなぜだ?ってあたりを考えないと。
本(ソフトウェアファクトリー)も出てるみたいで,カンファレンス当日も会場で売ってたんだけど,売り切れてた。ちと高い。
2006年1月16日
プログラミングは製造工程ではない
またも前回の続き。
「「設計書に文章で書いてあることをプログラミング言語に置き換えるだけ」ということになるのです」
もしこれが実際その通りだとすれば,それをやっている人というのはプログラマではなく,むしろコンパイラという職業じゃないかと。
で,もしも,プログラマがちゃんとプログラムを書けるレベルまで設計書を詳細化しなければならない,ということであれば,プログラマって何なの?
言ってみれば編集者がネームを書いて,アシが仕上げるって感じに近いのではないか。マンガ家はどこに行った?
「考えてみればこの業界のお仕事というのはですね,服飾業界などが産業革命以前に家内制手工業でいっこいっこ手作りをしていたあの頃と同じ状態のままなのです」
ワタシはむしろ逆で,プログラミングは設計の最終工程であると考えている。製造はビルドに相当する。そういう意味で製造はむしろ他のすべての製造業の中でもっとも進んでいて,ほぼ自動化されていると言っていい。
で,例えば5年10年使われるプログラムを作ろうとするのであれば,仕様書の質はもとより,クラスの分け方,関数の分け方から変数名に至るまで,ちゃんとしたレベルで設計していかなければならない。で,このレベルで設計書を書いて,設計書に書いてある変数名で設計書に書いてある関数を作る「コーダー」がいるのであれば,もしかしたらそのコーディング作業は「製造」になるかも知れないけど,そんな設計書を書くのは,それこそ無駄。だからプログラマがコードまで書く。でも本来プログラマがやるべきことはちゃんとしたプログラムを設計することなんだよね。
動作するだけじゃなく,ちゃんとしたプログラム(あいまいだけど)。変数の生存期間や凝集度のような測れる部分もあるけど,「分かりやすい変数名」のような,測れないものも含めて。
半年後に「こんなプログラム,ちょっと仕様変更するだけで大変すよ。読む気にもなんないですし。作り直しちゃった方が早いっすね」みたいなことになるプログラムは非常に多いんだけど,そういうのがなければ,本来はもっともっと稼げているはずじゃないかと思う。
いずれは今のようなコーディングがなくなる時代が来ると思うけど,そのときでもやはりプログラマはプログラマだろうと思う。プログラマは単にコードを打つ人ではないのだから。
プログラミングしかできない人がプログラマではない話
前回の続き。
「35歳過ぎても「プログラマでござい」なんて言って管理もできないような人は,金銭的に割りに合わないんですよ」
違うよね。
35歳過ぎて管理ができなければ,それはプログラマじゃなくたって割りに合わない。魚屋だって大工だって,営業職だって工場のラインマンだって,あるいは社長だってなんだってそれは同じ。
いい年こいて管理できなくても許されるのは,ほんの一握りの天才だけ。
どうすか。
35歳過ぎたプログラマは不要,ではなく,35歳過ぎて管理できない人は不要。
プログラマの定義は「プログラミングしかできない人」ではなく,「プログラミングできる人」だよね。
プログラマ35歳定年説とワタシ
12月も結局何も書かず。いやほんと,コンピュータさわってない。
その割に本は色々買ってきてはいるんだけど。
で,感想を書こうかと思ったは良いものの,なんつーか,まとまらない。
なので,まとめるのは諦めて,ちょいちょい書こうかと。
「SEのフシギな生態―失敗談から学ぶ成功のための30ヶ条 」
有名な本なので読んだ人も多いんではないかと。
色々思うとこはあったわけだけど,中でも。
「プログラミングスキルなんてどーだっていいノダ!」
こんなかでも触れられている「プログラマ35歳定年説」ってのは,まー昔からよく言われていることなんだけど,
「プログラムを書くなんて作業にたいした価値はありません。所詮は川の下流に位置する作業,業界に何年か浸かってりゃ自然と身につく程度のものなんです」
こういう言い方に,なんかこう,割り切れないものを感じていたところ,
「新吼えろペン 3」
島本和彦大先生の著作の中にヒントが。
チーフアシに対して,新人アシがこう叫ぶ。
「あんたが先生ですよっ!」「マンガ家の先生のやる仕事は…あんたが全部やってますよ!!」
そうか!そうゆうことか!と。
「背景を描くなんて作業にたいした価値はありません。所詮は川の下流に位置する作業,業界に何年か浸かってりゃ自然と身につく程度のものなんです」
定年説が指すプログラマというのは,実際はプログラマではなく,プログラマアシなんじゃないかと。
本当に必要とされるのは,経験を積んだプログラマであり,そういうのはむしろ35歳からが花ではないかと。
いやもう,そろそろその35歳に近づいてきたこともあるし,腹だけでなく他も成長させないとね,と思うわけで。
ま,「プログラミングスキルなんてどーだっていいノダ!」の中身はそれだけではないので,それは次のトピックで。
2005年10月 4日
最近買った本
とうとう9月は1回もエントリを書かず。死んだかと思ってた人もいるのではないかと。
それはともかく,この本,「サーバが落ちたときに,ある時点の(ゲーム世界の)スナップショットまで巻き戻る」ってのをどうやって実現してるんか知りたくて購入。どうやってスナップショットをリアルタイムにとっていくのん?って。
で,読んだ結果,ワタシの理解が正しければ「そんなに凝ったことはしない」のではないかと。ゲームというものの性格上,「完全にある一瞬」の状態じゃなくて多少のずれがあっても,誰も気が付かないし困らんということではないか,と。
ただ,一方で絶対使ってるはずのトランザクションについて,いっさい触れられてないから,単に解説が薄いだけなのかもという気もするし。
この本,全般的に「本当にこんなんでええのん?」(いやもちろん,簡略化して書いてあるんだけど)と感じずにはいられないことが多い。
「はじめに」に「簡単なサーバーモジュールを作成するにしても無知であることが自分を不安にさせ」などというくだりがあるんだけど,いやー確かに不安だわ。いろんな意味で。
そんでもって,Cのコードはもはや読めない自分に気づく。
2005年7月18日
コンソールって何が出力されるの?
って,今回curlの出力を止めてみて疑問に思った。
Xcodeから実行するとXcode側のコンソールウィンドウに出力されるcurlのログが,単独で実行するといわゆるコンソールに出力される。
Xcodeのコンソールウィンドウがsyslogへの出力を拾っている?
なんなんだろ。
2005年7月11日
それはいつか通った道3
ソフトウェアに対して,「この値段で」って言って値段を付けているのは,売る側の都合である,というわけで。
とは言うものの,それってパッケージソフトの話でしょ,っていう指摘も当然ある。
1本売ろうが100本売ろうが,っていうけど,受託ソフトウェアの場合って100本売るってわけにもいかないでしょ?って。
売りゃあいいんじゃん,というのがワタシの主張。どうすか。
売れるようにすりゃあいいんじゃん。受託先に,売ってもいいですか?売っていいって話なら安くできますよ?って聞けば(もちろん,契約書にもちゃんと書いてね)。
100%まるごと売れるなら苦労しない,って言うかも知んない。でもなにも100%使わんでもいいじゃん。
ある程度の汎用性を持たせないと後で使おうにも使えない,このプロジェクトでやるには荷が重い,って話もある。そりゃそうだけど,それは投資して,他のプロジェクトと併せて回収したら済む話。
つまり,受託ソフトウェアだからと言って,投資してパッケージのように売っちゃうことだって不可能じゃないはずで。
そんでもって,契約側の話のほかに,コードを何とかして再利用するようにしなければなんない。
実際のところ,受託ソフトウェアのコードのほとんどが,会社の中の誰かが1回は書いたことのあるコードなんじゃないかと。ワタシもCSV出力とか何回書いたか分かんない。また,実際,自分で書いたのじゃなくて人が書いたのをデバッグするという無駄な時間も少なからず過ごしているわけで。
どこか忘れちゃったけど,「出荷されていないコードは在庫である」というような話を読んだことがある。まったくもってその通り。
どうやって無駄な在庫を作らず,そんでもって1回書いたコードをたくさん売るかということを考えていきたい,と。
まぁコードの再利用なんて,いまさら感があるわけだけど,やっぱり継続的に考えないと。
なんか話が大きく脱線してるけど,元の筋に戻せるのか?
続く(予定)
それはいつか通った道2
間があいてしまったけど,続き。
トラックバックもいただいておきながら,ほんと済みません。
で,進む前に,まず,
ってあたりを,考えてみる。
そもそもソフトウェアというものは,値段を「どうとでもつけられる」ものだ,と言っておきたい。
製品のコストというのは,1個売るために必ずかかる材料費や直接人件費+1個売ろうが100個売ろうが一定である広告費や間接部門費でできている。
後者については,売れれば売れるだけ,1個あたりへの転嫁額が少なくて済む。
で,ソフトウェアというのは一般的に言って,その製品全体の価値に比して,前者の費用が極端に少ない。というか少なくできる。
Excelなんかはおそらく3,000円とかにして売っても利益が出るはず。
以前,本屋でなんかの本をパラパラっとめくってたら「一太郎を100万円で売るか10万円で売るかもめた,という話を聞いたが,自動車だったらそんなことはあり得ない。この点を見ても,ソフトウェア業界は未熟であると言える」などという文章を見たことがあるが,これはとんでもない話(もちろん速攻で棚に戻した)。
一太郎を販売する場合,そのコストのほとんどは開発費なわけで,それは1本売ろうが1億本売ろうが変わらない。したがって,開発に1億円かかったのなら,1億円で1本売るか,1円で1億本売るか(もちろんその中間で1万円で1万本売るとか),とにかく1億円を回収し,かつできればなるべく価格×売れる数が大きくなるように価格を決めればいい。
(どこかで聞いたような話だ,と思ったら,有料道路の通行料も同じと言えば同じ)
ただ,こういう値段付けをしているソフトウェアというのは,実際にはコンピュータソフトウェア以外にはほとんどない,というのも事実。
本も音楽も,どういうわけかページ数やCDの枚数で値段が決まっていて,いくらかかったからこれだけの値段,とか何枚売れそうだからこの値段とか,そういうふうにはなってない(これ,実際のところ,管理が大変だからとか,いちいち決めてられへんとか,そういう変な理由でこうなってるんちゃうかと推測)。
ともかく,ここで言いたかったのは「ソフトウェアはどんな値段でもつけられる」という話で,つまり。
ソフトウェアに対して,「この値段で」って言って値段を付けているのは,売る側の都合である,というわけで。
ウェブログ: XO : 2005年7月11日 01:38
2005年6月22日
それはいつか通った道
?システム価格を技術者の工数と単価で計算する方法では、何が問題か。
いまの方法はIT業界で長年続いてきたが、ユーザーにとっては納得性、透明性の低いものだった。よく言われているように、システム・エンジニア(SE)1人当たり月額いくらといった人月単価の設定は、個人のスキルや役割が異なるなかで、妥当かどうかの判断が難しい。
技術者の頭数ではなく,成果物について対価を払っていただける商慣習に変えていくよう,広く呼びかけたい
ってことで,「いや,言ってることは分かるけど」な話。
なぜ,ソフトウェア開発は人月いくらになっちゃうのか。ここを考えてもらわないと,この問題は永久に解決しない。
で,なぜって言えば「請け負う側の人件費が時給で払われてるから」なんだよね。
というか。
より一般的に言えば,「非定型業務は単位時間あたりの作業量およびその質が見通せないにも関わらず,給与は時給で支払われる」という状況自体,すでに問題。
そういう意味ではITとか関係なくて,他の業種でも営業職・技術職・企画職とかって,本来は時給という考え方と非常に相性が悪い。
もちろん色んな企業で「成果主義」とか「裁量労働制」とか「年俸制」とか,様々な試みをやってるってわけで。
ただ,それっていうのはどちらかというと評価の問題,つまり社内的な問題として語られることが多く,対顧客の問題として語られることって少ない。
なんで,それでほとんどの業種では問題にならず,IT系ばかり問題になるかと言えば,「ソフトウェアは原価の大半が人件費だから」。
1.原価の大半が人件費で,2.作業量・質が見通せないうえ,3.人件費が時給ベース,というような業種って,他に思い当たらないぐらい,ソフトウェア開発というのは特異な業種,と言える。
例えば,人件費が大半で,時給ベース,ってぐらいなら床屋とかもあるわけだけど,まあ作業量や質ってのは見通せる。質や量が見通しにくいという意味では,コンピュータソフトウェア以外のソフトウェア,つまり音楽や文章,映画なんかもあるわけだけど,ほとんどの場合,請負ではなく,売れた数量見合いで作者にお金が入るようになっているわけで(実はコンピュータソフトウェアと音楽・文章・映画との違いってのは他にもあるんだけど後述)。
ともかく,請負側が時給で人件費を払う限り,「工数がかかるからこれだけ必要です」という見積の仕方はなくならない,というか,なくせない。だって実際,そんだけ原価がかかっちゃうんだもの。
なくすとしたら,作業者への支払も「機能」「品質」などの成果物で決めなくちゃ,どうしてもソロバンがあわない。
でも一方で,それをやるんだったら,何のための給与所得者なの?個人事業主でいいじゃん,という話になっちゃう。
そうして話は元に戻る。というか次のステージへ。
続く(予定)。
ウェブログ: XO : 2005年7月11日 01:22
2005年6月 9日
今がベストな切り替えタイミング?
とにかく,一番先に思いつくけど一番先に選択肢から外しちゃうよな。
あるいは「どう考えても,PowerPCの命令セットを理解しないプロセッサを今から投入するってのはあり得ない。MacOS Xになるときに投入するならともかく」
って書いたものの。
よくよく考えると,今がベスト切り替えタイミングなのかも。
切り替えが正式に発表された今だからこそ言えることではあるけど,MNeXTを採用する,って決めた時点で,PowerPCを継続するよりIntelチップを採用しちゃおっかって動きのほうが実は強かったんじゃないんかなと。ファーストバージョンからIntel版が動いていたというよりは,PowerPC版よりIntel版の方が先に動いていた,あるいはIntelマシン上で開発していた,などという可能性もあるわけで。
そんでもって今なら,ある程度の製品がサポート対象からClassicを切ってて,また,そうでない両対応しているやつもBundle形式を使ってClassicとMacOS Xで違うバイナリを使ってるし,確かにワタシみたいにClassic環境なんか間違えてクリックしちゃったときぐらいしか起動しないって人が大半になった今。
2001年よりは2006年のほうがやっぱり切り替えのタイミングとしては適当なんだろね。
2001年に切り替えていたら,逆に今ほどMacOS Xは使われず,MacOS 9.8ぐらいがあって,シェアは落ちまくりで,iPodで稼いだ分をすべてMacの赤字につぎ込んじゃうみたいな状況になってたかも。
しかし,あれだね。昔はMacのほうがハードウェアのサポート期間が長い,つまりSE30でもSystem7が動くってことで,すごいメリットぽかったけど,今は完全にWindowsのほうがハードウェアのサポート期間が長いね。
ウェブログ: XO : 2005年6月14日 02:17
2005年6月 8日
例のインテルの話2
1)エミュレーションで実行する
2)トランスメタみたいなやつ
3)そもそもPowerPC互換。逆にPentiumの命令セットは理解しない
の3つぐらいの選択肢かと。
1)や2)って,それやったところでメリット少ないから,やる価値があるとすれば3)。
1)ですか。てゆうかx86をそのまま使うって,いいのか悪いのか全然分からん。とにかく,一番先に思いつくけど一番先に選択肢から外しちゃうよな。
みんな「それはないな」って思い込みが強いんで,誰もあんまり詳細に検討してなかったでしょ,って感じかね。
開発の話。
いますでにXcodeで開発してる製品はいいけど,大変なのはCodeWarriorでやってる人(というか製品)。
あと,AltiVec使って,こてこてのCPU依存コードを書いちゃった人とか。
まあ似たようなものがx86にもあるので,たいした問題ではない可能性はある。実際のとこ,どうなんだろ。
なんか意識して書かれているプログラムって実は少ないんちゃうかという。Macでも少ないけど。
で,まだ今回の話もあんまりよく見えてないけど,Rosetta(?)ってのが何なのかってのも興味ある,というかかなり重要な話ではないかと思う。
DEC Alpha版Windows NTでx86アプリを実行するというFX32!(だっけか)みたいな,エミュレータというよりはバイナリ変換ツールみたいなものだったら,パフォーマンスの面でも損しない可能性は高い。
まあ,でもなんつーか,G5よりx86のほうがより実行速度が速い,ってことじゃなくて,開発速度の速さの話,と思うことにしよう。
実際,G5発表当時(2003年6月),自分で書いた記事を見ると,「年内には3GHzモデルが出るらしいしな」などと書いている。確かにもうそれから丸2年経ってるわけで。少なくとも1年半は遅れてる。
「G5のほうがx86より速いって言ったじゃねーか」という意見もあるだろうけど(実際,ワタシも心情的にはそれが大きい),「2003年内に3GHz版G5が出る」っていう話があったればこそと思う。
ま,何にせよ,2003年当時,「3GHz版が出るまで待つ」って思わなくて良かった<そんなオチか。
ウェブログ: XO : 2005年6月 9日 02:16
2005年6月 6日
例のインテルの話
まあ,すぐに結果は分かる話なので騒ぐ必要はないんだろうけど。
ワタシも,多くの開発者寄りの人と同じく,ありえねーって思ってたけど。
PowerPC互換のCPUをインテルが作っちゃうっていう話だったら,それはそれで受け入れられる。
もちろんワタシはその辺のビジネスの話ってばよく分からんので,単純に技術的な面で(G5とか,単価いくらぐらいなのか知らんし)。
どう考えても,PowerPCの命令セットを理解しないプロセッサを今から投入するってのはあり得ない。MacOS Xになるときに投入するならともかく。
となると,
1)エミュレーションで実行する
2)トランスメタみたいなやつ
3)そもそもPowerPC互換。逆にPentiumの命令セットは理解しない
の3つぐらいの選択肢かと。
1)や2)って,それやったところでメリット少ないから,やる価値があるとすれば3)。
って,昔(っていうほど昔じゃないか),HPがPA-RISCからMerced(だっけか)に変えるって話をしてた頃にもしたことがあるような気が。いまどきのプロセッサはエンディアンの切り替えぐらい,普通にサポートしてるんかな(PA-RISCはビッグエンディアン,Intelは当然リトルエンディアンだったので不思議に思ってた)。
どうなりますか。
ウェブログ: XO : 2005年6月 8日 01:51
2005年5月30日
コーディングルール(名前付け規則含む)
死んでなかったのか>自分
てことで,コーディングルール。
一番分かりやすいところで,AppleのUniversal Header。
あれ,大昔(といってもワタシの知ってるのは90年代前半)に比べて,あとの方になったらすんごい綺麗になって,あんだけの規模であれだけの綺麗さというのは他に見あたらない(といったらほめすぎ?)
やっぱり,開発者が増えてくると,名前付けからインデントから,もうバラバラになるわけで。
ある程度決めてやっても,こう,やっぱり幅は出ちゃう。
あのUniversal Headerはどのぐらいの人数で,どのぐらいのルールを決めて,どのぐらいの期間をかけてやったのか,ちと知りたい。
って,今日仕事しながら思った。
2005年3月22日
C#を半年やってみて
始めました,つってから半年(blogのトップページが白紙になったのに気づいて書くことに)。
そろそろ見えてきたものがあるのかなと思いつつある今日この頃。
C#(というか.NET)じゃなかったら,そもそもやれる気がしないなぁという部分(.NET Remoting秀逸です)と,あとちょっと何とかして欲しいよねって部分と両方。
で,最近の口癖は「テンプレート欲しい」「スタックにオブジェクト作らせてくれ」の2つ。なんかグチがちょっと出ちゃうのね。
1つめ。
テンプレートがないんで,コンテナからオブジェクトを取り出したりすると,どうしてもキャストの嵐になっちゃう。とにかくいま書いてるコードはキャストが多い。で,そのせいで静的な型付言語というメリットがかなり殺されてて,実行時にならないと分かんないキャストミスが結構発生する。1回実行すればOKとか思うでしょ。そうじゃないんだよね。入力も確実にチェックしないと,途中,コンテナに何が入るかわからんという状態。コンパイラにチェックさせて来た身としては結構ツライ。
あと,気が付くとコピペしたようなコードが大量に増える。そんでもって,そろそろ直さなきゃって感じで,おおもとのクラスを見て,ユーティリティ系のメソッドを見て,インターフェイスを抽出して,って。おい,インターフェイスって。いや,インターフェイスって考え方はいいんだけど,つらい。
C++かObjective-Cならこんな作業要らんのにって。マジで。
で(Objective-Cを多少かじったせいなのか),今度は「object型はObjective-CのNSObjectみたいにどんなメソッドでも受け付けてくれる」ってふと勘違いして,コンパイルエラー。なんか愕然とするね。どうしてもキャストせなあかんのんか,キャストせな…って。
ワタシはC++育ちなので(かつ部署全体がC++系で,Java系がほとんどいないという,割と珍しい部署なので),Javaの人がどうやってこのキャストの嵐をやっつけてるのか非常に興味がある。そういう意味では今でもCだけでやれている人たちにも興味がある。
で,もう1つの「スタックにオブジェクト」ってのは,どっちかというとコンストラクタ・デストラクタとの組み合わせの問題かも。要はリソースの解放をスコープ抜けるときに自動でやってほしいってことなんだけど。
C#にはtry/catch以外にfinallyってのがあるので(Javaにもある?),それ使えばいいって話だけど,例えば3つのリソースを確保するコードを書くとすると,1つ確保するごとにtryブロックにしていく必要があって,どうしてもこの場合は3段ネストしなくちゃダメ。まあ,そんな感じでリソースを確保するごとに(?)どんどんネストが深くなっていく。C++はその点非常に楽チン。
ってゆっても,JavaやC#は,Objective-Cよりは例外を扱いやすい…てゆうか,ライブラリが例外を意識しているかどうか,という点で,かなり差があるわけで。
C++は標準ライブラリが(C#/Javaに比べて)へっぽこピーなんで,ある意味標準ライブラリを無視できる(すみません)し,Objective-Cは実装系が少ないこともあって,メジャーなのはNeXT Step系の(いまや)Cocoaしかなくて,それってば例外をあんまり意識してないし…。
言語とか標準ライブラリの生まれた時点で例外が設計されているかどうかってのは非常に影響が大きい。
JavaもC#(というかCLR)もその点では非常に恵まれている。
…はずなんだけど,.NETの例外クラスは,ひとことで言うと「ひどい」。
たぶん.NETで一番使えない部分は例外クラスの設計だと思う,いや,てゆうか設計されてないもん。適当にthrowしてるだけやんなあ…。
(ちなみに,一番ひどいのは.NET Remoting(JavaでいうRMI?)がリモートサーバで発生したすべての例外をキャッチしてTargetInvocationExceptionをなげること(とはいえ,一番かどうかは人それぞれだと思うけど)。そりゃないぜ,何のための例外だよ?)
…って,まあ,グチはあるものの,.NETというかCLRというか,その辺を含めて,C#って結構良くできてると思う。
side-by-side実行はぜひJavaに取り入れて欲しい。Oracle 9i入れると旅費精算システムが動かなくなるって何なんだよ…って,個人的なグチで済みません。
ただ,もし,仕事じゃなくて個人的に使うのなら?,ってことであれば,もしかしたらmanaged C++を選んでたかも。
やっぱりC++って,better Cっていっていいのか,テンプレートとコンストラクタ・デストラクタだけで,十分魅力ある。.NETでコンストラクタ・デストラクタとか使いたいもの。ArrayListやHashtableじゃなくて,vectorとか使いたいもの(mapは確かにHashtableとは比較しにくいけど)。
なんてゆうか,(C/C++的な)生メモリオブジェクトと(Java/.NET的な)ガーベージコレクション対象オブジェクトと(Objective-CとかCOM的な)参照カウンタオブジェクトとを明示的に使い分けられて,スタックにもオブジェクトを作れて,テンプレートもあって,かつ,クラスのメソッドを静的(仮想関数テーブル経由)にも動的(キャッシュテーブル経由)にも呼び出せるとかって言語があったら,飛びついちゃう。でもって,インタプリタとコンパイラの両方あったりなんかした日には!
ふと,インタプリタは無理にしても,それ以外の機能って,プリプロセッサ的な言語を作ればObjective-C++のソースとして食わせられるコードを吐くぐらいはできそうな気がするな,と思った。
というか寝ろよ>自分
こないだ会社で同僚と話していて,VB.NETはレイトバインディングができるので,C#でキャスト多発させて見やすくなくなっちゃうっていうのに比べて,その点だけは便利,って話を聞いて,そういえばそうか,って。
2005年2月16日
カブロボコンテストのグラフが表示されてない件
先日のエントリー「カブロボコンテスト中」からたどれるページには,参加者の成績とかがグラフで表示される,ってことなんだけど,なぜか表示されてないなぁと思ってたらWindowsでは表示できてた。
このグラフ,Flashで作ってあるようなんだけど,やはりFlashでも機種依存するのね。
いや待てよ?セキュリティとかの設定かな?
って,ちょこちょこ調べるも,結果分からず。
見えてる人いたら教えてください。
2005年2月14日
カブロボコンテスト中
1/15締め切り,ってことで1/15の昼にでもやろ,って思ってたら1/15の朝締め切られてたみたいで,登録できず。
11月ぐらいに作ったバージョンが生きてるはずなんだけど,3回のテストではパッケージ名を指定してなかったため(だと思うけど違うかも),動作してなかったんで,諦めてたら,どうも本戦ではマニュアル対応してくれたみたい。
現在71位てことで,どこまで行けるのん?(なんかもうトップには追いつけなさそう)。
ふと思ったのは,このコンテスト,賞金100万円なのね。
で,自腹でリアル市場に100万突っ込んだらちょっとの上げ下げは可能なんで(持ってる株にもよるけど数円程度?),1位取れそうなロボット作ってるチームは,差が詰まってたら売買しちゃうという手もないわけではないな,と。他のチームが同じことやったら意味ないけど。
いや,むしろ100万損するだけの値動きがなさそうであれば,数百万突っ込んでもペイするのかも。
ちょっと,いつだったか話題になったテロの起こる可能性に対して市場を作ってどうのこうのという事件を思い出した。
プレーヤがそこで得られる利益より少ないコスト(というかリスク?)で相場を左右できる市場はロクなことにはならないのね。
2004年12月22日
iPodが接続されたのを検知する
ListenToTheNewsicでは,iPodが接続(正確にはマウント)されたのを検知して,iPodリスト(正確にはポップアップボタン)に表示し,アンマウントを検知してリストから取り除いている。
参考にしたのは以下。
これだけだと(関数を実行したときに検出することはできても)マウント・アンマウントの検知まではできないので,同じくNSWorkspaceクラスの
NSWorkspaceDidMountNotification
NSWorkspaceDidUnmountNotification
の2つを受け取れるようにしておき,マウント時にiPodかどうかを上記の記事のように判定している。
ちなみにアンマウント後に来る通知のタイミングでは(当然のことながら)そのボリュームにどんなファイルがあるか調べることができない。
起動時およびボリュームがマウントされるたびに,それがiPodのボリュームかどうか調べて覚えておき,アンマウント時にはその情報で判断した。
その辺を扱うクラス(CNWiPodWatcher)のソースもアップロード。
2004年11月15日
シェアウェア?アフィリエイト?
話題の「特定商取引に関する法律」の件でもあったように,シェアウェア作者には「商売としてソフトウェアを販売している」というスタンスではない人がいる。
そんでもって,商売でないつもりの人が,商売だと思っている人から「それ商売としてどうなの?」と言われると,ビックリして焦る,という結果になる。
アフィリエイトも,ある程度市場ができあがってきて,収入も上がりつつある今,そういうケースが出てくる可能性を持っている。
はてなは,要はシェアウェア作者の会社なんじゃないかと思う。まだまだ「商売としてやってる」という感じじゃないんじゃないかな。まずはサービスというか機能の実装が楽しい状態。
いつかは突き抜けてくれることを期待して。
2004年11月 7日
例外処理
.NETってことでこれを会社で読んでたりするわけなのね。
カブロボでほとんど初めてJavaを触って(←それもどうかと思うが),なんというかさすがに.NETは後発なだけあって,Javaのごちゃごちゃっとした感じがないなぁと感じる。
で。
この本で気に入ったのが例外処理の章。
.NETに限らず,例外処理ってすんごい難しい。
try/catchがあったらOKって話じゃないよね。
だいたい誰でも1回はカッチョイイ例外処理の仕掛けを作ろうとして挫折してる。
(って断言していいのか?)
この本で言ってる,エラー処理と例外処理は違う,ってのもあれだ。言われるまで自覚したことがなかった気がする。なんでケースによって,例外をthrowしたりboolで返したりとかしちゃってた。
ともかく,言語とライブラリとそれからアプリ(の開発者)すべてが共通の認識・共通のポリシーで処理しないと,ちょっと見た感じはカッコ良くても,やっぱりワケ分かんなくなっちゃう。
誰かが「例外処理」とかって本を書いて,共通認識のたたき台となるような,そんな枠組みが欲しいなあ。
Tiger Early Start Kit for Developers
Tiger Early Start Kit for Developers には画期的なTiger製品を顧客に提供するために必要なすべてが含まれています。
ちょうど1年前のPantherのとき,$150だった。そんときはそれだけでもうすんごいお得だったんだけど,今回の$500はあんまりすごくない…。
なんというか,今後さらにAppleに貢ぐ予定のある人なら,もとが取れるかも,という感じ?
…と,ここまで書いてPantherのときのキャンペーンのメールを読み直したら「違ってた!」
やっぱり$500だった…。save over $150って書いてあったのね。
2004年10月24日
カブロボコンテスト
面白そうなので参加。
プログラムの言語はJavaということで,Macでも(UNIXの手順に沿えば)できるみたい。
サンプルプログラムを動かすとこまではできた。
(プログラムによって出力文字コードがEUCだったりShiftJISだったりしてなんだかなぁという気はしたけど)
2004年9月11日
こりずにAppleScript
正直言うとね、しんどいっす。AppleScript Studio。
で,Xcode 1.5にあげた今,今度はiTunesのスクリプティングに挑戦中。
やっぱりつらいっすわ。
まずね,ファイルリファレンスが取れない。
set theFile to file "test.txt" of folder "Desktop" of folder "kabeya" of folder "Users" of disk "RootSystem"
これはOKでも
set theFile to "RootSystem:Users:kabeya:Desktop:test.txt"
はエラー。もともとはCocoaから呼び出そうとして
set theFile to POSIX file to "/Users/kabeya/Desktop/test.txt"
(ちなみにルートボリュームの名前が「RootSystem」ね)
ってやろうとしたとこでつまづいたんだけど(てゆうか,iTunes関係ないし)。
こんな最初のほうでつまづくワタシが悪いのか,それとも何かインストールやら何やら環境のせいなのか。
ほんとに,AppleScriptも一般ユーザのための言語環境からプログラマのための言語環境に成り下がったなぁと(ん?成り上がったのか?<上がってない上がってない)
ウェブログ: AppleScript Studio & Xcodeメモ : 2004年11月22日 14:02
何か色々やっていたらできました(てか例文間違ってますね,set theFile to POSIX File "/Users/kabeya/Desktop/test.txt"ですね。toが一個余分)。
でできたほうの文は
set theFile to ("/Users/kabeya/Desktop/test.txt" as POSIX File)
って感じで。
この辺,どこがどう違うのか,今ひとつ分かりづらいすな。
こんにちは!
僕も、最近Xcode上でAppleScriptを始めました。ちょうど最初のテーマはiTunesでした。
どうぞ、よろしく!
(トラックバックさせていただきましたm(_ _)m)
どもどもです。
ソフトウェア名とかアイコンをどうするかという辺りで行き詰まってしまい(←バカ),しばらく放置してましたが,コメントをきっかけに改めて進めることにしました。
投稿者: kabeya : 2004年11月23日 13:01AppleScript Studioでゲームを作ってみました。
■漢字Mr.Wを捜せ!
http://www.appleco.jp/piyomarusoft/products_008.html
BGM再生とかクリア時のアニメーション、400個のボタン属性を1命令で書き換えたり、iTunesのMusic LibraryからBGMを選択したりと「AppleScriptならでは」の機能を多数実装しています。
投稿者: MARo : 2004年12月28日 11:162004年9月10日
シリアライズの話
そだそだ,帰りの電車の中で思ったことを忘れないように書いとこ。
ADO.NETとかってもなんだよ最後はやっぱりSQLかよ,と思ったことに関連した話。
もうほんとにあれだ,シリアライズっていうのが,なんか無駄じゃないかと。
世の中にはシリアルなものとそうじゃないものがあるんだけど,どういうわけかほとんどの記憶媒体ってシリアルなのね。なのでどうしても記録したり再現するときにシリアル化と逆シリアル化(そんな呼び方?って気がするけど,.NETのドキュメントに書いてあったので「逆シリアル化」を採用)しなくちゃなんない。実際にはもう少しシリアルじゃなくて2次元格子ぐらいにはなってるんだけど,せいぜい2次元。
メモリアドレスも,ディスク上のファイルも,バーコードも。逆にシリアルなデータって,音声と映像ぐらいしかないんではないかと思ったりするけど,それらにしてもヘッダやらチャンネルやら圧縮やらで,ほんとうにシリアルなデータってやっぱり簡単には思いつかない。
オブジェクトの持つツリーやらネットワークやらをなんつーか,そのままバチっと記憶できる仕組みがあるとずいぶん色んなことが変わる。メモリアドレスもシリアルじゃなくなるっていうと,いわば今の(ほんとのアドレスであるところの)住所みたいな階層構造になっちゃったりして,C言語とかのアドレスを直接演算できちゃう言語はどうするよ。
やっぱりタンパクとか使ってコンピュータ作るってのは,この辺のことを目指してるんだろうか。
.NET始めました
先週ぐらいから会社で。
まだちょっとしか触ってないけど,なかなかいい感じ。
いや〜でもほんと,いろいろいいとこどりしてるなぁと感心する。
ADO.NETは中でも出色と思う(ま,素人が見た感じなんであんまり当てにできない意見だけど)。
ただ,逆にADO.NETがここまでできるというのに,まだDBとのやりとりはSQLかよ,って気はする。
もう.NETオブジェクトを「そのまま保存!」ってできたらいいのにと。
ってゆうのに近いことができるのが,最近ちまたでバナーや広告を見ることが多くなった「Cach?」(このページの内部コードがEUCなんで,全角で書いちゃうけど)。「キャッシェ」と読むらしいですが(キャッシュじゃなくて)。
実際,これ会社でちょっと使ってみたけど,非常に面白いのは確か。これで内部で使えるのが「Cach? Object Script」じゃなくて,CLS準拠言語になったら,かなり気になる存在になるかも。
一時期,MacOS Xにも対応するって書いてあったけど,最近はその記述がなくなってて残念。
て,ちょっと横道に逸れたけど,.NET & C# 使ってて思ったのは,以下の2点
・Interface Builderってやっぱりよくできてるなぁ。特に差を感じるのがアウトレットとアクション。不思議に思うのが,なんでVisual Studioってウィンドウのリサイズに自動対応できないのか,って点。Power Plant Constructorですらできていたというのに(「ですら」とは失礼な>自分)
・Objective-Cのalloc/releaseはやっぱりなんとかして欲しい(笑)
Javaと比べると…,どうだろ,Javaもよく知らんけど,もしサーバサイドしか考えないなら実は.NETを使うメリットってそんなに大きくはないんじゃないだろうか。ADO.NETと,クライアントにも.NETを使える,という2つが最大のウリかなぁ。
MacOS Xも,CFPluginとか言ってないで.NETみたいなの(みたいって何なんだか)を早いとこ入れて欲しい。
ウェブログ: XO : 2005年3月22日 03:42
2004年9月 5日
インターフェイスビルダのバグ
しばらく前からXcode 1.5を使ってちょこちょこ作業してるんだけど…。
インターフェイスビルダでヘッダファイル読み直そうとしても「Read XXXX.h」がアクティブにならないんで,仕方なくその上の「Read Files...」を使うと,なんとそこで選んだファイルが消えちゃう!
最初,気のせいかと思ってたけど,どう考えても消えてる。
ヤなバグだねぇ。
2004年8月16日
Pascal
これって,AquaでのUIとかも作れるんだろか…。
試さないけど(←なんなんだ)。
2004年7月 9日
デスマーチの話
void GraphicWizardsLair( void ); //さん(ここに「さん」が要るのか?)経由。
元ネタはなんだろ,やっぱりゴールドラットだろうか。
ウチの会社(ソフトウェア会社)の原価計算も,まぁここにあるような直感とあわない(ここでは「疑ってもみなかった」ってあるけど,プロジェクト損益管理すると「疑いだらけ」になる)集計をしてるわけで。
例えば,社員を使うと高いから外注先を使う,でも社員は空いたまま,とかね。前は結構あった。
最近はもうプロジェクト損益はそれほど重視しなくなってて「ユニットとして」「課として」「部として」とかいう言い方が多い。
原価計算って,いわばゲームのルールなんで,実態と違う部分は当然あるんだけど,そんでも直感とあんまりにもずれたルールだと非常にやりにくいなぁと。それこそ逐一コンピュータに計算させないと,思ったようにならない。
空いた社員の分はプロジェクト損益には載ってこないものの,課の損益には載ってくるので「全プロジェクト黒字」だけど「課としては赤字」てケースもあり得て,で,ボーナス削減(笑)。これはかなり直感と違う。
そうは言っても,どのプロジェクトにも受注金額に見合う以上の人手をかけるわけには行かないんで(火がつきそう,とかついちゃったとかなら別だけど),その辺,どう考えるのかって,今後の展開が楽しみ。
2004年4月11日
Cocoa勉強会に行ってきた(4月)
Cocoa勉強会に行ってきた。
で,そんとき発表に使った資料をアップロード。
本職の人があまりいないせいなのか,各人の発表するネタがかなりニッチで,メシを喰うには要らないかも知れない知識なんだけど,オンラインソフト作者にとってはたぶんすごく面白いものばかり(少なくともワタシはそう思った)。
とはいえ,発表会自体,14時スタート21時終了はさすがにつらいし(まぁ今回はアップルストア銀座を借りたせいで,スケジュールが限られちゃったせいもあるけど),Cocoa勉強会のためだけに勉強するってこともしてられないんで,スケジュールや発表者の割り当ては考え直したいところ。
こう,なんていうか,今回のネタの背景って
・MySQLをMacで使いたい
・ADOとかDBIみたいな感じでやるには?
・ADOを調べる
・DBIを調べる
・動的にライブラリ(ドライバ)をロードする方法を調べる
・NSBundleを調べる
・CFBundleを調べる
・CFPluginを調べる
・COMを調べる
・DCOMを調べる(この辺はなんか横道にずれてる)
・SOMを調べる(この辺は調べるフリだけ)
・コンテクストメニューの現状について調べる(これもさわりだけ)
・COMをgccのC++でやる方法を調べる(CodeWarriorではできるけどgccではできないと判明)
・COMをgccのObjective-Cでやる方法を考える(なんかもうどうでもよくなってる)
・とりあえず共通で使える実装クラスを作るとした場合に,各DBMSごとのドライバの実装をどういう具合にするか考える
・継承/カテゴリ/デリゲートがCocoaでどう使い分けられているか調べる
・カテゴリがいつ有効になるか調べる
・C++でカテゴリみたいなことができるかどうか考える
・C++でdelegateみたいなことができるかどうか考える
・C++でできるデザインパターンとObjective-Cでできるデザインパターンについて考える
・継承した場合の関数,特に派生クラスの関数呼び出しについて調べる
・Objective-Cの引数渡しについて調べる→ありゃ!なんか思ってもみないことに?
てゆう長大なストーリーがあって(←バカ),途中にネタになりそうな部分はいっぱいあるんだけど,結局根本(最後の部分)から解決していかないと発表する側も自信を持って説明できないよな,と。
ここまでやると間隔が2ヵ月ってのはつらい。勉強会の準備だけして日々過ごしてるワケじゃないし。
てことで,4ヵ月に1回発表ぐらいが,サンデープログラマにはちょうどいいんで(ここからが重要),東京近郊に在住のMacユーザでプログラミングに興味のある方はCocoa勉強会にいらしてみてください。人数増えるとローテーションしやすいんで(笑)。
北海道なので勉強会には参加できないのが残念です。いつも拝見させていただいております。2004年4月の勉強会の資料をみせていただこうと思いましたが、ダウンロードできないようです。リンク修正いただけたら幸いです。
投稿者: doc-hiro : 2004年4月11日 08:482004年3月28日
さっそく?グラフソフト作成中
そんなこんなで、グラフ作成ソフトをちょこっと作ってみる。

だけどあれだ、NSBezierPathで描いたグラフをベクタ形式で保存する方法が分からん。
どうしてもビットマップになっちゃう。
この辺、CarbonでPICTなら簡単なのに。
一年前だし解決しているでしょうが、何もコメントないんで。NSData *data = [view dataWithEPSInsideRect:[view bounds]]; として、拡張子epsで保存すると簡単にEPS形式にできます。PDFにも。このへんが Cocoa のありがたい所。Illustrator 等で開くと編集もできます。ただいろいろ邪魔なもんも…。Quartz あたり直接いじりゃなんとかなるのかも…。ま、必要ないんで、調べてませんが…。
投稿者: kamluck : 2005年3月10日 19:30はじめまして。
「どうしてもビットマップになっちゃう。」が,ウソでした。
もともとベクタ形式で保存するところまではできてたんですね。
で,悩んでたのは,他のグラフィックソフトで編集可能なベクタ形式,ってところです。
「Illustrator 等で開くと編集もできます」って話ですが,IllustratorがないのでFreeHand MXで開いてみると,全部で1つのオブジェクトになってて分解できないんです。
なんかうまい方法があるんでしょうか。
投稿者: kabeya : 2005年3月14日 00:502004年3月18日
引き受けたいのはヤマヤマだけど…
以前、会社の同期が「あるソフトのMac版を作りたいから頼むかも」って言ってたのを又聞きしたっていう記事を書いた。
本気じゃないと思ってたら、今日、本人から非公式の打診が…。
まぁ、今の仕事も結構ノリノリなんで、それどころじゃないです、って断わったけど、それにしても、あるソフトとはあれか〜。ぜひやりたかった!いや、期間さえもらえれば、1日1時間程度ずつでもいけるか?
来期とか言ってたから、ちょっとずつやることも可能か?もうWindows版があるんだから仕様は固まってるだろうし。あ〜やっぱりやりますって言っちゃおっかな。ボリュームとだいたいのスケジュールだけでも聞いておくか←やる気になりつつあるバカ。
でも、MacOS 9でも動くようにお願い、って言われたらワタシ的には結構大変。
てゆうか、今からMacOS 9で動くMacを調達できるのか?
2004年3月15日
CocoaでMySQL
MySQLをG5にインストールして、Perl+DBIとかPHPとかでプログラムを作ってるんだけど、やっぱりCocoaから使いたい。
って誰かがインターフェイス作ってるでしょ、って調べると、MySQL Cocoa、ってとこ?
このMySQL Cocoaの一番のネックはGPL。Lesser GPLじゃないんだ。
DBMSのコントロールを主体とするツールなんかだったらGPLでソース公開、ってのも納得いくけど、なんつーか、DBにアクセスするのは手段であって目的じゃないからね。DBを利用するアプリのほとんどはDBアクセス自体に競争力があるのではない。
てこともあるし、PerlのDBIとかWindowsのADOみたいに、こう可搬性ってんですか、そういうのを持つライブラリが欲しいところ(DBIとADOではインターフェイスのでかさが違いすぎるけど)。
で、ぽちぽち作り始めてたり。次回Cocoa勉強会に間に合えばいいんだけど(間に合わなかったらネタがない…)。
2004年3月 6日
コードのように日本語を書く
何日か前のエントリで、分かりやすい文章をかきます、って宣言して、その後、いろいろ考えてたけど、結局、こういうことじゃないかと。
「プログラムを書くときのように、日本語文章も書け」
プログラムを書くときの注意点っていうのは、まんま日本語文章、とくに技術文章・ビジネス文章を書くときの注意点に当てはまる。
「関数には、その関数が何をやるのか分かりやすい名前をつけろ」
→「文章にはその文章が何を説明するのか分かるような見出しをつけろ」
「分かりにくい関数名しか付けられないとしたら、その関数は分けるべき」
→「分かりにくい見出ししか付けられないとしたら、その文章は分けるべき」
「変数の生存期間を短くしろ。ひとまとまりの処理にすべきものは近くにおくべき」
→「トピックの提示からその説明までとびとびにするな。関連する文章は近くにまとめるべき」
「コーディングスタイルは一定に。例えば例外処理をif節でやるのかelse節でやるのかなど、なるべく統一しろ」
→「文章スタイルは一定に。例えば、2つの項目を説明する際に、一方が仮説→検証という形をとるなら、もう一方も仮説→検証という形をとるようにしろ」
などなど。
ということはあれだ、名著「コードコンプリート―完全なプログラミングを目指して」ってのは、日本語を書く上でも非常に参考になる、ってことかもしれない。その観点で読み直してみよ(そういえば会社に持って行ってた)。
まぁでも「文章が下手な人のコードは汚い」なんてことは「思わない」。
単に、コードを書くときには気を付けているようなことを、日本語を書く際に意識しているかどうか、ということだけなんちゃうかと思う。
2004年2月29日
Mac開発で食ってる人の数は?
金曜日に会社で後輩から「壁谷さんの同期の人がなんかのMac版作るとか作りたいとか作って欲しいとかなんとか言ってましたよ」ってな話を聞いた。
まぁ、ワタシのMacプログラミングは趣味の領域を出てないんで、使えるアプリを作るってとこまでなかなか行かないし、向こうも「作って欲しい」っていうのは本気じゃないんだけど。
ただ、確かにウチの会社の既存の取引先(外注さん)でMac版作れるところってのは、たぶんない。
だいたい、Mac用のソフト開発で食ってる(食っていけてる)人は、100の位の前半、つまり200〜300人ぐらいじゃないかというのが、こないだのCocoa勉強会のあとの懇親会で出た結論。そんなに少ないの?
まぁ、MOSAのミーティングに行ったらほとんどの人に会えちゃう、ってのもあり得る話ではある。
2004年2月28日
Melt 0.2.1ソースコード
画面が溶けるスクリーンセーバ・モジュール、「Melt」のソースコードをアップロードしました。
いくつかポイントがあると思っています。何かの参考になれば。
- CoreGraphicsを使ったスクリーンショットの取り方
- 取ったスクリーンショット(32,000色・256色)をフルカラーイメージに変換する方法
- フルカラーに変換したスクリーンショットをNSImageで利用する
- NSBitmapImageRepから生データを取り出してAltiVecで変形する
- 「オプション」シートの作り方・使い方
- 「パスワードを要求する」がオンになっている場合用に、暗転させられちゃう前にスクリーンショットを取る方法(+ (void)performGammaFadeでスクリーンショットを取る)
質問があればこの記事にコメントしてください。
2004年2月26日
Cocoaで使うAltiVec
に、Cocoa勉強会2月定例会で発表に使った資料(の手直し版)をアップロードしました。
ほんとに入り口だけだけど。
2004年2月23日
Cocoa勉強会に行って来た
友の会の関根さん、みやくんに誘われて行って来た。
なんていうか、レジュメを用意して発表、なんてのはずいぶん長いことやってなかったので大変だったけど、他の人の発表も「ほう」というようなことがあって、なかなか有意義だった。
ちなみにワタシが発表したのは「Cocoaで使うAltiVec」。
最近勉強しはじめたばっかりなんで、たいした内容にはならなかったけど、割と好評でなにより。
発表内容はちょこっと手直しして後日アップロードする予定。
2004年2月22日
Cocoaバインディングが分かりにくいワケ:4
結局、あれだ。
NSControllerの派生クラスやIBのパレットを作ろうとしたときに、あれ?「Controller Key」のプルダウンには何が表示されるの?bindingsをbindするときはどうすんの?「なんか、仕組みを全然分かってなかった!」
ってなっちゃったのが、事の発端だったような気がする。
分かってないというより、知らされてない、ってのが正解だったような。
未だに、cocoa Bindingsを使いこなすまで、体系的に纏められた記事にお目にかかったことが無い。
断片的な記事が多く、「ふ~ん、なんとなく分かった。」でも、白紙から作り上げようとすると「何で?」になり、ちっとも進まなくなってしまう。
どっかに、良書はないものかいな?
投稿者: konsaider : 2008年9月 1日 16:51たぶん,この一連の記事にトラックバックをくれたHMDTさんの本がおすすめでしょう。
Second EditionでCocoaバインディングに触れられています。
Editionが第n版を指してるんじゃなくて,第n巻みたいな感じなので,Third EditionでもFirst Editionでもなく,Secondで。
http://www.amazon.co.jp/gp/product/4861001242/
投稿者: kabeya : 2008年9月 1日 22:182004年2月21日
Cocoaバインディングが分かりにくいワケ:3
前の記事からの続き。
再ツッコミをいただいてしまった。
で、だんだん分かってきた、のか?
組織図とかディレクトリのクラス構造でよくある、(まぁゆうたらTreeですな)、ノードとかリーフ。
中にデータを持っているのが「ファイル」(属性)で、中に「ファイルやディレクトリ」(プロパティ)=を持っているのが「ディレクトリ」(関連)、みたいな。
でね、そこまではいい。関連か属性かは、人間はすぐ分かる。
Macはどうやって判断しているかというと…。上の例でいえば、たいていisDirectoryとか関数があるはず。どっかでコンピュータが属性なのか関連なのかを判断する仕組みがあるはず。
…判断する必要はないのか。
そうか、Macが判断するんじゃなくて、プログラマが気を付ければいいってことか。
NSStringがさらに関連を持つかどうか、NSImageが属性なのかどうか、なんか判断する仕組みがあるんじゃないかと思ってたけど、そういうもんはないんだ。
たとえば、MyBDCNumberというクラスを作ってそれを保持する場合と、MyDocumentというクラスを作ってそれを保持する場合とがあるとする。人間は、前者は属性、後者は関連、って分かる。
コーディングがなくても、名前をみただけで分かる。
けど、Macはどう?普通に考えると、isAttributeとかがあるとか、属性は何かに登録するとか、何かから派生させる必要があるとか、とにかくなんか仕掛けがないと判断できないはず。でも「Macが」判断する必要はない。なぜだ?プログラマが間違えないようにするからだ…。本当か?
Key Pathをたどれるかどうか、事前に知る方法がどっかにあるんじゃないかと思ってた。
attributeKeysが何かやってるんじゃないかとか。
けど実は、挑戦してみて失敗したらエラーにするから失敗しないようにプログラムを作ってね、と。
たしかに、よほど複雑なのじゃない限りそれでじゅうぶんだし、複雑なのでもプログラマがんばれってことでいいと思うけど。
どっかで勘違いしはじめたんだろね。どこでかな。
ウェブログ: XO : 2004年2月22日 12:05
Cocoaバインディングが分かりにくいワケ:2
個人的には、「プロパティとはKVCのキーです。KVCのキーとは、ある規則に従ってメンバ変数またはメソッドの名前と関連づけられた文字列です」としたほうが、分かりやすいんじゃないかと思う。
attributesとrelationshipなんてのを持ち出すからややこしい。
もちろん、概念としてのattributesとrelationshipは分かる。けど、実装では何がattributesで何がrelationshipか?っていうと…
attributesはmutableなメンバ。…この説明は納得できる。
relationshipは?別のオブジェクトへのポインタ。…ちょっと待って。Cocoaでは(C++のように)メンバとしてオブジェクトの実体は持たせられないんで、すべてポインタ経由でしょ?だからattributesもポインタで保持しているんでしょ?ポインタをreleationshipとするなら、attributesとどう違うの?ん〜、見分けられない。
で、attributesとrelationshipをどう見分けるか、に対する一つの答えが「だから別に見分ける必要ないじゃん。どっちもプロパティでしょ?これがつまりKeyなんよ」っていうもの。これは説得力ある。
もう一つの答えが「NSObjectのattributeKeysで返ってくるのがattributes、toOneRelationshipKeysとtoManyRelationshipで返ってくるのがrelationship」。こっちはね、じゃattributeKeysとかで返ってくるのは何?っていう次の疑問が出てくる。
たぶんそれらが返すのは、「自分でこれはattributes、これはrelationship」って決めて、そのようにコーディングしたもの。
つまり自前クラスを作ったらクラスメソッドとして、自前クラスのattributeKeysなどを知っているNSClassDescriptionを返すメソッドを定義してやる必要がある(と理解してるけど…)。
しかし、先に書いたように、NSObjectControllerは、attributesKeysやtoOneRelationshipKeysで値を返してこない。
これが返してくれてれば、かなり納得できたはずなんだけど。
で、この2つの答え「attributesとrelationshipはとりあえず区別しなくていい」「クラスメソッドを定義して区別」を比べると、動きや利便性からみて前者のように考えないと納得がいかない。
だったら最初からattributesとかrelationshipはいらないし、もっと「プロパティとKVCのキー」について分かりやすく説明するべきでしょう、ということなのね。
「いったんそれぞれのビューにバインディングを設定してしまえば、この更新メカニズムを意識することはありません。実装の詳細を知る必要はありません(どちらにしろ非公開です)、メカニズムはただ単に動くのです。」
そんなんで納得できるかって、ねぇ。
ウェブログ: XO : 2004年2月21日 18:27
やっぱり、よくよく考えるとKVOはObservingで正解かな、と。
Notificationとの違いは「DefaultNotificationCenterがあるかないか」よりも、「Modelの値を更新したとき、Modelに通知する義務があるかないか」が重要じゃない?
Cocoaバインディングが分かりにくいワケ
なぜCocoaバインディングが分かりにくいか考えてみた。
いや、動きは分かる、じゅうぶん分かる。でも、どういう仕組みで動くのか分かりにくい。
Model ← KVC KVO → Controller ← KVC KVO → View
みたいな絵がCocoa Bindings:Support for the MVC Paradigmには描いてあるんだけど、これが実態を表わしてないせいじゃないか?
ControllerがModelに値を反映するのは、確かにKVC (Key Value Coding)で、これは疑いない。
機能もドキュメントになってるし。OK。
ところが、Modelの値の変化がControllerに通知されるのは? KVO (Key Value Observing) で、確かにこれはドキュメント化されてるけど、Observing、という名前とは裏腹に、実際は値を「監視」してるわけじゃない。
どっちかというと、中身の動きはNotification、つまり「通知」だよね。Notificationってのがすでに使われてるからObservingになったんじゃないかと思うぐらい。
KVCでModelの値を変えたControllerは、Modelに「あんたの値を変えましたよ」って通知する。
「変えましたよ」って通知を受け取ったModelは、自分に関心のあるObserver(この場合は、他のController)に、「値が変わったよ」って通知する。Observerは監視してるんじゃなくて、通知をお願いしてる。
同じことは、Controllerの変化?をViewが知るときにも行なわれているはず(違うかな)。
Controllerを監視する、っていうと何を監視するんだ?っていう疑問がわくけど、違う違う、本当は「Controllerから通知を受ける」んだね。本来の「監視」という意味に相当する処理は走ってないだろうと。
分かりにくいのが、ViewからControllerに向かってのびるKVCの矢印。
これが分かりにくい原因は、Interface BuilderのInfoパネルの「Bindings」ペインにある「Controller Key」と「Model Key Path」のせいじゃないかと。
「Controller Key」は分かるか?んー、Controllerのキー?なんかよく分からない。
じゃ、置いておいて、「Model Key Path」は?
プロトコル「NSKeyValueCoding」のリファレンスを引くと、確かにvalueForKeyPath:とsetValue:forKeyPath:ってのがある。
いろいろ試すと、forKeyPath:のところには「メンバ変数(Key)」.「メンバ変数の指すオブジェクトのメンバ変数(Key)」が指定できて、それを使って「リレーションをたどっていける」。
じゃ、IBに戻って「Model Key Path」に「Controllerのメンバ変数」.「Controllerのメンバ変数の指すオブジェクト(=たぶんModel)のメンバ変数」が指定できるか、っていうと、そうじゃないんだこれが。
「Controllerのメンバ変数」は「Controller Key」に設定するのであって、「Model Key Path」には「ModelのKeyへのPath」じゃなくて「ModelのKey(=メンバ変数)」を指定する。Pathが余分。
いや、そうでもないのか。Controllerのが指すのは直接関連するオブジェクトだけで、何もModelが単一のオブジェクトでできてるとは限らないからか。つまりModelのKeyにたどり着くのに、いくつものリレーションをたどる場合もあると。その場合は「Model Key Path」にmemberA.memberB.memberCのような長いPathを指定すればいい、と。
なんかそう言われれば確かにそうかも、って気がする。
で、最後、全体のまとめである、KVB (Key Value Binding)。
これは全然仕組みが分からない。
リファレンスに一部のヒントはあるんだけど、全体像は公開されてない。
試しにIBのパレットを作って、プロトコル「NSKeyValueBindingCreation」のメソッドを実装して(分からないところは適当にNSLogをかませて)、ウィンドウに貼り付けてNSObjectControllerとBindしてみた。
確かに、exposeBindingsで公開したBindingsは、Infoパレットに現われて、Bindできそうになる。
けど、そのあとbind:toObject:withKeyPath:options:で何をやればいいかってのが分からない。
ちょこっと考えると、toObject:のオブジェクトに、addObserver:forKeyPath:options:context:を送って、自分をObserverにすればいいのかな?ってとこなんだけど…。
また逆に、Controllerのほうも、「Controller Key」がどっから取得されているかっていうのが謎。
単純に考えると、NSObjectのメソッドtoOneRelationshipKeysで取得、なんだけど、実際にNSObjectControllerのインスタンスにtoOneRelationshipKeysを送ってもnilが返ってくる。ってことは何か別の方法が?
むー。あんまり今の段階でKVBについて調べてもしょうがないんだろね。
ウェブログ: XO : 2004年2月21日 13:04
2004年2月14日
Cocoaバインディングの件
「プログラム上でNSTextFieldにsetStringValue:を使って値を変更する」ってどういうケースなんかなぁ。
ちょっと考えて思いつくのが、NSStepperとNSTextFieldを組み合わせたよくある奴。
![]()
こんなの。
これって、NSStepperかNSTextFieldをもう一方のtakeIntValueFrom:に接続すれば連動させることができるけど、変更した値が即座にモデルに反映されるようにするには、ちょっとコツがいる。
Cocoaバインディングを使わない場合、
・NSTextFieldをNSStepperのtakeIntValueFrom:に接続
・NSStepperを自前コントローラのモデル更新メソッドに接続
・NSTextFieldのdelegateに自前コントローラを設定して、自前コントローラにcontrolTextDidEndEditing:を追加し、モデルを更新する
の3ステップになる(もっとうまい方法があるような気がするけど)。
これって、考えてみると変。
NSTextFieldもNSStepperもコントローラを知っておかなきゃなんない。連動してるんだから、本来、どっちかが知ってりゃいいはずなのに。
Cocoaバインディングでも事情は似たようなもので、NSTextFieldやNSStepperのtakeIntValueFrom:はモデルを更新しないみたいなのね。
そんなら両方バインドしちゃえ、ってことになっちゃう。
「NSStepper+NSTextFieldで一つのコントロール」ってできるはずなのに、それぞれでコントローラを知っている状態。なんか無駄だし、整合性をいちいち取るってのもね。
「プログラム上でNSTextFieldにsetStringValue:を使って値を変更する」ってこういうケースなんかなぁ。
2004年2月12日
64bit Mathオプション
よくよく見ると「Code so generated will not run on 32-bit processors.」って書いてあった。
iBook(G3 500MHz, OS 10.2.8)で動かないんで、なんでかなぁと思ってたけど、Crash Reporterのログを見ると、乗算を行なっているところで落ちてるんで、コンパイルオプションを再確認。
ってことで、Use 64-bit MathオプションはG5でしか使えない(当然か)。
> Use 64-bit MathオプションはG5でしか使えない
違う違う、
Use 64-bit Mathオプションを使ったプログラムはG5でしか使えない
の間違い。
投稿者: kabeya : 2004年2月12日 06:51デバッグシンボル
Xcodeのビルドスタイル設定でGenerate Debug Symbolsをオンにしておくと、プログラムがクラッシュしたときにCrash Reporterがどこでクラッシュしたか、ソースファイル名:行番号まで出力してくれる。
クラッシュログは~/Library/Logs/CrashReporterに吐かれる。
こりゃ便利。
AltiVecのマニュアル
モトローラのAltiVecのページにはマニュアルがおいてあって、AltiVec Programming Environments ManualとAltiVec Programming Interface Manualの2つが入手可能、のはずなんだけど、後者はリンクが切れてる。
PDF file search (altivecpim)で入手可能。
(もしくは切れてるリンクのURL中のALTIVECPIM_D.pdfっていう部分をALTIVECPIM.pdfって書き換える)
2004年2月 5日
ARGB->RGBAの変換
結論は、unsigned long longを使えば速くなる、ってことにしちゃう。
unsigned long long argb;
unsigned long long rgba;
rgba = ((argb << 8) & 0xFFFFFF00FFFFFF00LL) | ((argb >> 24) & 0xFF000000FFLL);
このコード、そのままだと32bitローテート(rlwinm)が使われるみたいで、unsigned longを使った場合と速度はほとんど変わんない。
でも、ビルドスタイル(DevelopmentとかDeploymentとかのこと)の設定で「Use 64-bit Math」ってのをオンにすると64bitローテート(sldiとかsrdi)が使われるようになる。
64-bit Mathのオンオフを変えてアセンブラコードで比較すると、long long以外のところも結構変わるので、実は常にオンにしておいたほうがいいのではないかと(違うんかなG5だからかな)。
ともかく結果的に1280×1024の変換で0.7秒→0.4秒に短縮することができた。
なんかもうちょっと速くなる方法がありそうな気がするけど。
amanoさんとこの記事経由で、飯森さんの記事にたどり着きました。
最初、なんか色味が違う!って思ったけど、記事自体、RGBA→BGRAという変換だったんですね。
AltiVecバージョンをARGB→RGBAに書き直して0.4秒→0.3秒に。
で。飯森さんのバージョンが元メモリをそのまま書き換えてたので、その方式で計ると、確かにそれだと0.01秒かかんない。
なんでこっちは0.3秒もかかるかというと、元画像とは違うところに変換後の画像を作ろうとしているからで、
*rgba = henkan(*argb);
という今の方式では、henkanがどんなに頑張ってもargbからのロード&rgbaへのストアで時間がかかっちゃってて、あるところ以上は速くならないみたいなんですね。
AltiVecはよく知らないんですが、ロード&ストアの命令もあるみたいなので、ちょっと勉強してみたいと思います。
投稿者: kabeya : 2004年2月 6日 07:282004年2月 4日
PPCのintrinsic functionを使いたい
ARGBとRGBAの変換(RGBとアルファチャンネルのデータの並び順変換)をするのに、8バイト×4を左8ビットローテートすりゃいいんだけど、Cにはローテートがないんで、
unsigned long argb;
unsigned long rgba;
rgba = (argb << 8) | (argb >> 24);
こんな感じになっちゃう。
これが結構遅くて、G5 1.5GHzで1280×1024のデータを変換すると0.7秒ぐらいかかる(一瞬0.4秒台の時があったけど、気のせいでしょう)
で、マシン語にはrlwinmとかいうローテート命令があるんで、それを使って直接ローテートしちゃおう、と。
CodeWarriorにはPPCのマシン語を直接実行しちゃうようなintrinsic functionがあった(らしい)んだけど、gccでそれをどうやるか、ってのが問題。
実は、ppc_intrinsics.h、ってのがDeveloper Toolsにはあって、そこにマクロで__rlwinmって定義されているんで、これを使えばいい、はずなんだけど、これ使うとどうもコンパイルできない。
さてどうしたものかと。
こんにちは。おそらく、ご存知でしょうが・・・
inline assembler は CW と同じように使えるみたいですね。
Xcode From a CodeWarrior Perspective : Inline ASM
ここの下の方にも Macro の intrinsic についてちょっと書いてあります。
投稿者: amano : 2004年2月 4日 12:19どうもです。
このドキュメント、どっかで見たなと思ったら、/Developer/Documentationの中にもありますね。
で、確かにドキュメントに書いてあるように、
s = __rlwimi(s, n, 8, 23, 23);
ってやるとコンパイルが通る。でも
s = __rlwimi(s, n, b, 23, 23);
だと通らない。
なに言ってんだか分かんないメッセージが出てコンパイルエラーで止まっちゃう。
いろいろ試行錯誤しているうちに、8ビットローテートは
rgba = __rlwinm(argb, 8, 0, 31);
と書けばコンパイルできる、ということが判明。
8を変数にするとダメみたいです。
そういうもんですかね。
で、気になる速度の比較結果は…
「まったく同じ!」
え〜?
デバッグ版だと、inlineて書いてあるのに関数呼び出しみたいな感じでコンパイルされて、むしろ遅いという結果に。
すっぴんの状態ですら
rgba = (argb > 24);
が
rlwinm argb, 8, 0, 31;
みたいにコンパイルされるみたい。
よくいう「最適化するな。計測しろ」ですね。
この場合は先に逆アセンブル結果をみておくべきだったというか。
自分のサイトで少し言及 したところ、フォローいただきまして、ちょっと前の macosx-dev-jp の投稿 を紹介していただきました。お知らせまで。
Bobolin jest sielskim oraz ładnym miejscem istniejącym na drodze pośrodku, między kurortami Dąbki i Darłowo. Charakterystyczny klimat szczególnie dobrze wpływa na górną część dróg oddechowych. Oddziałuje na to istotnie zadbane otoczenie, ogromna odległość od akumulacji komunalnych, estetyczne plaże Bałtyku oraz lasy sosnowe również wypełnione jodem powietrze. Piaszczysta plaża w Bobolinie to jedna z najczystszych i w najwyższym stopniu okazałych plaż nad naszym morzem. Bobolin plus okoliczne Dąbki spojone są dróżką do spacerów także dla rowerów. Bobolin to także perfekcyjne położenie do uprawiania jazdy konnej - właśnie w tym miejscu na dżokei potrzebujących spektakularnej przygody czekają przejażdżki o zachodzie słońca kresem morza do Darłówka i Dąbek. Wyszperasz tutaj mnogość wygodnych i tanich pensjonatów, jak Domki letniskowe EL-DAR, Domki letniskowe FALA, Villa Quarto, Pensjonat "Babilon", Dworek Nadmorski, Domki Letniskowe Fala, AmberWilla, Ośrodek Domków Letniskowych SUNSET, Pokoje Gościnne Małgosia i wiele innych. Całość czego zdołasz wyszukiwać pod określeniem Pokoje Nad Morzem wynajdziesz w naszym letnisku. Wystarczy wstąpić na stronę internetową i wybrać przydatny ośrodek. Nawet nie obejrzysz się kiedy będziesz już w drodze nad morze. Jeżeli organizujesz przyzwoicie wypocząć - zaakceptuj nasze przywołanie.
投稿者: Geammergy : 2011年11月25日 02:552004年2月 3日
GCCでのlong long
全然知らなかったけど、ISOのC99という規格ではlong long型が正式サポートされている、ということらしい(ワタシが知ってたのはC89という規格、ということなんかな)。
で、MacOS Xの正式コンパイラであるところのGCCではC89モードでもlong longがサポートされている。って別にCodeWarriorもずいぶん前からlong longサポートがあったので覚え書きをするほどでもないんだけど。
覚え書きするのは、long longのときの定数の書き方。
long定数は0xFF00FF00L、のようにLを末尾に付ける。
long long定数は0xFF00FF00FF00FF00LLのように、LLを末尾に付ける。
unsignedの場合はそれぞれUL,ULL。
知ってる人には「なんだ今さら」って感じだけど。
2004年2月 1日
NSBitmapImageRepの16bit対応
イメージをレンダリングするのには、NSBitmapImageRepを使うらしい。
のだけれども、なんかこのクラス、使いにくい。
イニシャライザの名前が、
(id)initWithBitmapDataPlanes:(unsigned char **)planes pixelsWide:(int)width pixelsHigh:(int)height bitsPerSample:(int)bps samplesPerPixel:(int)spp hasAlpha:(BOOL)alpha isPlanar:(BOOL)isPlanar colorSpaceName:(NSString *)colorSpaceName bytesPerRow:(int)rowBytes bitsPerPixel:(int)pixelBits
こんな感じで長いのはまぁしょうがないとしても。
このイニシャライザに渡す最初の変数は、イメージバッファへのポインタなんだけど、RGB&アルファチャンネルの順番を指定する方法がない。プレーンごとかピクセルごとか、ってのは指定できるのにね。
で、一番使いにくいのは、16bitモードが、なんと4bit×3原色の12bitしか喰わないこと。
bitsPerSample=4 samplesPerPixes=3 bitsPerPixel=16の組み合わせはOKなんだけど、5,3,16の組み合わせだと、ログに
Inconsistent set of values to create NSBitmapImageRep
って出て失敗する。4bit×3原色だと4096色にしかならない。お前はFM77AVかと(古くてすみません)。
ともかく、ほんとに4096色の次が1670万色なのか?
2004年1月23日
MovableTypeで表示が途中でおかしくなる件
ときどきMovableTypeを使ってるサイトで、ある記事が途中で終わったり、途中から他の記事と混ざったり(!)してるのを見ます。
どうもSafariがUTF-8をうまく表示できないケースがあるってのが原因らしいのね。
(Spread Your Wingsで知りました)
Unicodeは実装(の方針、というべきか)難しい部分が色々あるので(従来の文字コードとUnicodeの対応に関する諸問題など)、なかなか大変(Safariのバグの原因がそういうことに関係するのかどうか知りませんが)。
へえ、知りませんでした。私はまだIEなんですよ(^^;)
うちの日記はどうかと思って試してみたらとりあえず大丈夫みたい? これからはチェックしないとなぁ。
いやいやいや、実は浅利さんところで気が付いたのでした(笑)。
日によって(?)複数の記事が混じっているときがあります。すごいですよ。え?って思うもの。
投稿者: kabeya : 2004年1月24日 01:50ネーミングの方法
ネーミングの作り方
「ネーミングの作り方」という日本語?が気になるけど、ネーミング。
やっぱり、名前が最初にズバッと決まると、あとがやりやすい、というかやる気になるし、コンセプトを守りやすい…のか?どうなんだ?
ところで、上記のところに書いてあるかどうか、隅々まで見たワケじゃないんでなんだけど、「日本人はなんでもかんでも省略したがる人種である」ってことが重要と思う。
改めてコンピュータソフトウェアのネーミングを考えてみると、日本人に受ける「4文字以内に略せる」っていうのがあんまりない。
- マック(ソフトウェアじゃないけど)
- ネスケ
- ハイパカ
- フォトショ(普及してないか)
- イラレ(これもか)
- ニセン(Windows 2000 Professionalだけど、なんとWindowsとProfessionalが略されていて2000だけ残ってる!ちなみにWindows 2000 Serverは「ニセンサーバ」)
- ことえり(何かを略したように見えて実は略してない!)
ところが、「メルマガ」「ホムペ」「メアド」など、どう考えても「それ略しにくくねぇか?」というものが省略されることもある。こういうのはホントに市民権を得たんだって感心する(そういう意味では「パソ」がすでにPersonal Computerの略、というのがスゴイ。Super Computerを「スパコン」と略す勇気にも拍手したい。Superって氾濫してるけど、そのわりにスパと略してるのって他に思いつかないもの)。
その一方で「インターネット」が意外と略されないのがフシギ。「ネット」っていうのが微妙に省略形なのかどうなのか判断の難しいところ。「イントラネット」は「イントラ」になってるのに。
C++よりC#のほうが普及するのは、コーディング自体の読みやすさのせいというより、言語自体の名前の読みやすさのせいか?普通読めないよね、C++。
ていうかコンピュータ知らない人の前で…
「シープラプラ」
プラプラ?プラプラて…(間抜け?)
「シーシャープ」
ふーん、何それ?
「オブジェクティブシー」
てめぇ俺にゃわかんねと分かってて難しいこといってんだろ!
なんかもうちょっと言いやすい&覚えやすい名前を考えてもらいたい、ってのと同時に、自分もまぁそのへんを意識して考えていきたいと思った。
2004年1月18日
サンプルプログラムのライセンス
/Developer/ExamplesにあるAppleのサンプルプログラムのライセンス(ソースコードの先頭に書いてある奴)を訳してみました。
どの程度、使って良いのか気になったもので。
シートウィンドウの現れ方
友の会の忘年会で話題になっていたことの一つに、
「シートウィンドウの現れ方が2種類あるけど、その違いが分からない。
同じAPIを使っているはずなのになぜか別の動きをする」
てのがあった。
2種類というのは「スルって出てくるやつ」と「ビヨ〜ンってかぶさるように出てくるやつ」の2つ。
特に後者の「ビヨ〜ン」てのはPantherで初登場なんだけど、確かにどういう条件で?というのが不明だった。
で、判明。
ソースウィンドウの幅よりシートウィンドウの幅のほうが広いと「ビヨ〜ン」で、狭いと「スルッ」。
Jaguarで試したところ、「ビヨ〜ン」に相当するものがジニーエフェクトになってて、「スルッ」ってのと微妙に違うけど、まぁ区別しにくい。
なんか、違う感じにする必要があることなのかどうなのか。
2004年1月15日
tar/gzip/zipのファイル名文字コード
よくよく考えると、あれですね。どれだ。
DropDiskImageってStuffItの日本語ファイル名の問題がどうたらとかえらそうに書いてたものの、ファイル名の文字コードの問題はgzipにもzipにもある、ということを思い出したので書いときます。
えと、アーカイバってもう20年前からすごい数あって、まぁたぶんその辺の処理内容って当時からそんなに変わってないんでしょう。
当然ファイル名はchar配列で取得、というような処理になってて、文字コードはASCII前提、日本語は(DOSのShiftJISだと)表問題とかで通らない場合もある。けど、とりあえずそこだけパッチ、みたいな感じでずっと来たんじゃないかと思います(違ってたらごめんなさい)。
圧縮ファイルなりアーカイブファイルなりに含まれているファイルの名前ってのは、そゆことで実行環境から標準的な手段で(readdirとかで)得られる文字コードそのままで保持されている、と考えるのが素直です。わざわざファイル名の文字コードをアーカイブの中に保存している、ってのは少ない、というかワタシは見たことない。
tarやgzip, zipも例外でないわけで。
なのでDropDiskImageで日本語名のフォルダをディスクイメージファイルにして、さらにgzip/zipで圧縮すると、gzipやzip自体は可搬性があるのに、そのファイルはMacOS X以外の環境では復元できないことがあります(現にWindowsで作成されたzipファイルの中にはMacOS Xで復元できないものがあります。StuffIt Expanderは何か文字コードの判別処理を持っているらしく、だいたい復元できちゃうんですが)。
.dmgてばMacOS X以外の環境で復元ってのも(今は)考えにくいんですけど。
なんかそう考えると文字コードを保持したアーカイブフォーマットがオープンソースで欲しいですね。
なんか「まだtar?」って気もしますし。
# squash/squeeze/squelchとか、CP/Mのアーカイバだかアーカイブフォーマットだかには、なぜかsqu〜が多かったのを思い出してしまいました。日本語で言うと「ぺちゃ」「ぺしゃ」「ぶちゅ」ぐらいのイメージなんでしょうね。
2004年1月12日
Cocoaのマニュアル
そろそろCocoaのリファレンスマニュアルを誰か書いてもいい頃だと思いませんか<って誰に問うている?
oomori.comさんでもいいんですが(リンク切れてませんか?)、ともかく紙で。
今までで一番よかったリファレンスマニュアルは、NECのPC-8801 mkII SR付属のN88-BASICリファレンス。
不思議と後継機種のmkII MRに付いてた同リファレンスはいまいちだったのね。
何がよかったのか、改めて考えると、
- 小さめB5サイズ(確か。もう20年も前だから忘れちゃったけど)
- 1ページに1関数(BASICだからステートメントだったり関数だったりするけど)
- それぞれの関数にサンプルコードと出力結果がついてた。サンプルも重要なら出力結果も重要
- なぜか「SCREEN スクリーン」みたいに読み方も書いてあった(笑)。中学生だった私にはこれ重要。「RUN」を「ルン」って読んでた同級生もいたからなぁ。BASICには「NULL」も「WARNING」もなかったけど、仮にあったら「ナル」「ウォーニング」って書かれたのかなぁ
またいつものように話が横道にそれちゃったけど、ともかく今のHTML版リファレンスは使いづらいなぁという話でした。
NECといえば、私は内容はともかくPC8001(無印)のマニュアルがリング綴じで見やすかったのを覚えています。
#開いたままで置いて置けるので。
あとPC9801シリーズのPC-UXのマニュアルは記載が丁寧でよかったです。全部で30センチ以上ありましたからね〜。私はこれでUNIX入門です。いまでも数冊とってあります。
リング綴じは良さそうですね。
リング綴じなマニュアルは最近見ませんね。
てゆうか最近は紙でマニュアル付いてくること自体あんまりないですしね。
オンラインマニュアルに紙のマニュアルと同じような使い勝手を求めると、オンラインマニュアル専用のモニタが欲しくなるのが困りものです<物欲王
2004年1月11日
eclipseを使ってみる
ふと思い立ってEclipse (2.1.2)を使ってみた。
Mac版のスピードってどうよ?ってことだったんだけど、思ったより速いというかやっぱり遅いというか。
たぶん「十分実用的」っていう言い方が正しいのかも(ちなみにマシンはG5/1.5GHzです)。
日本語化および日本語入力については「エクリプス」の「日本語化」記事で。
コマンド+スペースが言語切り替えにならず、Eclipseのコンテンツ・アシストに喰われちゃうので、「ウィンドウ」→「設定」→「ワークベンチ」→「キー」→「編集」→「コンテンツ・アシスト」でcommand+Spaceを「除去」。
よくよく考えると、Classic MacOSだとアプリがコマンド+スペースを捕らえることなんかできなかったのが(MacOS XのCarbon Event Managerはよく知らないし、Cocoaではもはや全然意識してないんでClassic MacOSが例になっちゃうんだけど)、Javaだと手前でキーハックができちゃう。
それ考えると、Mac版のJavaで日本語のインライン入力ができるまでの道のりって遠そうだなって。
2004年1月 2日
AppleScript Studio
amazonのバナー見てたらAppleScriptの本もいくつかあって、「そういえばAppleScript Studioって何?」ということで、たどりついたのが上記ページ。
この中にAppleScript Studioの入門もあって、さっそく挑戦。
Appleのサンプルコードなんかも参考にしながら1つプログラムを書こうと。
正直言うとね、しんどいっす。AppleScript Studio。
せっかくなので頑張って最後までAppleScriptで書き上げるつもりですが、途中、原因不明の動作があったので、AppleScriptからObjective-Cのメソッド呼び出して回避したりして。なんだこれなら最初からObjective-Cで書いた方が良かったと。
ちょっと気が付いたことをメモ。
- TabView上のコントロールはそのコントロールが載っているTabViewItemがアクティブになっているときしかアクセスできない。なので2枚のTabViewItemがある場合に、例えば初期設定値を設定しようと思ったらset current tab view item of tab view "xxx" to ...て感じでアクティブなTabViewItemを切り替えて1枚1枚アクセスする必要がある
- どういうわけか、PopupButtonのcurrent menu itemが動作しない。いや動作するんだけど、1回ポップアップメニューをクリックするまで設定&取得ができない。しょうがないので、結局Objective-Cを使って、call method "selectItemIndexAt:" of theObject with parameter myMenuIndexみたいな感じで設定。取得はset myMenuIndex to call method "indexOfSelectedItem:" of theObjectで実行
- 同様にMatrixもcurrent cellが設定&取得できない(気がする)。ので、こっちはタグ使って、call method "selectCellWithTag:" of theObject with parameter myCellTagとset myCell to call method "selectedCell" of theObject/set myCellTag to call method "tag" of myCellで
なんでつらいのかも書いておこう。
- デバッグしづらい(どうやってデバッグするの?今回はprintデバッグの亜流、display dialogデバッグで対応)
- Objective-Cだったらアウトレット作って接続すれば、あとはどういう具合にそのコントロールが他のコントロール上に配置されているか意識しなくても済む。AppleScript Studioだと、そのコントロールが例えばWindow → TabView → TabViewItem → Box → Matrix のButtonCell、みたいなのを常に意識させられる。それぞれのコンテナオブジェクトに名前付けておく必要があるし、指定漏れがあればワケの分からないエラーメッセージが表示されるし、コーディングも長くなって見落としが発生しやすい
- Xcodeにバグがあって、Info.plistの内容をXcodeから編集できない。Project Builderを使えば編集可能
HyperCardぐらいの気軽さで取り組めるものってないものかと。
ウェブログ: XO : 2004年9月11日 21:15
日付から考えると、Xcode 1.2の登場前のお話でしょうか。たまたま検索エンジンで調べものをしていたらたどりついたので書いておきます。ご存知でしたらスルーしてください。
■デバッグ
イベントのログを取るのは辛いですが、オブジェクトの内容などであれば、ダミー変数に入れるようにして、その行をブレークポイントに設定しつつデバッグを実行。ブレークポイントでダミー変数の内容を確認できるので、それでデバッグが行えるでしょう。変数の内容を確認したいだけであれば、log命令も使えます。
■Info.plistの内容編集
できます。3ペインの表示にしないと内容をいじくれない部分もあるので、そのあたりの話でしょうか。
どうもありがとうございます。
Xcodeは1.1ですね。まだ1.2にはしてないんです。
試してみてもやはり1.1だとブレークポイントで止まったりしないし,Info.plistも編集できないので,1.2からできるようになった,ってことでしょうかね。
1.2にしますか。
AppleScript Studioに関していえば、Xcode 1.2のほうがよいと思います。
AppleScriptに関しては日本に担当者もいないし、Xcodeなどのツールもまた然り。USに直接文句を言っていますが、なかなか動いてくれませんね(^ー^;
投稿者: MARo : 2004年5月25日 11:34ということは?
ブレークポイントで止まったり,ログも出せたりってのが1.1でもできるということですかね。
謎です。私んとこは何がイかんのですかね。
(まだ1.2入れてません…)
結論からいうと、そういうことになるかと(汗) ただし、ログは「log」命令を使って、文字列しかログウィンドウに表示することはできません。リストやレコードや数値などは文字列にしないとログ表示は無理です。ただし、「AE Monitor」を使うことで生のAppleEventすべてをログ出力することは可能なので、それを参考にするという方法もアリでしょう。生AppleEventの判読は、自分はできかねるので……一応ご参考までに。
ブレークポイントについては、止められる場所と止められない場所があるのかもしれません。ハンドラの先頭行とか、特定のハンドラとか。load scriptコマンドで読み込まれた外部のScriptについてもブレークポイント対象外です。
投稿者: MARo : 2004年6月 5日 01:322003年12月28日
nibファイルを分ける
忘れちゃうので覚え書き。
例えばMail.appなんかだとnibファイルが50近くに細かく分けられている。
nibファイルを分けると何がいいか、っていうのは、ほんとのとこよく分かんないんだけど、個人的には
- アプリケーションの起動が早くなる。メインバンドルにすべてを突っ込んでしまうと、その中のオブジェクトをすべて読み出して再生するのに時間がかかる(ってアーロン・ヒレガスの本に書いてあった)
- nibが分かれていることで再利用しやすいモデル・ビュー・コントローラを設計できそうな気がする
で、まぁnibファイルを分けてみよう!ってことになった場合に困るのが、nibファイル間でconnectできねってこと。
例えば、Cocoaドキュメントベースアプリケーションの雛形を選んでプロジェクトを作成するとMainMenu.nibとMyDocument.nibっていう2つのnibファイルができる。
MainMenu.nibにはメインメニューがあって、MyDocument.nibにはドキュメントウィンドウがある。
MyDocumentクラスが例えばドキュメント中の選択してるオブジェクトの種類によって、受け付けるメニューコマンドを取捨選択できたら便利じゃない?
けど、MainMenu.nibにあるMainMenuからはMyDocument.nibのアイテム(ウィンドウその他のオブジェクトやインスタンス化されたオブジェクト、それにFile's OwnerやFirst Responder)に向けて線を引っ張ることはできない。
ところが、Mail.appはメインのメール一覧画面とフォルダ用のドロワー画面が別のnibファイルになってて、もちろんメインメニューもそれぞれのnibにあるわけじゃなくて雛形同様、一個のnibにある。
けど、フォルダ用のドロワー画面はメインメニューの「メールボックス表示」からのメニューコマンドを受け取って、NSDrawer#toggle:を受け取ってる。
これ、どうやってるのつって調べてみると、「メインメニューから、メインnibファイルのFirst Responderに向けて線を引っ張ってる」。
Mail.appのMailViewer.nib(Mail.appのメインnib)のFirst Responderにはなぜか「showMailBoxesPanel:]っていうアクションがある。
確かにshowMailBoxesPanel:っていうアクションがFirst Responderにあれば。レスポンダチェーンをたどって、異なるnibファイルにあるオブジェクトにもメッセージが届くだろうと想像できる。レスポンダチェーンにshowMailBoxesPanel:を処理できるオブジェクトがいなければ、そのメッセージは無視されるだけ。
ほんでも、なぜMailViewer.nibのFirst ResponderにはshowMailBoxesPanel:っていうのあるの?なぜワタシのMainMenu.nibのFirst Responderにはないの?これどういうことよ?
いろいろ調べた結果、Interface Builderの「Class」タブ画面で、NSObjectにぶら下がっているFirst Responderには手動でアクションを追加できるということが判明。
なんかね、いろいろファイル読み込ませたり、色んなボタン押しまくったりしたんだけど、分かっちゃうとなーんだって感じ。
この「Class」タブ画面では、クラス?によって、動きが3種類に分かれる。
- NSObjectなどの既存クラス:グレーで表示される。派生クラスの作成ができる。アウトレットは追加できない。アクションは追加できる(カテゴリ機能があるせいか?)対応するソースは作成できない
- 既存クラスから派生させて作った自作クラス:黒で表示される。派生クラスの作成ができる。アウトレットもアクションも追加可能。対応するソースを作成できる
- First Responder:黒で表示される。派生クラスの作成はできない。アウトレットは追加できない。アクションは追加できる。対応するソースは作成できない
ともかく、First Responderにアクションを追加してメッセージを送ると、他のnibファイルにあるそのメッセージを処理できるオブジェクトがレスポンダチェーンに載ってれば、正しく処理される。
載ってなければ処理されない(例えばメニューなら自動的に不活性になる)
ただ、First Responderに例えばshowMailboxesPanel:を追加しても、実際にどこかのクラスにshowMailboxesPanel:っていうメソッドが追加されるわけではないことに注意。
あくまで線を引っ張るためだけにアクションを追加するのね。
線を引っ張ることさえできたら、そこからObjective-Cの特徴である動的バインドが有効に働く。
この仕組みがない場合、NSBundle#loadNibNamed:とかでロードする際にポインタをつかんでおいて、半ばアーリーバインド的にメッセージ送信せざるを得ないんだけど、この仕組みがあればポインタをつかむ必要も、ポインタをつかむオブジェクト(デリゲートを兼ねたような奴)を作ったりする必要も全然ない。
2003年12月16日
XcodeというかMacOS Xでの各名前の扱い
絶対忘れるんで覚え書き。
Xcodeには色々名前を設定するところがあって、ざっと気づいたものでも
- Xcodeアイコンのところで「情報を見る」と「一般」タブで表示される「名前」
- ターゲットのところで「情報を見る」と「一般」タブで表示される「名前」
- 同じくターゲットの「一般」タブで表示される「プロダクト」
- 同じくターゲットの「プロパティ」タブで表示される「実行可能ファイル」(Info.plistのCFBundleExecutable)
- Info.plistのCFBundleName
- さらに、自分でできあがった.appの名前を変えてつける「パッケージ名」
という6つの「名前」がある。
何個かルールを見つけたので挙げておくと、
- Xcodeアイコンのところの「名前」は、プロジェクトファイル名に使われるが、(Xcodeがプロジェクトファイルを開いているので)実質編集できない。変える場合はXcodeのプロジェクトを閉じて、Finderで変える
- ターゲットの「名前」はビルドの際に中間ファイル保存先として使われるほか、「ターゲット」の一覧に現われるが、実行ファイルには一切関係ない(ゼロリンク時はパスがかかれちゃうらしいので、デバッグ版では関係ありそうだけど)
- プロダクト名はアクティビティモニタやDragThingのプロセスドックで表示されるプロセス名として使われる
- CFBundleNameはAppleメニューの隣のNew Applicationの代わりに表示される
- パッケージ名はDockで表示される
- CFBundleExecutableとプロダクト名が異なっていると、Dockにアイコンが表示されず、メニューバーにもメニューが現われない(バックグランドアプリになるみたい、だが、Classicのバックグランドオンリーアプリと違って、ウィンドウは表示することができる)
まあ正直言ってややこしいだけなんだけど、さらにややこしいのは、日本語で名前を付けるとビルドできなくなる「名前」があるということ。
単純に考えて怪しいのは「ターゲット名」なんだけど、CFBundleExecutableも日本語を付けると失敗する。ということは「プロダクト名」も同じにする必要がある(でないとメニュー使えないし)。
て、いうところなんだけど、なぜか「アクティビティモニタ」や「コンソール」は日本語名がアクティビティモニタに表示される。
これは一体全体?
2003年12月15日
NSUserDefaultsの動作
NSUserDefaultsの動作でちょっとハマった。
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
って感じで登録すると、~/Library/Preferencesの下にplistができる、と思ってたんだけど。
答えは否、というかこれだけじゃダメなのね。
どうも、plistに書き込むタイミングってのは、デフォルトと違う値をNSUserDefaultsに設定したときらしい(かつ、イベントループが回ってきた適当なタイミング)。
なので、開発中なんかで、デフォルト値をコロコロ変えているような場合でも、デフォルト値から変えなきゃ追従してきてくれちゃう。
迷うのはデフォルト値の書き出しがうまく動いているか動作確認するような場合。
変えない限り書き出されないってんで、確認のしようがない。
2003年12月 9日
Pantherから変わったCDのコピー
3日連続でなんなんだという気がしますが、友の会の忘年会より。
Pantherになってから、CD-ROMに乗っかってるファイルのコピーが変わったね、っていう話。
具体的には、JaguarまでCD-ROMからFinderを使ってコピーしたファイルやフォルダは書き込み可能だったのに、Pantherからは書き込み禁止でコピーされるようになった、なんでだ?改悪では?っていうもの。
CD-ROMには書き込めないからって、そっからコピーした後のファイルやフォルダを書き込み禁止にする必要はないだろう、という意見ね。
ただ今日、他のOSの動作もちょっと調べてみて、結局、このPantherの動きがもっとも正しい処理だろうと。
まず従来のFinderのコピーの問題点っていうのは、コピーしたときにパーミッションのモードが変わっちゃうっていう点で、モードが変わって困るようなもんはFinderでのドラッグ&ドロップじゃなくてインストーラでインストールさせなさい、ちゅうようなこともAuthorizationあたりのドキュメントに書いてあった(という気がする)。
具体的には、JaguarではCDかどうかによらず(これがミソ)、とにかくFinderでコピーするとフォルダについてはchmod ugo+wを実行したような、ファイルについてはchmod u+wを実行したような感じにすべて変わっちゃう。フォルダのset-GIDビットとかstickyビットとかは落ちたり落ちなかったりで、まぁよく分かんない。ファイルのset-UIDビット類は落ちちゃうみたい。
ともかく、Finderでコピーしたときに、Jaguarではモードが変わってた。
んで、Pantherでは基本的にcpと同じでモードが変わらなくなった。
こういうことなんでしょう。
Finderでコピーするのがデータファイルだけなら、確かにJaguarのような動きの方が好都合。
ところが、アプリ(今はBundleなんで、パッケージの中身のモードが変わっちゃうのは怖すぎ)とか、例えばcgiのディレクトリとかをFinderでコピーすると、モードが変わっちゃうってのは、もうこれ、あかんですよ。
PantherのFinderのほうが、動きとして安全なのは間違いないところ。
なんせ、このご時世だし。
2003年12月 8日
CarbonかCocoaか?
昨日の忘年会の話で。
正直、CarbonなのかCocoaなのか、どうなの?
って話が出た。
これね、たぶん「CarbonかCocoaか」っていうキーワードで認識している人が多いと思うんだけど、実際は結構複雑。
前提条件として検討すべき項目も
1)CFMかMach-Oか
2)言語をどうするか(Objective-C/Java/C/C++)
3)Classicを対象にするかどうか
4)開発環境をどうするか(CodeWarrior/Project Builder)
ってのがある。
言葉で書いたら分かりにくかったので、表にしてみると、
CFM |
Mach-O |
|
| CodeWarrior | サポート |
サポート |
| Project Builder/Xcode | 未サポート |
サポート |
CFM
|
Mach-O
|
|
| MacOS 9以前 | サポート
|
未サポート
|
| MacOS X上のClassic環境 | サポート
|
未サポート
|
| MacOS X(ネイティブ) | サポート |
サポート |
Carbon API
|
Cocoa API
|
|
| MacOS 9以前 | サポート
|
未サポート
|
| MacOS X上のClassic環境 | サポート
|
未サポート
|
| MacOS X(ネイティブ) | サポート
|
サポート
|
C
|
C++ |
Objective-C
|
|
| CodeWarrior | サポート
|
サポート |
未サポート
|
| Project Builder/Xcode | サポート
|
サポート |
サポート
|
Carbon API
|
Cocoa API
|
|
| C | サポート
|
未サポート
|
| C++ | サポート
|
未サポート
|
| Objective-C | サポート |
サポート |
確かにわかりづらい。
上記の質問に似た奴で、
・CocoaにしちゃうとCarbon APIが使えなくなるんじゃないの?
・CocoaにしちゃうとSTLが使えないんじゃないの?
Carbon APIは、Cocoa APIと混ぜて使えるし、Mach-Oでも使えるし、Objective-Cでも使えちゃう(ただしJavaからCarbon APIが使えるかどうかは不明)。
Cocoaを使ってても、同時にSTLも使えるので心配不要。C/C++の標準ライブラリも使えちゃう。
もちろん、例えばNSStringの実体をvectorに入れたい、のようにObjective-Cの言語仕様のせいで無理なケースもあるんだけど(Objective-Cはスタックにオブジェクトを作れないので)。
Objective-CとC++を同時に使うのをAppleはObjective-C++と呼んでるけど、単に同時に使えるだけなんで、Objective-CにもなくC++にもないような新しい言語拡張は一切なし。2つのちょっと違う言語を混ぜたにしては、小細工がなくていい感じ。
Model-View-ControllerのモデルだけC++で作って、ビューとコントローラをObjective-C/Cocoaで作る、ってのも可能。
逆(モデルだけObjective-C)は、ビューをゴリゴリC/C++で書くことになっちゃうので、やめた方がよさげ。
ところで、一番悩ましい質問が何かと言えば
・Cしか知らないんだけど、次に覚えるならObjective-CとC++のどっちがいい?
ごめんなさい。答えられません。
てか、Objective-CはMacではいいけどツブシが効かないし、C++覚えてもCocoaは使えないんで、Javaを覚えてください。ってのはダメ?
※ 2004/01/27 読み直したら、とんでもなく読みにくかったので直しました。
ウェブログ: XO : 2007年11月 4日 02:18
CarbonとCocoaは割と直交しているんだけど、重なっている部分もある。
それはイベントループとウィンドウ周り。
CarbonはCarbon Event Managerを使ってるのに対し、CocoaはNSApplicationに自前のイベントループ(NSRunLoop)を持っている。
CarbonはWindowRefを使っているのに対し、CocoaはNSWindowを使っている。
CocoaのウィンドウからWindowRefを取ったり、WindowRefからNSWindowを作ったりとかできるようにはなっているんだけど、いまんとこあんまり実用的じゃないような気がする。
投稿者: kabeya : 2003年12月23日 18:202003年12月 2日
Xcodeのビルドスタイル設定
Xcodeでビルドスタイルを設定する方法が分からなくて困ってたけど、ようやく発見。
左側のグループとファイルでXcodeアイコンの付いたプロジェクト名の行を選んで「情報を見る」もしくは「インスペクタを表示」。
こりゃ分からんわ。
ずっとターゲットのまわりを探してた。ターゲットのところで情報を見ると、コンパイラオプションが並んでて、中には「ゼロリンク」とかもある。
ゼロリンクをオフにしたいんだけど、ってゼロリンクのチェックをオンオフしてもビルドスタイルがDevelopmentだと必ずオンになっちゃう。
結局は、上に書いたような手順でビルドスタイルの設定画面を表示させると、そこにも「ゼロリンク」があるという寸法。
5年くらい前までのMS製品かよ!
改善したつもりで改善になっていないのはよくあることだけど。反省>自分。
2003年11月29日
MS VisioとOmni Graffleから見るターゲット層の違い
今日、社用でMSのOffice 2003のデモを見せていただく機会があった。
Office 2003つってもWord/Excel/PowerPoint/Accessではなくて、
Visio/Project/InfoPath。
もともとの企画意図からは結構離れたデモだったんだけど、それ以上に勉強になった。
例えばUML図。
確かにお絵かきツールでUML描けます、ってのはあったけど、本気で描こうとするとRoseとか必要、って感じがしない?→ってひよって見えない人に聞いてどうする。
(どうでもいいけど、Roseって高すぎない?UMLって金かかるんだって思っても不思議じゃない。お三方の給料が高いせいかもしれないけど、MSならいくら給料が高くてもこういう値段はつけないんちゃうかと)
ところがVisioならRoseより1桁安い割りには結構いけるじゃない、って気がしました。
ところがMacはといえば、G5にもバンドルされているOmini Graffle。
ほとんど使ってないというほうが正しいけど、やっぱりお絵かきツール(どうでもいいけど、なんで「お」絵描きツールって妙な「お」を付けちゃうの?)の域を出てないって気が。
他のツールよりきれいにできるとは言えども。
もちろん、 UMLだけじゃないよVisioは。
もう、ドキュメントをいかに綺麗に書くかっていう時代はWindowsではとっくに終わってて、どう共有・再利用するかっていう時代になってる。
MacはCOMに対抗するはずのSOMが影も形もなくなった今、OpenDocの後継はJavaですよって言うならば、CocoaでもCarbonでもなくJavaをメインにすべきだと、思ったりもするけど、どうなんですか(ってまたひよって見えない人に聞いたりして)。
ほんでね。
ここで言いたいのは、Microsoftは、100人・1,000人・10,000人にソフトウェアを売る方法ってのを考えていて、そういう方向で製品を作ってる。
一方のAppleはiPod/iTunesですよ。G5ですよ。iMacですよ。Ginzaですよ。
これね、そのまま行けば全く別のカテゴリを発生させる可能性があるね。
で、しかもその方がAppleにとって好都合。
Mac or WindowsじゃなくてMac and Windows。
iPodの宣伝は改めるべきじゃないの?
ってVisioとかGraffleと関係ない方向に行っちゃいましたか。
2003年11月22日
Programming for Panther
http://developer.apple.com/membership/pantherpromo.html
とりあえず。11/21までらしいし。
↑終わりました。
今になって調べたら、上記キャンペーン、実はずいぶん前からやっていたと判明。ウチには11/7の時点でメールが来てたけど見落としてた!
内容はっていうと、ADC Select Membershipが$150で申し込みできるというもの。ちなみに今から申し込むと$500です。Mailing Membershipでも$199します。
2003年11月12日
Linuxから目覚める僕らのゲームボーイ
Wataru's memoの「Linuxから目覚める僕らのゲームボーイ」が今、話題沸騰中。
理屈から言っちゃうと、MacOS Xでもgccをクロスコンパイル用にコンパイルし直せば(なんか分かりにくい?)、MacOS Xから目覚める…ってのも可能なはず(本の中身を知らないので全然確かではないけど)。
Developer Tools/Xcode Toolsに入っているgccは当然 PowerPC&Darwin用にコンパイルされてる(gcc -dumpmachineで確認できる)。
USBケーブルへのアクセスってのが難しいかも知んない。
ウェブログ: Slack Kingdom : 2003年12月10日 13:59
ケーブル付とはいえ結構いい値段するんですよね。この手の物に弱い私はつい買っちゃうんですよね。USBが単なるシリアルだといいんですけどね。
投稿者: EVA Titer : 2003年11月13日 13:12わたしも買っちゃうと思いますね。
ゲームボーイもいっしょに(笑)
USB周辺機器のプログラムって作ったことがなくて、.BOutとかのシリアル時代の知識しかないんでどうしたものかと。
あ〜、本買っちゃいました。対象はGBAでした。
USBケーブルへのアクセスは何のことはない、付いていたlibusbがMacOS Xに対応していたんで、ほとんどそのままで動きました。
念のため書いておくと、
1. 付属CDからGBA_BOOK/optusbフォルダをHDのどっかに丸ごとコピー。
2. Pantherでは書き込み禁止フラグが立つので、chmod -R u+w optusbで書き込み可能にしてね
3. tar zxvf libusb-0.1.7.tar.gz を実行して
4. cd libusb-0.1.7
5. ./configure
6. make
7. cp ./.libs/libusb.a ..
8. cd ..
9. 適当なエディタでMakefileの2行目のgccの行のケツに「-framework CoreFoundation -framework IOKit」を追加
10. make
で完了。
いろいろ調べたら
っていうサイトを発見。
本に付いているoptusb.cは1.0.1なんですが、libusbが少し古いので、最新版をCVSでゲットしてきたら無事動作しました。
2003年11月 6日
復刊ドットコムで再び
しばらく前から例の復刊ドットコムでコンピュータ・プログラミング」復刊特集ってのが催されてる。
コンピュータの世界ってのは移り変わりが激しいので、たいていの本は復刊しなくてもええんちゃうかと思うんだけど、息の長い技術、例えばUNIXとかC言語とかっていうのの潜在需要はある一方で、原典・古典が絶版になっちゃってるってこともある。なんせMacがUNIXになったっていうのですら最近の話だし。
中でも復刊をお願いしたい(というか、英語版の最新版にあわせて改訂版を出して欲しい)のが、前にも書いた「H&Sリファレンス」。
今はどうしてるかっていうとVC++についてるヘルプを使ってるんだけど、H&Sの記述にはかなわない。
まじめな話、お願いします。
って誰に何を?
2003年11月 4日
KVCと可視性
Pantherから加わったKey-Value Coding(KVC)。
「名前」でオブジェクトのプロパティを参照・設定できるっていうもの。
C++とかじゃ考えられない(いや共有ライブラリとかからGetProcAddressみたいな関数でひっつかまえてこればできないことはないんだけど)この仕組み、よくよく考えると可視性を無視しまくりじゃん!
Objective-CはC++のclass同様、デフォルトのメンバ変数の可視性はprivateのはずですが、KVCを使うと、それがNSObjectControllerにまる見え。アクセッサがなくてもアクセスできちゃう。
ただし、アクセッサがあればそっちが使われるという、「へぇ」な仕様になってる。
為替計算機の例でいえば、ConverterクラスにsetDollarsToConvert:ってメソッドをつければ、テキストフィールドの値変更時にそれが呼ばれるし、つけなければメンバ変数dollarsToConvertが直接変更される(名前の付け方はKVCのドキュメントに書いてある)。
ロバストなプログラムを作ろうと思ったらアクセサをきちんと作っておいた方がよいね。作んなくても動いちゃうけど。
なんかね、C++と比べるとあまりにもすべてが動的すぎて怖い部分もあるってのは事実。
2003年11月 2日
Controllerに挑戦
HMDTのコントローラに関する翻訳を見て、早速XcodeでControllerに挑戦してみたですよ。
オリジナルの題材が為替計算機だったんで、こっちは利息計算機を移植?してみようと。
ところがよ。
オリジナルの為替計算機ってのは、モデルがすんごいシンプル。
変換レートと金額から、変換後の金額が計算される。
AppleのKeyValue Observingの解説に載ってるサンプルもシンプル。
ファーストネームとラストネームからフルネームが得られる。
モデルとしてはすごくすっきりしていて申し分ないんだけど、現実はこんな簡単な関数従属性をもつモデルばっかりじゃない。
この利息計算機も、例えば借入金額を変えると出力としての支払総額・利子総額・支払月額の3つが変わる。ところがサンプルのように支払総額の値を取得するときに計算して、利子総額の値を取得するときに計算して、支払月額の値を取るときに計算して、ってなことになると、同じ計算を3回も繰り返すことになっちゃう。
計算は1回だけして、結果をそれぞれの変数に取っておいて、あとはそれを返すだけにしたい。
で、どうしたかっていうと、ダミーのオブザーバ(テキストフィールドとか)を作って、計算ルーチンを監視させる。で、ダミーのオブザーバは不可視にしておく。
確かじゃないかも知れないけど、オブザーバは登録した順に呼び出されるようなので、支払総額・利子総額・支払月額の前にダミーオブザーバを登録する。
あれ、思ったよりまどろっこしい?
ダミーのオブザーバを使わない場合は、手動でオブザーバを登録することも可能(addObserver:forKeyPath:options:context:とobserveValueForKeyPath:ofObject:change:context:を使う)らしいので、ちょっと試してみるけど。
なんかもうちょっとすっきりさせる方法があるような気がするんだけど。
モデルに、計算の経過値をプロパティとして加えればよいのでは?
経過値は、借入金額、実質年率、支払回数に依存。
支払総額、利子総額、支払月額は、経過値に依存、という
具合でどうですか?
これはこれは。mkinoさんにコメントいただくとは光栄です。
で、実は最初にやったのがご指摘の奴です。
ところがこれだと経過値が支払総額・利子総額・支払月額のいずれか1つでも変わったら必ず変わらなければならないという制約があります(実際、同じ経過値を返したら表示が更新されなかった)。
値が絶対に異なるように返せるというのであればよいのですが、どんな値を経過値として返すかよく考えないと、思わぬバグを作り込むことになりそうです。
借入金額・実質年率・支払回数のいずれかが更新されたら計算ルーチンが実行されるところまではOKなので、例えばstatic変数で計算回数をカウントしておいて、計算経過値としてはその回数を返すという方法も考えられます。
確かに、これはこれでうまく動きますが、なんだかモデルとしては横道に逸れちゃってる気がします(計算回数を返すってのが何なのか、特にKeyValue Bindingだとコーディングに依存性が現われないので、他人から見ると分かりにくい)。
いろいろ試行錯誤したところ、借入値→計算経過値、計算経過値→支払値と連動させるためには、サンプルの為替計算機からいくつか修正が必要、と分かりました。
為替計算機の場合、レート・総額のいずれかが更新されたらコントローラ(=オブザーバ)によって、変換後の値を計算するamountInOtherCurrencyが呼び出されますが、この呼び出しってのは変換後の値を表示するフィールドとコントローラがバインドされていることにより実行されています。
ところが計算経過値をどこにも表示しないとなるとコントローラとバインドすべきフィールドはなく、コントローラは計算経過値を取得するルーチン(=計算ルーチン)を呼び出しません。
対処方法は試行錯誤の結果、2つ発見しました。
1つは(最初に書いていた)非表示のフィールドを追加するというもの、もう1つはinitのなかでaddObserver:forKeyPath:options:context:を使ってオブザーバを登録し、observeValueForKeyPath:ofObject:change:context:のなかで計算ルーチンを呼び出す(これも最初に書いてましたが)、というものです。
で、計算経過値→支払値ですが、借入額→計算経過値はトリガーがある(テキストフィールドならtextShouldBeginEditing/textDidEndEditingとか拾ってるのだと思います)のに対し、計算した結果が変化したかどうかはトリガーがないので、自前でトリガーを組み込みます。
計算経過値を返すところでwillChangeValueForKey:とdidChangeValueForKey:を使って値を設定するのです。こうすると、計算経過値の変化をコントローラが拾ってくれるようになって、支払額も更新されるようになります。
もうちょっと整理したらソースをアップロードするようにします。
ソースコード拝見しました。
なるほど、これはちょっと面倒ですね。
やられているとおりに、Interface Builder とは別に、
observer を設定するのがいいと思います。
でも、このぐらいの計算量だったら、
メッセージパッシングを重ねることのパフォーマンスを考えると、
各フィールドが、毎回計算したほうが速かったりして。
そうですね。まったくご指摘通り、この件に関しては支払側パラメタの参照時にそれぞれで計算関数を呼んだ方が理解しやすいし速いと思います。
ただ、これがDBやネットワークにアクセスしたり、膨大な計算をするようなものだったりすると、何らかの方法でキャッシュしておく必要がありますね。
最初は、あれどうやるのかな?って思ってやったことなので、あんまりサンプルとしては適切じゃなくなっちゃいました。
ただ、もう少し簡単にできるのかなと思ってたので、結局「手動でオブザーバ登録」てことだと、なんかこうすっきりしないですね。
もう少し画期的な方法があるような気が。
Interface Builderでやれるようなことだと良いんですけど。
2003年10月25日
iTunes for Windowsと開発
HAPPY Machintosh Developing TIME!によればiTunes関連は(DLLやOCXじゃなくて)静的リンクされてるため、ほとんど何もできない、ってことですが。
iTunesと一緒にインストールされるiTunesHelper.exeは、COMサーバになってて、iPodServiceと、iPodManagerっていう2つのインターフェイスを持っているみたい。
このうち、iPodManagerっていうほうは、たぶん、既定のユーザインターフェイスを表示したりするだけだと思うけど、iPodServiceのほうはなかなか面白そう。
- BeginTransfer/EndTransfer
- LockiPod/UnlockiPod
- FindFirstiPod/FindNextiPod
- Mount/Unmount
- GetDiskSize/GetVersionInfo
- DeviceName/OwnerName
- LaunchApplication/HomeApplicationID
とかってのが見える(他にもあります)
なんか、ちょっと触ってみたくないですか?
ウチにはiPodないんで触れないんだけど(わはは)
英語版のファーストリリースではiTunesHelper.exeが常駐していましたが、今の4.1.1では起動しなくなりました。
10MBぐらいメモリを食ってたので、ものすごく評判悪かったんでしょうね。
iTunesをダウンロードした人がみんなiPodを持ってるってわけじゃなくて、むしろAppleは持ってない人にiPodを売りたいんでしょうから、しょっぱなから印象悪くしてもしょうがない。
揚げ足を取りたい人はいっぱいいるんだし。
ところでATOKは「あげあし」を「揚げ足」って変換しますが、揚げ足って、下足の唐揚げみたいですな。
投稿者: kabeya : 2003年11月10日 03:502003年10月 7日
フリーのDB
G5のキーボード、時々入らないキーがあって大変っていうグチは置いておいて。
フリーのDBシステムが欲しいなと思う今日この頃。
いや、もちろんMySQLとかPostgreSQLとかあるのは知ってます。
ただこれらは結構ちゃんとしたDBMSなので、インストールとかバックアップとかそれなりに大変。
欲しいのはAccessとかFileMakerとかのファイル共有型DB。
要は自作のソフトでDBを使いたい、組み込みたいんだけど、Macだと手頃なのがないなぁと。
知らんだけかな、ってか探してないだけかな。
WindowsならもうAccessで決まりと思うんだけど。
なんつってもエンジンを使うだけならAccess本体がなくても動くから。Jet EngineがWindowsで標準的に備わっている、というのか、開発側がAccessを持っていれば、実行時にはAccessは不要(あ、AccessのマクロとかVBAじゃなくて、ODBC/DAO/ADOとか使った場合ね)。もちろんメンテとかするのには必要なんだけど。そんでもメンテするユーザってのは限られてるんで、この辺は非常に助かります。
かといって、UNIXに備わっているdbmを使うかって言うと…。
FileMakerのMacOS XバージョンがODBCとか使えればいいんだけど(使えるのかな。製品ページみたけど分かんなかった)。
評価版(実はG5にインストーラがプリインストールされてた)をインストールするとFileMakerのODBCドライバのインストーラもインストールされる。
(なんてややこしい状況なんだ。「インストーラがプリインストールされてて、そのインストーラでインストールすると、さらにインストーラがインストールされる」ワケ分からんわ)
ほんでもって、「お読みください」に書いてあるのが
------
9. ODBC について
9.1. Mac OS X でのODBC
9.1.1. FileMaker Pro ODBC ドライバのインストーラによってインストールされるドキュメントでは、ファイルメーカーPro 6 に含まれないか、またはファイルメーカーPro 6 でサポートされていないODBC ドライバが参照されています。現時点でサポートされているのは、FileMaker 4.0 Text ドライバのみです。このドライバのテクニカルサポートについては、DataDirect Technologies 社ではなく、ファイルメーカー社にお問い合わせください。
-----
全然分からんわ、と思ったのは私だけですか?結局、OS XでODBCが使えるかどうかとか、FileMaker 4.0 TextドライバってのはFileMaker Pro 6.0とどういう互換性があるのか(ないのか)、とか、そもそもサポートされているという4.0 Text ドライバがインストールされるのか、とか。
ちなみに、ODBCドライバインストーラでインストールしても、ドライバは使えません(ウチだけ?評価版だから?)。
投稿者: kabeya : 2003年10月 9日 01:21結局、ApplicationフォルダにDataDirect ODBC folderってのができていて、そっちにODBC Configureってのがあって、そいつのドライバ一覧にはドライバ名が表示されてるってのが判明。
でも試す前に試用期間がきれちゃったのね(わはは)
投稿者: kabeya : 2003年12月23日 16:412003年10月 2日
トヨタ式人づくりモノづくり
という本を買ったですよ。自動車産業のモノづくり、っていうか生産を勉強しようと思って。
そしたら、なんですか。CMMとか言っている奴は、このトヨタ生産方式という奴の、まあいわば二番煎じ。
早い話、コンピュータソフトウェアでもまったく同じだと感じたわけです。
私の働いている会社(ソフトウェア会社です)の生産性が低いからかも知れませんが、ありとあらゆるメーカー、食品・機械・電気・ソフトウェア・医薬品、あるいはもしかしたらサービス業の人も、いっぺんこの本(もしくはその他のトヨタ生産方式に関する本)は読むべきだと、思ったですよ。
ワタシは(個人的に)日本のモノ作りを応援したい派です。
トヨタ生産方式、と呼ばれるものの目玉は「仕掛け」です。日本企業が好きな「仕掛け」なんです。
トヨタには「仕掛け」を成長させる「仕掛け」がある。
こう読んだわけです。
コンピュータソフトウェアの世界では「CMM」(能力成熟度モデル:Capability Maturity Model)というのが、いかに組織的に品質向上をできるか、の尺度として使われています(いることが多いのです?)が、トヨタ式というのはその最高レベルである5に相当するのでは?と思うのです。
いかに属人的要素を排除し、組織として品質を確保するか、というのが、それが工業として成り立つかどうかの分かれ目だとワタシは考えています。
職人に頼っていては工業ではない、それは工芸である、ってのはどこかで聞いた話です。
ワタシは「トヨタ式」の強さはそれこそ「人づくり」にあると考えています。どうやってそこにいる人を育てることができる会社にするか。
最近は個性の時代ってことになってきているのかも知れませんし、プログラマってのは「個人の哲学」がわりと重んじられる世界なんですが、それでもなお、「組織の力」というのを重視したい、と思います。
2003年9月24日
Dockへのアプリ名称の表示
自作ソフトの「パスワード忘れちゃう ?」なんだけど、実行するとDockには英語名「ForgetPassword ?」が表示されちゃう。
Info.plistにフラグを設定すると、Dockが勝手に翻訳するらしい。
うそ。
たぶんパッケージに入っている実行ファイル名が表示されてんだろう、と考えてたんだけど、MacOS Xに付属の「Preview」は、どういうわけかDockに「プレビュー」って表示される。
やるなDock。日英も英日もどっちもこなすとは。
ま、バカなこと言ってないで、どうやって表示名が切り替わるのか調べないと。
Pantherになったら「パスワード忘れちゃう?」ってDockに表示されるようになってました。
Japanese.lprojの下にInfo.plistを置いて、そんなかのCFBundleNameに「パスワード忘れちゃう?」って書いてあるんで、それが効いているんじゃないかと。
JaguarまででなぜForgetPassword ?と表示されてたかは不明。
2003年9月19日
多重継承の問題(2)
なかなか寝付けないので続き。
こういう感じで在庫情報とか受注情報とかって、顧客ごとに追加データがあるのが常なんだけど、じゃあそれが全くホントにその顧客固有かっていうと、そんなことはない。どっかで見たことある、っていうのが普通。
で、基底クラスから派生クラスを複数作ったのはいいけど、これらの派生クラスのいくつかを再合成したくなる、ってわけなんだけど、それやり始めるともうぐちゃぐちゃね。仮想基底クラスとか同名関数のオーバーライドとか大変。
一つの解決策は追加データクラスとかヴァリアントクラスとかって作っておいて、基底クラスのメンバ関数にGetCustomDataとかって作っておいて、Four Char Code (Macでおなじみの'TEXT'とか)を引数に渡して、派生クラスでそのFour Char Codeに対応する追加データを返す、ってやり方。
追加データの処理は追加データクラスの派生クラスに一切任せてしまえば、在庫情報クラスの派生クラスは合成しなくても、GetCustomDataだけ新しく作って追加データ部分はそのまま再利用できる。
もう一つの解決策がtemplate。
template <class BaseClass>
class WithKeiro : public BaseClass
{
// 省略
};
みたいな感じで、基底クラスをテンプレート引数にしておいて、派生クラス側の実装をすべてtemplateにしちゃう。
ってこの考え方は「修飾」の提案って文章で知ったもの。
ほんでちょっと考えたのは、基底クラスを仮想デストラクタだけ持つクラスにして、すべてのメンバ関数・メンバ変数をtemplateで書けば、ものすごい自由度があるんじゃないの?ってこと。
別に関連性の高いメンバがそのtemplateになくっても、例えばファイルをオープン・クローズする関数を持つtemplateクラスを作ったとして、そのtemplateクラスのメンバ変数にファイル名とかなかったとしても、templateの頭に「このtemplateはGetFileNameを持つクラスを基底クラスとして要求します」とかって書いておけばいい。
まあ、実際にやってみたんだけどね。途中で挫折。
しんどいのね、templateって。
やたら不等号増えるし、デバッグしづらいし。コンパイル遅いし、ちょっと変えると全コンパイルになっちゃうし。今のところ、templateのimport(だっけか)ができるコンパイラが手に入らないというせいもある。実行ファイルのサイズもむちゃくちゃデカくなるんちゃうかな、最後までいってないから分かんないけど。
考え方はちょっとおもしろいなぁと思ったんだけど、現状では実用的でない。
記法をもうちょっと工夫して、コンパイラがもうちょっと進化したら、また試してみよう。
そうそう、Objective-Cのカテゴリって、既存クラスにメンバ関数の追加ができるという意味で、結構近いモノがあるんではと思うんだけど、それがまた全然違うのはしかも動的というところで、それもすごいよね。メンバ変数の追加ができたら言うことないんだけど、ランタイムの実装とバグなしで処理を書くのが難しくなっちゃうだろね。
なんかタイトルと全然関係ないね。
2003年9月18日
多重継承の問題
出荷計画システムを考えよう。
在庫クラスZaikoのオブジェクトに対し、注文クラスChumonのオブジェクトを順に引き当てていくというような処理を考える。
パッケージソフトとして標準的な仕様である(と思われる)、Chumonの持つ納期順・注文日順に在庫を引き当てよう(普通は入庫予定とかも引き当てるんで簡素化バージョンだ)。
てことで、そういう処理を作成し、顧客デモに持っていったところ、「だいたいいいんだけど、少し直して欲しい」ってことで、最初の顧客、ハッスルコンピュータ社向けにカスタマイズ。
引当を、納期・注文日より、自社のオンラインストアの顧客を優先にするって仕様に変更!
とりあえずChumonクラスから派生させて、HChumonとかを作って販売経路をメンバに持たせる。
そんなこともあろうかと、Factoryパターン使ってるから、派生クラスのオブジェクトを生成して必要なメンバだけ値設定するところと引当処理をStrategyパターンでちょちょいと。
無事リリースして次の顧客、ナックルコンピュータ社へ持っていくと、どういうわけか、納期・注文日より、教育機関を優先して引き当てるってご要望が!
これもChumonクラスから派生させて、KChumonとか作って業種なんか付ければ、もう最初とほとんど同じだね!
3番目の顧客は…アップスコンピュータ!
直販で教育機関で、かつ注文金額の大きさを優先だ!
て、直販で教育機関ていうのはもうやったよ?
どういうふうに派生させる?それとも派生させない?
続きはまた明日(か明後日か)。なんか批判めいて見えるのは気のせいだ!
2003年9月17日
動的バインドの使い道
手続き型言語に慣れた我々(って誰だ?)から見ると、「動的バインド」のメリットは非常に分かりづらいよね。
ある関数で処理を行なう中で、メッセージを受け取ったり受け取らなかったりされては困る、そもそも、そのメッセージを受け取るか受け取らないかは考えて設計するだろ、というふうに考えちゃう。
実際のところ、通常に処理する部分はObjective-CやVisualBasicのような動的バインドを許す言語でもC++やJavaのような動的バインドを許さない言語でもそれほど大きく違わない。
そうでしょ、例えばグリッドにデータを設定するときでも、だいたいはグリッドオブジェクトを意識して、かつデータソースを意識するでしょ。
InitGridとかって関数作っても、そこにグリッドオブジェクト以外のものを渡したりしないし、データソースでないモノを渡したりもしない。Objective-CでidとかVisualBasicでAs Objectとかって宣言するのは、手を抜いたりライブラリのバージョンが変わって静的バインドではバインドできなくなったりするときの対策ぐらいでしょって。
ところがあれだ、実は動的バインドが異常に威力を発揮するところがあるんだよね。
それは「イベントハンドラ」。
メッセージハンドラ、と読み替えてもらえば「あ!」って思うかも知れない。
要は、オブジェクトは相手が受け取るか受け取らないか知らんけど、とにかく自分に変化があればイベント(メッセージ)を相手に向かって送出する。
受け取る側はどんなイベント(メッセージ)が来るか分からんけど、とにかく自分が受け取れる(関心がある)イベントだけ受け取る。
VisualC++でMFCをやってる人は、NMHDRという構造体を知っている(かも知れない)。
こいつはイベントに関連するデータを受け渡すための可変長構造体だ。
結局、C++では動的バインドができないから、1つだけはバインドできる関数(OnNotify)を用意して、その中でNMHDRの中身をのぞき込んでswitchで分岐しちゃおう、って考え方だ(実際にはOnNotifyがMFC内部でそれなりに分岐されるので、MFCユーザはそこまではあまり意識しなで済むんだけど)。
てことで、動的バインドがその意義を発揮するのは、本当にオブジェクト指向ぽいところ、イベントというかメッセージのやりとりのところなんだよね。
これを関数呼び出しでやっちゃうとMFCみたいな方法を採らざるを得なくなっちゃうんだろね(MFCについては、もうちょっとうまいやり方もありそうだけど)。
G5に付属のDeveloper Tools
G5のOSが10.2.7、というのは周知の通り。
しかし付属のDeveloper ToolsがDecember 2002バージョンであるということは知られていないのでは?
G5に最適化しようと思えば、TN2086に書いてあるとおり、June 2003のパッチをダウンロードしてgccを切り替える必要がある。
それともインストールの仕方が悪かったんかな。
まあ、最適化するほどCPUを使うプログラムを書いていないので、別にいいんだけど。
あ、そか。gccを再コンパイル?それはいいかも。
gcc 3.3のG5最適化付きのソースってあるんかな。
2003年9月15日
@selectorの一意性
2つ連続してObjective-Cの話をしたのは
プログラマー天国のプログラマーのためのObjective-C入門のなかの一節、
「同じ名前のメソッドは、戻り値の型も引数の数と型も同じでなければならない」
うそや〜ん。マジで?
ってことがきっかけ。
で、まあ前の2本の記事のほか、HAPPY Macintosh Developing TIME!のObjective-Cの最適化なんかをみると分かるとおり、そんなことはなかった、あ〜よかった、ってのが結論。
確かに、@selectorではクラス名を渡さないので一体どうなってんだ?ってことなんだけど。
CocoaのObjective-Cコンパイラはライブラリファイル中のデータ領域(テキストセクション)にプログラム中の文字列定数をおくのだけど、そのなかに通常の文字列定数の他にセレクタの文字列も格納する。ほんでもってその文字列へのポインタを@selectorで取り出す。へぇ。
同じセレクタなら@selectorの値も同じになる、ということを考えると、ダイナミックリンクの際にリンカが同じ文字列のエントリが別々のライブラリファイルに存在したらどっちかをネグったりなんかする必要があると思うんだけど、実際どうなってるのかはちょっと不明。
横道にそれちゃったんで元に戻すと、各インスタンスには隠しメンバ変数としてisaというのがあり、こいつは自分自身のクラスへのポインタを持っている。自分自身のクラスってのもsingletonオブジェクト、ってのがC++と違うところ。
クラスのオブジェクトはC++の仮想関数テーブルのようなものを持っていて、この中から該当するセレクタを探す。C++みたいに直接仮想関数テーブルのエントリにアクセスするんじゃなくて、あくまで探す。探した後はキャッシュするんでいつでも遅いというわけではないんだけど。探すキーは@selectorの値だ。
で、そのクラスの関数テーブルに渡されたセレクタに相当するものがなければ、親クラスのほうに制御が移る。
てことで、「同じ名前のメソッドは、戻り値の型も引数の数と型も同じでなければならない」ってことはない。
そのクラスにその引数でそのセレクタを持つメソッドがあると確信できるなら、そのメッセージを送信して全然構わない。問題になるのは、そのセレクタを持つメソッドがないために基底クラスにそれがスルーされて、基底クラスではその引数じゃない引数を取ろうとしている場合だ。この場合は例えば引数のサイズや数が違ったりしたら、SIGBUSであっさり死亡してしまう。
2003年9月14日
Objective-Cの型保証
C++ではARM(Annotated C+ Reference Manual)の7.2cに書いてあるとおり、リンカレベルで型保証されてる。
どういうことかというと、SomeClass::SomeFunction(int, int, int);という関数は、ライブラリにそのままの関数名SomeFunctionでエクスポートされるんではなくて、クラス名・引数の個数・それぞれの引数の型を省略形で付加した、Q29SomeClassCSomeFunction__9SomeClassFiiiみたいな格好でエクスポートされる、ってことになってる。
なので、ライブラリとそのヘッダファイルがあって、仮にヘッダファイルに書いてある関数の引数がライブラリ作成時から変更されていても、間違ってリンクしちゃうことはないんだよね。
一方で(Cocoaの)Objective-Cの場合、これが設計ミスかどうなんかは判断しかねるけど、型保証はない。
NSStringのinitWithCString:は、[NSString initWithCString:]というそのままの名前でエクスポートされている。
コンパイラはヘッダを見て警告を出してくれるけど、リンカは警告もエラーも出さずにそのままリンクしちゃう。
そういう意味でガチガチの型保証に慣れてきたC++プログラマにとっては、Objective-Cはちと怖い言語ではあるよね。
Objective-Cのセレクタの名前空間
Objective-Cには、C++で言うところの多重定義(overload)がないのね。
つまり同じスコープで同じセレクタやプロトタイプを持つ関数は定義できないってこと。
セレクタが同じ、ってのは、引数の前についている(なんて言うのか知らんけど)引数名みたいなのも含めて同じ、てことなので、例えば、引数の数と型が違う次の2つのセレクタは同じでないってことになる。
-(void)writeString:(NSString*)text atX:(int)x atY:(int)Y;
-(void)writeString:(NSString*)text from:(int)startOffset length:(int)length;
この場合のセレクタ名ってのはwriteString:atX:atY:とwriteString:from:length:、つまりなんか引数名みたいなやつ(なんていうのか知らんけど)まで名前の一部になるってことね。
C++の多重定義の場合、
void writeString(NSString* text, int x, int y);
void writeString(NSString* text, int startOffset, int length);
なんてことは(仮引数以外に差がないため)できないので、その辺はObjective-Cのほうが柔軟性があるようなないような、タイプ量はObjective-Cのほうが多いよね(違)。
ほんでもって次に、親クラスと同じ名前を持ち、引数や返値が異なるセレクタの場合をみてみよう。
例えば、
@interface Test : NSString
{
}
- (void) initWithCString:(int)value;
@end
みたいなもんだ(言うまでもなく、この例は極悪だ)。
この場合、[[Test alloc] initWithCString:3]とやると、TestのinitWithCStringが呼ばれて、親のinitWithCString(NSStringのinitWithCString)は、そのままでは呼ばれない。
普通(完全に親と違う動作をさせるとか、完全に親と同じ処理を自分で書いちゃうとかしないかぎり)、superという指定子を使って、いったん親クラスへメッセージを転送(まあ親クラスの関数をコール)してから自分の処理を行なう。
@implementation Test
-(void)
initWithCString:(int)value
{
self = [super initWithCString:"test"];
// do something for Test here.
}
@end
この場合のsuper...の部分ではNSStringの-(id)initWithCString:(const char*);が呼ばれるのね。
なんか気持ち悪いってことなんだけど、それはObjective-Cのコンパイラもそう思っている(というかコンパイラの設計者が思ったんだろね)上記のコードはコンパイラが警告を出す。
Objective-Cの場合、ダイナミックバインディングなので、
void f(id obj)
{
[obj initWithCString:3];
}
f([Test alloc]);
f([NSString alloc]);
というコードはコンパイル可能なんだけど、当然、あとの方のNSStringを使った方は失敗しちゃう(SIGBUSで終了する)。
C++の場合は、idに相当するものもなく、ダイナミックバインディングでもないため、上記のf()なんかは全くコンパイルできない。
例えばf()の引数をNSString*(に相当するもの)にしてもNSString::initWithCString(に相当するもの)の引数がconst char*なのでf()がコンパイルできないし、Test*を引数にしてもf([NSString alloc]);(に相当するもの)がコンパイルできない。
いや、もちろん無理矢理キャストすればコンパイルを行なうことはできちゃうけど、それでSIGBUSを食らうのは同じ。
ちょっと横道にそれちゃうけど、C++ではTestクラスのポインタに対して、initWithCString:(const char*)に相当する呼び出しを行なうことができないのね(ここでもキャストすれば別)。
派生クラスの関数によって基底クラスの関数は隠される、ということ。
.mmと.mでの文字定数の扱い
Objective-Cは基本的にCで、Objective-C++は基本的にC++なので、
.m(Objective-C)と.mm(Objective-C++)では、1文字の文字定数
('A'とかね)の型が違うのね。
.mではint型だけど、.mmではchar型になっちゃう。
それでトラブルが発生するようなケースは(Objective-Cが型による呼び分け
ができないために)思い当たらないんだけど。
WindowsにおけるイベントとCocoaにおけるdelegate
Windowsでの開発の場合、例えばVBならフォームにコントロールを貼り付けて、そのコントロールから発生するイベントのハンドラを親フォームに記述する。
Cocoaの場合、それに相当することをしようとすると、イベントハンドラを持ったクラスを作って、それをコントロールのdelegateに設定する。
Cocoaの場合は、ウィンドウに直接書くんじゃないのね。
VBで、例えば2つのコントロールのスクロールを1本のスクロールバーで同期化するってことをやろうとすると、スクロールバーからのイベントハンドラ、つまり同期化の処理を、フォームに書く必要がある。
フォームなんてのは普通、コントロールの数も違えばやることが全然違うので、普通は使い回さない。
いきおいこのようなイベントハンドラが各フォームにコピペされるという羽目になる。
Cocoaでは、例えば複数のスクロールすることのできるコントロールやビューをメンバとして持つクラスを作っておいて、それにイベントハンドラを書いて各メンバへスクロールメッセージを送るようにしておけば、このクラスは再利用できる。
それともVBでこういうケースのもっとうまい解決方法があるんかな。
結構、delegateで悩む人が多いようなのでコメント。
ClassicアプリではEventRecordを受け取るためのイベントループがありました。普通はWaitNextEventでそっからイベントを拾ってから各イベントハンドラに振り分ける。ClassicだとWaitNextEventでマウスダウンとかを拾ってから各コントロールのTrack〜ってやつを呼ばなければならなかった。
CarbonアプリではCarbonイベントハンドラってのをCarbonEventManagerに登録するとイベントが発生するたびにそっからコールバックがイベントハンドラに来ます。CarbonEventManagerになってからは各コントロールがマウスダウンとかの低レベルなイベントを処理してくれて、最終結果としての、例えばプルダウンメニューの値が変わったとかの高レベルなイベントを処理してくれるようになった。
ただしイベントを出したり受け取るのは(Cなので)オブジェクトじゃなくてアプリそのもの、と言っていい。
Cocoaでは、プログラマが扱うのはやっぱり高レベルイベントだけで、さらにCarbonと違うのはObjective-Cのオブジェクトがイベントを出して、Objective-Cのオブジェクトがイベントを受け取ると言うこと。
イベントを出す側のdelegateというメンバに、イベントを受け取る側のポインタを設定すると、次からはその間でイベントのやりとりが行なわれる。
で、イベントのやりとりは、C++なんかだと汎用的なイベントハンドラ関数型というのがあって、それに渡された構造体の中身を見てswitchっていうパターンが多い。
けど、Objective-Cでは(動的バインドなんで)直接メッセージ送信([object messageWith:value]みたいな奴ね)を行なう。対応するメソッドが受け取り側にない場合はメソッド呼び出し自体が行なわれない。
2003年9月12日
うるさ〜い
と怪物君が暴れそうなG5。
全然書いてなかったかも知れないけど、注文したのは一番下の1.6GHzモデル。2GHzデュアルって選択肢は先立つもののない我が家には存在しない。
ほんでもまぁ無事9月中に届きました。しかしうっせー!初期不良で帰っていってしまうというのが当初の予想だが、このまま壊れてもおかしくない気がしてくる。
iBookをターゲットディスクモードで起動して(Tキーを押しながら起動)、G5をシングルユーザモードで起動して(コマンド+Sを押しながら起動)、ほんでホームディレクトリをdittoでコピー中、だからなのかもしれないけど、ファンの音は会社のマシン室並みのうるささ。
XserveとかPowerMac G4がうるさいので、G5で改善された、というのであれば、前2者はどんなうるささなんだという気がする。
我が家ではG5の呼び名は「空気清浄機」に決定した。
StudioMXも(在庫切れらしいので)後日出荷される手はずになったので、まずは何より。
マシン使った感想はまた別途。
2003年9月 7日
デバッグシンボルの生成
覚え書き。
Project Builderではデフォルトで、ビルドスタイル「Development」「Deployment」の2つを選ぶことができる。
だけど、「デバッグシンボルを作成する」オプションはじめ、コンパイルオプション画面で設定できるオプションは2つのビルドスタイルに共通。
なので、Deploymentのときにサイズちっちゃくしようと思ったら「デバッグシンボルを作成する」のチェックをオフにする必要があるし、かといってそのままだとDevelopmentに切り替えてもデバッグシンボルが作成されない。なんか面倒。
ってことで、
- 「GCCコンパイラ設定」の「デバッグシンボルを作成する」はオフ
- 「Development」スタイルの方の「ビルド設定」のところでOPTIMAIZATION_CFLAGS = -O0 -gのように、「-g」を追加
- 「Deployment」スタイルの方の「ビルド設定」は-gなし
それよりも、それぞれのビルドスタイルでビルドしたオブジェクトが分けて管理されてないんだけど、なんかおかしくないか?スタイルを切り替えるたびに毎回リビルドしなきゃなんないの?
パスワード用テキストフィールド
久しぶりに覚え書き。
NSTextFieldに「パスワード用文字列」とかないかなぁとか思って探していたら、なんのことはない、NSSecureTextFieldというクラスがあった。
普通にInterface BuilderでNSTextFieldを貼り付けて、プロパティインスペクタのCustom ClassでNSSecureTextFieldを選ぶ。
こんだけ。簡単。
2003年8月18日
G5出荷
G5の3モデルのうち、下位2モデルが米国で出荷開始されたらしい。
Appleのいう「出荷する」ってのはどういうことかというのがものすごく曖昧で、早い話、「出荷開始=出荷」なのか、「バックログ分すべて出荷=出荷」なのかはよくわからない。
Appleの場合、当然前者だと思うが。
ほんでもってあとは日本でいつ出荷されるかということ。今月中に届くといいなぁ。
2003年8月14日
参照カウンタ
みんなが夏休みとってるときに、会社で何やってるかって言うと、あれだ。デバッグ。
担当プロジェクトではないんだけど、まぁ顧客テスト中に発生したエラーの原因が分からず、空いてる人で再現テストとかするという、よくあるあれです。特に連休前によく発生するのはなぜか?
それはともかく、そのエラーの内容というのがOLEオートメーションエラーというやつで、詳細エラーメッセージが「起動されたオブジェクトはクライアントから切断されました」という、「なんなんだ!責任者出てこい!」状態の、これもWindowsではよくあるパターン。
正確な原因が分かってないので、これから書くことは間違ってるのかも知れないけど、まあ書いておこう。
これってのはCOM関係のエラーらしいのです。正確に言えば、上記のメッセージはRPC(Remote Procedue Call)関係なので、DCOMかも知れませんが。COMってのはご存じの通り(かどうか知らないが)、あれです、参照カウンタを使ってオブジェクトの管理をしてるんです。
で、おそらく、参照を保持している側から、参照される側のオブジェクトのメソッドを呼び出したのはいいが、参照される側はすでに解放されちゃってる、とかいうパターンなんです。おそらく。まだ再現すらしてないんですが。
参照カウンタと言えば、Objective-CというかCocoaも参照カウンタでオブジェクトを管理しています。
要はオブジェクトが誰からも参照されなくなったら(参照カウンタが0になったら)勝手にオブジェクトが解放されるので、どこでオブジェクトを作ってどこでオブジェクトを解放するかを設計しなくてもよくなる、ってことなんですが。
現実はそんなに甘くなくて、参照カウンタの上げ下げを各所できっちり作り込んでおかなければならず、これでミスすると原因が究明しにくくなるという問題があります。
Objective-CはC++と異なり、演算子のオーバーライドがないので、スマートポインタのようなものは作れませんが、拡張子を.mmにすることでObjective-C++になって、C++の機能も使えるようになるため、C++のスマートポインタのようなものを導入することも可能です。
ですが、あれです。
やっぱりきっちり設計して、きっちりドキュメント化しないと参照カウンタとかスマートポインタってうまくいかないんです。
どういうケースで参照カウンタがカウントアップされて、どういうケースでカウントダウンされるか。どのメソッドは参照カウンタをどういう状態にして返すか。
Visual Basicもやはり、参照カウンタを使っているのですが、デバッグするのはCがいいなと思います。参照カウンタがどう遷移しているか見たいもの。
けっこう、この「起動されたオブジェクトは〜」のエラーで悩んでいる人は多いようです。
このときの現象はOracle Objects for OLE(OO4O)をVBから使ってストアドプロシージャを呼ぶと、ときどきエラーが発生する、ってものだったのですが。
結局、RPCでもDCOMでも(たぶん)なかった、というのがこのときの結論でした。
詳しいことはOracle保守サービスの契約に守秘義務があるということで書けませんけど。
2003年6月30日
Renamer Cocoa版
RenamerのCocoa版がだいたい完成。
ただし、255コードポイントへの切りつめ処理は入っているが、31文字への切りつめは行なっていないので、HFSには対応してない状態。

酔っぱらって作ったアバウト画面は破棄(笑)。普通にしました。
アイコンのRキーが黄味がかっているのは古き良き時代を偲んでのこと。
決して手垢で黄色くなったわけではないと思いたい。
いま気が付いたけど、iBookのUSキーボードは文字が中央に貼ってあるのね。
何となく、Macのキーボードって左下に文字を貼ってあったような気がしてたけど、気のせいか。
ちなみに今使っているWindowsのキーボード(お気に入りのKEY TRONICの安USキーボード)は左上に文字が貼ってある。
ふーん。
で?
2003年6月27日
G4
すかさずアップルはG4を値下げしてますな。
1.25GHzのシングルプロセッサ版が159,800円。
む〜。どうなんだこの値段は。
その前の1GHzシングルは189,800円で売られていたようなので、3万+0.25GHzお得。
1.25デュアルは195,800円。249,800円から5万の値下げ。1.42GHzデュアルはラインナップから消えた(なぜ?)
G5の評価が固まっていない時期だからな。
年内にG5の3GHzモデルが出るらしいしな。やっぱりもう少し待つか。
イソップ童話に出てくるぶどうをとれなかったキツネの心境とか、ドーハでイラクにゴールされたラモスの心境とか(違)よく分かる。
くどいって。
2003年5月31日
HFS+ファイル名の切りつめ処理ソース
あんまり汎用的にならなかったが、ソースをアップロードした。
ちょっとした長さになったかと思ったが、ちょっとしてなかった(笑)。
Terminalからmake allすると、Testというファイルができるので、./Testでテスト結果を出力。
標準出力にちょろっと情報を出力するほか、Test.txtにもテキストを出力する。
だから何なんだ、という程度のことしかやってないけど。
2003年5月27日
HFS+ファイル名の切りつめ処理
以前に参考として挙げた「FSRefs と Unicode ロングファイル名」の中で「これはちょっとした長さのコードになる」というので省略されていたUnicodeの切りつめ処理。
ちょっとした長さのコードを書いてみた。
もう少し汎用的にしてからアップロードしようと思う。
要る人がいるのか分からんけど。
2003年5月19日
ドラッグアンドドロップ
MacOS Xのアプリって、自分自身にドラッグアンドドロップできるのね。
(全部がそうなんかな?)
なんなんだか。
2003年5月18日
アバウト画面
Macのプログラム、と言えば「アイコンから作る」。
かの藤本氏も以前どこかで(DocFreezerIIのドキュメントだったか?)「アイコンから作る」とか言っていた、
アイコンとアバウト画面、それにソフトウェア名の3つはオンラインソフトの命、と言っても過言ではあるまい。
ほんとか?
実はひそかに「Cocoaはやっぱり!」をパクって、「Cocoaはサッパリ!」を始めようかと思ってはや2年、いつのまにか2chにも「Cocoaはさっぱり!」スレが立ってしまい、旬が過ぎてしまった今となっては、それっぽく作ったこの画像も、使う機会を失ってしまっていた。

俗にいう「今の若いもんはすぐカタチから入ろうとする」状態。中身が伴わない典型。
見せるだけ(わはは)。
で、最初の話。制作中のRenamerのMacOS X対応版、あとはアイコンとソフトウェア名だけど、アイコンと「Renamer」は引き継ぐとしてアバウト画面をどう作るか、あ、まてよ、ReadMeも作らんと。
ま、ともかく、その辺の奴ってのは本体作るより楽しい部分があるというのは否定できない。
問題は本体を仕上げることだが、今日は家に帰ってきたけどまた火曜から1週間大阪なので、来週ってのはキビシイかもしらん。
またアバウトだけか…。
2003年5月15日
Carbon化
Renamerだが、よくよく考えて、やはりCarbon化はやめようかと思う。
むしろCocoaベースで作った方がよいのではないかと。
で、いくつか調査した点。
Q:ファイルをアプリアイコンにドラッグ&ドロップした場合、delegateにapplication:openFile:がどういうふうに来るか。
A:1ファイルずつ、複数回来る。
Q:ドラッグ&ドロップですべてのファイルタイプを受け付けるようにするには?
A:Classic同様、受け付けるファイルタイプ(OSタイプ)として****を登録する。
ProjectBuilderのターゲットのところでInfo.plistのエントリに書類のタイプを追加する。
Q:HFSからドラッグ&ドロップしても、application:openFile:には日本語ファイル名が文字化けしないで来る?
A:YES!YES!YES!
ジョーシキですか?
こんだけ分かったら、かなり楽勝。
後は、今のRenamerがどういうエラー処理をしているか調べて、同じ処理をしとこう。
Carbon化より全然簡単、は言い過ぎか?
2003年5月14日
ボリュームのsignature
先日、ボリュームsignatureを一覧にしたが、あまりにも不明な点が多かったので調査し直し。資料じゃなくて実際にコードを書いて動かす。
FSGetVolumeInfoをkFSVolInfoFSInfoで呼び出すと、FSVolumeInfo.filesystemID/FSVolumeInfo.signatureに以下のコードが返ってくる。
| ファイルシステム名 | 説明 | filesystemID | signature | 定数定義 |
| HFS | MacOS標準フォーマット | 0x0000 | 0x4244 | kHFSSigWord |
| HFS+ | MacOS拡張フォーマット | 0x0000 | 0x482B | kHFSPlusSigWord |
| MFS | System7以前のフラットファイルシステム | 不明 | 0xD2D7 | |
| UFS | UNIXファイルシステム | 0x6375 | 0x4B48 | |
| NFS | ネットワークファイルシステム | 不明 | 0x4E4A | |
| AFS | AppleShareファイルシステム | 不明 | 不明 | |
| SMBFS | 0x6375 | 0x4244 | ||
| WebDAV FS | 0x6375 | 0x4341 | ||
| UDF | 不明 | 不明 | ||
| FAT | MS-DOSファイルシステム | 0x4953 | 0x4244 | |
| ISO9660 | CD-ROM | 0x6375 | 0x4147 |
AppleShareは自分のマシンのディスクをマウントさせてくれないみたいなので、まあ帰ってから再挑戦。
MFSはもう調べることもできんし、もう使ってる人もいなさそうだから無視しよう。
しかし何か規則性がありそうななさそうな…。
2003年5月11日
ファイルAPI調査(3)
もちろん、HFS上には255文字のファイル名を持つファイルというのは作れないので、FSCreateFileUnicodeを使うとしても常に255文字使えると言うことにはならない。
このため、事前に書き込み先のボリュームがどんなファイルシステムを使っているのか調べる、ということが必要になってくるかも知れない(普通はしないか)。
前にも書いたが、こういうこと気にするのは
- Renamerのようなファイル名の一括変換処理を行なうもの
- ClipSのようにクリップボードやメールなどのテキストを先頭から何文字かとってファイル名にしてしまうという処理を行なうもの
- ファイルアーカイバ(StuffIt!とかtarとか)
- ダウンローダのようなもの
って今、FSCreateFileUnicodeを使ってMacOS XでHFS上に漢字40文字のファイルを作ろうとしたら、エラーコード-50 (paramErr)が返ってきた…。
ここは一つ、-1410(errFSNameTooLong)を返して欲しいところ。エラー処理しにくい。
で、具体的なファイルシステムの調べ方。
実際にファイルを作ってみてエラーコードから推測。
うそ。
FSGetVolumeInfoをkFSVolInfoFSInfoで呼び出すと、FSVolumeInfo.signatureに以下のコードが返ってくる。
| ファイルシステム名 | 説明 | signature | 定数定義 |
| HFS | MacOS標準フォーマット | 0x4244 | kHFSSigWord |
| HFS+ | MacOS拡張フォーマット | 0x482B | kHFSPlusSigWord |
| MFS | System7以前のフラットファイルシステム | 0xD2D7 | |
| UFS | UNIXファイルシステム | 0x4B48 | |
| NFS | ネットワークファイルシステム | 0x4E4A | |
| AFS | 不明 | ||
| SMBFS | 不明 | ||
| WebDAV | 不明(マウントしてる?Finderがそう見せてるだけ?) | ||
| UDF | 不明 | ||
| FAT | 不明 |
不明な部分はそのうち調べよう。
逆にHFS+上にファイルを作るとは言っても、FSp系では255文字のファイル名を持つファイルは作れない。
ので、例えば255文字のファイル名を持つリソースファイルを1発では作れない。
FSpCreateResFileしかないので…って、もしかしたらFSCreateForkでいきなりファイルが作れるのかな?
要調査。
2003年5月10日
復刊ドットコムでH&Sリファレンスを復刊キボンヌ
話は横にそれちゃうが、復刊ドットコムというところが、廃刊になっちゃった本を希望者集めて復刊させちまおう、という活動をしている。
私も会社に持っていったまま行方不明になっている「H&Sリファレンス」を復刊リクエストしてみた。25票/100票とか出ていたので100票集まると出版社との話になるってことなんではないかなと想像。
まあ色々と「これをもう一度読みたい!」って本があるなか、「読みたいって言うより手元にないとちと困る(こともある)」って本が「H&Sリファレンス」と「ARM」。
これなくてC/C++を使うってのは、マニュアルなしでガンダムを操縦するってのに近く、ということは、なきゃないでどうにかなるってことか。
まあ自分が必要とすることは今ではあんまりないんだけど、人に教えるにはやはり必要。
ちなみに。
H&Sリファレンス=新・詳説C言語:H&リファレンス ハービソン&スティール著 1994年発刊
ARM=注解C++リファレンス エリス&ストラウストラップ著 1992年発刊
って、よく調べると、ARMって復刊してるやん!えらい!
誰が偉いのか知らんが元々トッパンから出てたのがシイエム・シイというところに移ったらしいのでシイエム・シイというところが偉いのだろうと推測。
2003年5月 9日
ファイル名用テキスト変換API調査
ってことで、前回の
これから検証しないとダメだと思うが、CFStringRef unicodeFileNameRef = CFStringCreateWithBytes(nil, (const UInt8*)shiftJISFileName, strlen(shiftJISFileName), kCFStringEncodingShiftJIS, false);
const UniChar* unicodeFileName = CFStringGetCharactersPtr(unicodeFileNameRef);// do something uses unicodeFileName
CFRelease(unicodeFileNameRef);
は、前述のTECを使ったコードと同じものを返してくれるのか?
について検証。
やはりNormalization Form Cで返ってくる。
TEC(Text Encoding Conversion Manager)を使えば当然のようにNormalization Form Dで返ってくるが、
で、問題はこれがFSCreateFileUnicodeで通るかどうかだ。
については結果から言えばNFCでもNFDでもどちらも「通った」。
ただし、実際のファイルシステム上にはNFDでファイルが作られ、もちろんファイル名長チェックもNFDの文字数(正確にはコードポイント数)に対して行なわれる。
このためNFCでは事前に正しいファイル名長のチェックができない(エラーでFilename too longが返ってくるたびにちょっとずつ縮めていくってことは可能かも)。
ユーザにSaveAsダイアログでファイル名を指定してもらう場合はともかく、自動的にファイル名を付けるような処理(テキストやクリップボードの中身からファイル名をつけるなどの処理)では、やはり最初からNFDで返してもらう方がよい。
現実的には、自動ファイル名生成処理(というか指定した文字数のファイル名を作る処理)を実装するには、TECの変換API+(前回の参考文献にもあるように)UCFFindTextBreakを組み合わせたルーチンを自前で作る、ということになるのだろう。
ところでTECには文字数(コードポイント数)を数える処理はないの?
TECConvertTextで返ってきたactualOutputLengthをsizeof(UniChar)で割ればいいだけとは思うけど、なんか釈然としないものが…。
ちなみにCFStringには(CFStringオブジェクト自身の)文字数(くどいけどコードポイント数)を数えるメソッドがある。
またCFStringGetMaximumSizeForEncodingみたいな関数もTECにはない。
悪い意味で面白かったので(?)TECConvertTextのリファレンス(のDiscussの部分)を訳しとくと、
もし割り当てた出力バッファが変換されたテキストを返すのに小さすぎた場合、関数は失敗します。最良の結果を得るためには、出力バッファを割り当てる際、以下のガイドラインに従うようにします。
- 変換先エンコーディングの必要な概算バイト数を基準にします。変換先エンコーディングで必要とされる追加バイト(例えばエスケープシーケンス)も、実際のテキストに加えて算出してください
- 常に少なくとも32バイトは割り当てるようにしてください。
- サイズが重要である場合は、少なくとも変換されたテキストを部分的にでも保持するのに十分大きい出力バッファを割り当てるようにしてください。テキストを部分的に変換することが可能です。その場合、次の変換対象バイトポジションを調べたり、残りのバイト数を決める目的でactualInputLengthパラメタを使うことができます。残りのテキストを変換するのは単純に、残ったテキストと新しい出力バッファを指定して再度関数を呼び出してください。
- もし変換先エンコーディングが、ISO-2022-JPのような、アスキーで始まりエスケープシーケンスで別のキャラクタセットに切り替えるようなエンコーディングスキームの場合は、切り替えを示すエスケープシーケンスを返すためのスペースを含めて割り当てる必要があります。ISO-2022-JPはエスケープシーケンスとして1バイトまたは2バイト文字の前に3〜5バイトを必要とします。バッファが5バイトより小さければ、TECConvertText関数は変換するテキストによっては失敗します。
こんなもんいちいち計算できるかい!
全プログラマがエンコードを変換したくなるたびにこんなこと考えなきゃならんとすれば、誰がMacなんかのプログラムを作るか、Appleよ?
とはいうものの、いまやTEC以外にもいろいろなルーチンが使えるので(ほんとはまとめて欲しいところ…少なくともクロスリファレンスは用意してほしい)、まあ、勘弁しといたろかって感じだ(←何様のつもり?俺様?)
結局、通常テキストとファイル名の相互変換はTEC/CoreFoundation/UnicodeConverter等を臨機応変に組み合わせる必要があるってことなんかな。
2003年5月 6日
続ファイルAPI調査
HFS+に関するTechNoteを読むと、HFS+でのファイル名は
CreateTextEncoding を使ってテキストエンコーディングを作成するときは、TextEncodingBase に kTextEncodingUnicodeV2_0、TextEncodingVariant に kUnicodeCanonicalDecompVariant、そして TextEncodingFormat に kUnicode16BitFormat を設定してください。これらの値を使用すると、たとえ Unicode 規格が発展した場合でも、Unicode が HFS Plus ボリューム上と同じ形式になることが保証されます。
ということらしい。つまりShiftJISでファイル名がある場合、以下のような処理でUnicodeファイル名を作って使うことができる。
const char* shiftJISFileName = ...;
TextEncoding hfsplusEncoding = CreateTextEncoding(kTextEncodingUnicodeV2_0, kUnicodeCanonicalDecompVariant, kUnicode16BitFormat);
TextEncoding hfsEncoding = CreateTextEncoding(kTextEncodingMacJapanese, kMacJapaneseStandardVariant, kTextEncodingDefaultFormat);
TECObjectRef converter;
TECCreateConverter(&converter, hfsEncoding, hfsplusEncoding);
TextPtr unicodeFileName = malloc(xxx);
ByteCount actualInputLength, actualOutputLength;
TECConvertText(converter, shiftJISFileName, strlen(shiftJISFileName), &actualInputLength, unicodeFileName, xxx, &actualOutputLength);
TECDisposeConverter(converter);
// do something uses unicodeFileName
free(unicodeFileName);
…なげーよ!
エラー処理がなくてこの長さなので、エラー処理を入れるとえらいことになる。
ところで、macosx-jp MLのこの投稿によると、
実際、CFString/NSStringがサポートしているエンコーディングコンバータは(現在のところ)TECのスーパーセットなので、
ということだが、上記のような、kTextEncodingUnicodeV2_0, kUnicodeCanonicalDecompVariant, kUnicode16BitFormatといった、細かい指定がCFStringでできるのか?
いや、できない(反語)。
いやいやまだよくは調べてないんだけど。つい勢いで。
これから検証しないとダメだと思うが、
CFStringRef unicodeFileNameRef = CFStringCreateWithBytes(nil, (const UInt8*)shiftJISFileName, strlen(shiftJISFileName), kCFStringEncodingShiftJIS, false);
const UniChar* unicodeFileName = CFStringGetCharactersPtr(unicodeFileNameRef);
// do something uses unicodeFileName
CFRelease(unicodeFileNameRef);
は、前述のTECを使ったコードと同じものを返してくれるのか?
いや、返してくれない(反語)。
いやいやまだ検証してないんだけど。つい勢いで。
まあしかし、たぶんdecomposeされないな後者は(おそらくNormalization Form C)。
で、問題はこれがFSCreateFileUnicodeで通るかどうかだ。
その他の参考文献:「FSRefs と Unicode ロングファイル名」
「UnicodeUtils OSAX」
「macosx-jp MLの投稿記事」
遅いのでまた明日。…もしくは明後日以降(ひよってみました)。
2003年5月 5日
ファイルAPI調査
WindowsにおけるFAT→FAT32/NTFS移行時のように、MacOS Xになってからロングファイル名が密かに問題になっているとは思う。
おおっぴらに問題になっていないのは、HFSの制限がFATのような8+3という短いものでなく、31バイトという、まあだいたいはOKでしょう!という長さだったからに違いないと推測。
ところで現在のMacには大きく分けて3種類、細かく言えば10種類ぐらい、ファイルを扱うAPIが存在する。
大きくは、Carbon系/Cocoa系/UNIX系と分けられる。
CFMから呼び出せるのはCarbon系のみ、C言語から呼び出せるのはCarbon系/UNIX系のみ、Cocoa系はObjective-Cからのみ呼び出し、ということなので、上記のような分け方でよいかと思う(ただしテクを使うことでCFM/Mach-Oの相互呼び出しは可能)。
細かく言えば、Carbon系は、FSp系/FS系/H系(/PB系/PBUnicode系/PBH系)の6種類に分けられるし、UNIX系もPOSIX系/ANSI C系の2種類に分けられる。
こんだけあること自体ですでに充分ややこしいのに、これらのAPIに渡すファイル名のエンコードやファイル名長がいちいち異なっているために、混乱すること極まりない。
パスカル文字列を渡す奴・C文字列を渡す奴、ShiftJISを渡す奴・Unicode(UTF-8)を渡す奴・Unicode(UCS-2)を渡す奴、255文字まで行ける奴・31文字しか行けない奴。
さらに、Carbonには定義だけされているもののMacOS 8/9では実装されておらず、MacOS Xでしか使えない、なんて奴もある。
Appleのドキュメントも結構ひどくて、引数の型に「UniChar」、説明に「Unicode」とか書いてあるが、そんなにザックリ言われても分からんやろ!これに何を渡せと言うのですか?が書いてなかったりする(HFS+のドキュメント読め!ってことかな)。
おまけに保存先としては、単純に考えてもHFS/HFS+/UFSがあり、さらにSMB経由/AFP経由のNTFS/FATとか考えちゃうと(考えすぎです)何がなにやら。
また、HFS+のUnicode(UCS-2)は一般によく使われているNormalization Form C(これだと普通の日本語は2バイト)ではなく、濁音・半濁音を別の文字として扱うNormalization Form Dなので、「ダ」は「タ」+「゛」の4バイト消費する。
これによって、例えばUTF-8&Normalization Form Cで255文字のファイル名をopen()に渡してファイルを作ろうとすると「ファイル名が長すぎます」エラーになってしまうことがある。
ただし!Normalization Form Cで渡しても255文字以下ならエラーは出ずにそのままファイルが作成されるAPI(openとか)もある!!(それはそれでありがたいが)
もっと言えばUCS-4のサロゲート領域を使った奴なんかどうなんだろう(調べてない)。正直なところHFS+のドキュメントに書いてある「255文字」が何を表わしているのか、ドキュメントをきっちり読まないと分からん。
いろんな歴史的経緯があってこんなことになっちゃったのだとは思うが、なんだかなぁ。
(例えばなんでNormalization Form Dなのかと言えば、HFSが大文字小文字を区別しないため、HFS+でも大文字小文字を区別しないソートなどを行ないやすくするためだったのではないかと思われる。そんなコンパチビリティ必要だったのかどうかと言われれば、どうだろう、HFS+の登場したMacOS 8.1の頃は必要だったのかも)
…そんな背景があって、ちょっとファイル周りのAPIについて調査&整理をしようと思いたった今日この頃。
どっかに整理されてんのかな。
っていって、調査し始めたところ、バグ込みプログラムを実行したために削除できないファイルができちゃった。てへ。
…てへじゃねぇ!
2003年5月 2日
Carbon化途中経過
引き続きRenamerのカーボン化作業。
結局、Navigation Services対応のコーディングはしたものの、Project BuilderではRenamerの仕様を満たせないことが判明。
Project Builderでは必ずパッケージになってしまうらしく、Renamerの特徴である「アプリをコピーすることで設定を複製する」、要は、「ファイルタイプとかクリエータとかの変換って、毎回おんなじだけど、とは言っても複数パターンあるでしょ、ほんならアプリ本体をコピーしてそれぞれのアプリ毎に設定を覚えておけば、そのアイコンにドラッグ&ドロップするだけでお気に入りの変換が2回目以降設定なしでできるやん」対応機能(長いな、おい)が使えないのである。
これはアプリのリソースフォークに設定を保存することで対応している。
Macがネットブートに対応したいつだったかのバージョン以降、「マシン本体にHDが付いてない機種もあるのでアプリのリソースフォークにデータを保存するのはやめて、初期設定フォルダに設定を保存しましょう」というガイドラインが出たが無視。そもそもネットブートで使っている奴なんぞ見たことないし。
もちろんProject Builderを使って開発してもリソースフォークをオープンするコードを生成することは可能であるが、それにはリソースフォークをオープンするファイルのパスを今のコーディングから変えないとダメなのである。
さすがにそれはイヤんなので(CodeWarriorで作るときとコード変えないといかんし)、コンパイルが通るところまでやって、とりあえずProject Builderからは離れた。
あとはどこで落ちるかを確認する。
CodeWarrior 5なのでデバッガは使えないということで、普通ならprintfデバッグだが、Metrowerksの標準ライブラリがカーボンで動作するかどうかも分からんので、StandardAlert()を使ってデバッグ(笑)。
30分ぐらい格闘したところで、落ちる場所が判明。
ずっと昔のMacintosh Developer Journalに載っていたMemoryGlueルーチンをそのまま使っていたのがアウト、ということらしい。確かにメモリをリザーブしたりなんだりしてるからな。その中のどこで落ちるのかは調べずに、NewHandleなどの普通のルーチンを呼ぶように書き換えるだけで完了。いまさらメモリをリザーブというのもあり得ないし。

無事起動。
いくつか問題点もあって、
- デフォルトボタンの枠を今までは自分で描いていたが、とりあえず描かないようにした。でもやはりAquaなら青ボタンにする必要がある。
- なぜかサイズボックス(右下のやつ)が付いている。元の奴にはないんだが。
- 文字の幅が変わっているので、ボタン幅が足りてない
- アバウトボックスが描画されなかったので修正。ボタンが押されるまで中身なしwhileループ、というのがまずかったらしい。EventAvail(everyEvent, &event);をかますことでOK。
- Navigation Serviceにうまく対応できていない(笑)
- ロングファイル名に対応できていない。
結構、大変。
2003年4月20日
驚愕の事実その2
Safari v73のクリップボード処理がおかしい!驚愕の事実だ!というのを2日前に書いたが、さらに驚愕の事実が…。
前から有名な現象だったのね。
あはは。
あははじゃねぇ!
友の会のiWeek出展用CDにはこのサイト(CGI以外)をまるごと載せることにした。
ほんとうはRenamerのCarbon化までしたかったのだけど間に合わず。
2003年4月17日
Safari v73
すでにいろんなところで話題になっているSafari v73。
こいつにはやられました。
ClipS Xに漢字コード変換機能を付けようと思って、日本語のページからテキストをコピーし、TECSniffTextEncodingをかけてみていた。
なんかどうも思うように判定されない。
そもそもコピーしたテキストをクリップボード表示すると、日本語の部分が???で表示されるので、どんなエンコードで保持しているのかなと悩むこと1時間。
何かがおかしい。
で、直接Safariからテキストをドラッグしてデスクトップにクリッピングファイルを作り、DeRezを実行。

マジデスカ…
エンコードとか関係あらへん… 「?」が入ってるやん!
で、Mailなどのアプリは従来のテキスト型'TEXT'ではなく、Unicode(UCS-2)テキスト型'utxt'からペーストするため、正しくペーストできる。
が、もちろん'utxt'に対応していないアプリ(例えばCarbon版SimpleText)には日本語をペーストできない。
仮に'utxt'に対応できていたとしても、'utxt'と'TEXT'の両方があった場合に'utxt'の方を優先的に使うようにしなければ、やはり日本語をペーストできない。
恐るべし。
恐れている場合ちゃうて。
2003年4月 9日
Ruby
朝起きたら風邪がひどくて出張やめようかと思いつつ、支度をして出発。
今回の旅のお供になる本は「たのしいRuby」。プログラミング入門者向けらしい。
そろそろRubyを、と思いついてからはや1年。
なんでもRubyCocoaというのがあるそうで、これはCocoaの知識がないと使えないというような気もしないではないが、どちらにしろRubyを知っておいて損はないだろう(Perlのときもそんな感じだったな)。
そんなこんなで、新幹線の中で読み始める…が。
鼻水が止まらず、おまけに肩も関節痛で、本を持ってられない。
帰りに読みます…(ビール飲んじゃって読まないかも)。
2003年4月 6日
プリンタ復活とCarbon化資料
部屋の片づけをする。
OKI MICROLINE 600PSIIとALPS MD5000の電源を入れてみる。以前のXOにも書いたが、きちんと動作しなくなっていたので、ずっと放置していた。
捨てるかどうかの判断をしたかった。
しかしながらどちらも動くには動いた。特にMD5000のほうは、インクリボンが切れているだけだった。
ただ、両機種ともUSBにもFireWireに対応していないのでiBookからは直接出力できない。
プリントサーバはプリンタ自体がこういう状況だったので、友人にあげてしまったし。
当面はWindowsをファイルを使って経由して印刷する。
でもってCarbonDaterを印刷し、ちょっとずつCarbon化に挑戦。
道のりの長さを考えて、Supported But Not Recommendedのやつはそのままにしておくことにした。
TextEditをやめてMLTEに置き換えろって言われて、簡単に置き換えられる奴はそういない(はず)。
それにしてもStdGetFolderが使えず、NavigationServiceにしろといわれても…。
MacOS 8〜9の時代にさぼったツケがここでこういう形で返ってくるとは。
2003年4月 4日
CarbonDater
Renamerに対してCarbonDaterを実行。
CarbonDaterとは、PPC実行ファイルのゆうたらインポートテーブルを調べて、
- リンクしているAPIの一覧
- ローメモリグローバルにアクセスしているかどうか。 MacOS 9以前では全システム・全アプリが同一のメモリ空間で動くので、システムグローバル変数をアプリが直接見れるのであった
- システムヒープへのリソースロードを行なっているかどうか。 MacOS 9以前ではシステムが予約している領域にリソースをロードすることができ、こいつをロード後にDetachすることで常駐リソースとすることができるのであった。 使い方としては実行コードをロードして、トラップテーブルを書き換えてその実行コードをシステムファンクションに置き換えて、そのまま常駐させるように設定してからプログラムを終了する、というようなものがある。当然、MacOS Xのプロセスごとのメモリ空間(保護されたメモリ空間)では正しく動作しない。
- カーボンでサポートされている
- カーボンにも存在するけど動作が変わっているので注意
- カーボンでもサポートされているが推奨はしない
- カーボンではサポートされていない
このシステムが今日(4/3)の時点でClaris Emailer 2.0v3を使って構築されていることに驚いた(ちなみに5〜6年ぐらい前には私もClaris Emailer 2.0v3を使ってた)、というのはさておき。
いやはや結構直さないとダメね。
Supported APIが182に対し、それ以外の3種合計は81。1/3ぐらいが要見直し。
先は長いです。
そだ。
作者友の会で、iWeekに出展することが正式に決定された。
今年は何年ぶりかに出品できそうで楽しみ。
2003年4月 3日
Renamerのバグ
Renamerのバグは、内部的にGetResourceとReleaseResourceの回数を数えているモジュールがあって、その回数があっていない、というものであった。
アバウト画面を表示するとMacsBugにUserBreakで落ちてしまう。
コードからいうと、GetResourceでなくて、GetPictureでPICTを読み込んでいるハンドルに対して、ReleaseResourceしてしまっていたのが原因。
これだと回数があわない。
いちおうGetPicture(resID)=GetResource('PICT', resID)ってAppleのドキュメントに書いてあるのを確認して、GetPictureをやめてGetResourceするという、ちと変な方向への修正を行ない、浅利さんに再度メール。
そだそだ、アップロード前に履歴ファイルと説明書を修正しよう、って思い立つ。
もともとのファイルはSimpleTextの書類。ところがTextEditではSimpleText形式(というか'TEXT'形式)のスタイル付きテキストが書き出せず、RTFになってしまうことが判明。
Developer Tools CDにSimpleTextのProject Builder版(Carbon)のソースがあったなと思い、ビルドしてみるがClassic環境とフォントが違うのか、文字化けする。
Classic版のSimpleTextを起動するが、MacOS Xでは'ttro'(TeachText ReadOnly、と言われている)形式のファイルと'TEXT'形式のファイルが同じアイコンで表示されるため、編集できない理由が分からずちょっと悩む。
Renamerを使って(笑)'ttro'から'TEXT'に変換して、やっと編集可能になる。
2003年4月 2日
引き続きRenamer
引き続きRenamer。
PowerPC版すらなかった。
なんと最新版(1997年のバージョン1.2)にはPPC版がないものの、古いバージョン(1996年のバージョン1.0)にはPPC版があった。
しかし古い方はソースの一部(というか半分以上)がなかった(笑)。
当時、PowerMacは自分で持っておらず大学の研究室にしかなかったため、試しにPPC版を作っては見たものの、次からは自分が使わないからという理由でやめちゃったということを思い出した。ショッパイね。
それはともかく、コンパイルは無事すべて通るようになった。
kControlCheckboxControlUncheckedValueっていう定数が、アピアランスマネージャ導入時にkControlCheckBoxControlUncheckedValueに変更されたらしいが、こんなもん見比べたかて分からんやろ!
CheckboxからCheckBoxに変えてなんが嬉しいん?嫌がらせなん?定義箇所さがそ思って、めちゃめちゃヘッダ検索したったちゅうねん。
まあともかく、起動してみる。
unknown PowerPC exception
分からんがな分からんがな…
ワシはどないしたらええのん?あんたも分からんのんかも知らんが、もうちょいガンバったれや。
とiBookに語りかける深夜であった…。
Renamerデバッグ
Renamerは結局、Metrowerks デバッガがMacOS 9.1で動作しないのではないか?という感じで勝手に結論付けてOKということにした。
リリース版はうまく動作するように見える。
早速、浅利さんにメール。
3時半になってしまったので寝る。
そのあとすぐにバグ報告が返ってきたとも知らずに…。
2003年4月 1日
DILoad?
久しぶりにRenamerをコンパイル。
そもそもCodeWarrior 5で一度もコンパイルしたことがなかった、という事実が判明(プロジェクトコンバータが起動した)。そりゃそうか。
おそらくCodeWarrior 11ぐらいが最後のコンパイルだったのだろう。
PowerPC版すらなかった。
最新のUniversal Headerをダウンロードしてコンパイルすると、引っかかる引っかかる。
直すのに1週間ぐらいはかかりますな、これは。
見たことのない関数(昔、自分で書いたからそこにあるんだろうが)、例えばDILoad()とかある。どうもEventDiskという関数の中で呼んでいるところを見るとDisk関係のAPIらしいが、DeviceManagerには載ってない。もっともSafariの検索機能はきちんと動作していないので、目視による検索だが。
…
そんなんでは埒があかないのでDeveloper Connectionでサーチ。Disk Initialization Manager、とある。そんなのCarbon Referenceに載ってない(ただしもちろん目視による検索)。
なんだかよく分からんことに時間を費やしていた時代もあったのだなぁと、ぢっと手を見る。
あ、うそ。
見ませんでした。
2003年3月31日
「MacOS X プログラミング入門 Objective-C」
大阪出張の道すがら、「MacOS X プログラミング入門 Objective-C」(荻原 剛志著)を読む。
この本、一年ぐらい前から我が家にあったのだが、途中まで読んでほったらかしてたのであった。
最近は出張のときにプログラミング関係の本を持って歩くのがなかなかよいと気づいたのだ。
他に気になることがないし、気になったとしても電車の中ではどうしようもないし。
ということで、春休みの帰省か、学生が多く見受けられる電車の中、今回の本も集中して読むことができた。
普通だと飽きるか、逆にすぐ試したくなるところだけど、飽きても他にやることもないし、あせっても試すマシンはないしで、最後まで勢いで読んでしまう。
感想。
Objective-Cはシンプル、という言い方がこの本に限らず多いのだけど、まあそれは認める部分もあるのだけど、実際のところ、C++に比べるとコンパイラの実装に依存する部分が非常に多いというのは改めて再認識。
言語仕様とライブラリ仕様というのが明確に分かれていないのは(Visual Basicみたいと言えばそうなんだけど)、C++を知っている人間から見るとちょっとヤな感じ。
この本もObjective-Cとはいいつつも結局はCocoaにしか通用しない。
newやdeleteが言語仕様にないのがシンプルだ(言語仕様の拡張が少ない)、という言い方は、確かにそうだとは言えるが、それと引き替えにNSObjectの振る舞い(ライブラリの仕様)を覚えなきゃならない。
単純にC++よりObjective-Cは使いやすいということにはならないと思う。
落とし穴の数はC++と同じぐらいあると思うよ。
そんなこんなで、Objective-C++がおすすめ。
Objective-C+C++。
よいです。
2003年3月22日
MacOS Xのファイル名
ClipS Xを作っている際にもう一つ気が付いたこと。
MacOS Xのファイル名って、どうやって使うんか?
「クリッピング」っていうのはNSStringのユニコードと、NSString:dataUsingEncoding:(NSUnicodeStringEncoding)で返ってくるユニコードが違うのであった。
以前、WebDAVのファイル名で「ダ」が「タ」+「゛」になるというようなことを書いたけど、まさにそれで、「クリッピング」だと一文字分、長さが違ってしまった。
この辺、どっかにはっきりした資料あるのかな。
ちなみにdataUsingEncodingで返ってくるユニコード文字列の文字列長を取得する方法が分からず、NSData:lengthをsizeof(UniChar)(=2)で割って使ってる…
話は変わって。
Macを使うようになって最初に買ったソフトウェアはATOK8だというようなことは前に書いたけど、そのあと買ったのは
- Jterm
- Think C & Think Reference
それはともかく、Think Referenceが今まさに欲しい(いやフロッピーはまだあるけどね。Carbonではないし、リファレンスDBも古いし)
誰か作ってくれ〜
結局、インターフェイスはともかく、リファレンスDBを作るのが大変なのであるよ
2003年3月20日
Safariで画像をコピーすると…
ClipS Xを作っている際に気が付いたこと。
Safariで画像をコピーすると、クリップボードには上下が反転した画像が入る。

器用、というかそんなバグ普通作るか?
あと、今まで全然気が付かなかったが、MacOS Xではクリッピングファイルを開いた状態でコピー(コマンド+C)を実行しても、クリップボードに内容が転送されない。
クリッピングのメリット半減といってもいいような機能ダウン。
「クリップボードの内容」が文字化けしているのもどうにも気に入らないし、クリッピングファイルのビューワーを作ろうと思った(ClipS Xに付けるのが正しい気がする)
話は変わって。
以前のXOに「ソニーはバカマーケ?」みたいなことを書いたけど、バカは自分だった…。
ZD Net Macの記事に出井会長がジョブスと協業の話をして断わられたというような内容が載っていた。
断わるとはな…。まあ、いいように使われないようにしよう、という考えなのかも知れん。
2003年3月 2日
プリコンパイル済みヘッダ
うちのiBookが遅く感じる理由の一つが、ProjectBuilderでコンパイルしていると、「プリコンパイル済みヘッダのものとCarbonSound.hの日付が違うから、プリコンパイル済みヘッダは使えないよ」というメッセージが出て、コンパイルをヘッダ丸ごとやってしまうこと。
今のMacのヘッダは、Carbon/Carbon.hかCocoa/Cocoa.hぐらいしかinclude(import)しなくて済んでしまう一方で、全ヘッダを取り込んでいるというコンパイル効率の悪い構成になっている。正直、速いマシンであるならこういう単純化は歓迎だが、iBook 500MHz+MacOS Xではきつい。
調べた結果、プリコンパイル済みヘッダの作り直しは、sudo fixPrecompsをterminalから実行すればよいということが分かった。
コンパイルが速くなってちょっとすっきり。
Emacs c++-modeのc-style-alist、まだObjective-C用の設定が自分の中でも決まっておらず、ちょっと使いづらい(メッセージセレクタの':'がラベルのインデントになってしまっている気がする。よく見てはいないけど)。
早いところ決めねば。
X11のヘッダファイルはX11 SDKに入っているらしい。X11 for MacOS Xダウンロードページにリンクがあったけど気づかなかった。とりあえずダウンロードしておく。
2003年3月 1日
Cocoaの横タイトルバーウィンドウ
Cocoaで横タイトルバーのウィンドウ(上のスナップショットにも見えてるDragThingのドックみたいなやつ)を作る方法が判明。以下はメモというか独り言。
Carbonの関数を使って横タイトルバーのウィンドウを作ってからinitWithWindowRefを使えば良かったのだった。
CreateNewWindow(kFloatingWindowClass, kWindowSideTitlebarAttribute | kWindowStandardHandlerAttribute, &boundsRect, &windowRef);
myWindow = [[NSWindow alloc] initWithWindowRef: windowRef];
[myWindow makeKeyAndOrderFront:nil];
試してみて分かったが、横タイトルバーのメタルウィンドウは作れなかった。
ところで、上記のinitWithWindowRefはもしかしたら内部で指定イニシャライザ(initWithContentRect:styleMask:backing:defer:)を呼んでないのではないだろうか?
NSWindowの派生クラスを作って簡単にCarbonのウィンドウを作れるようにしようとしたところ、「initWithWindowRefはいまんところ派生クラスから使えないよ」というメッセージがデバッグウィンドウに実行時に出力される(こんなもん実行時に出力するんじゃなくて、リファレンスに書いておけって感じだ)。
確かに、派生クラスを作っているときに指定イニシャライザをどうやって呼ぼうか考えた結果、「わからんので、とりあえず試すか」というふうになってしまった。
ちなみに、
myWindow = [[NSWindow alloc] init];
[myWindow initWithWindowRef:windowRef];
[myWindow makeKeyAndOrderFront:nil];
のようにいったん普通に初期化してから、あとで再初期化しようとしてもきちんと動作しない(横タイトルバーにならない)。
Objective-Cのイニシャライザは、イニシャライザ(の多重定義)が複数あっても、それぞれ内部で他のイニシャライザを呼ぶことができるし、また同じものや違うものを混ぜて複数回呼ぶことも可能(言語仕様的に、という意味で、実際何度も初期化してよいということではないが)。
しかもイニシャライザはオーバーライド可能。
この点、C++のコンストラクタとはまったく異なる。
C++ではコンストラクタは1つのインスタンス生成時にどれか1つが1回しか呼ばれない・コンストラクタ中から他のコンストラクタを呼ぶこともできない・コンストラクタは継承されない(上書きできない)、ということが言語で保障されている。
Objective-Cのこのイニシャライザの特性により、指定イニシャライザという、コンパイラでチェックできないコーディングルールが必要となっている。
まったく異なる2つの方法で初期化できるような場合、指定イニシャライザのインターフェイスはその2つの方法を含んでなければならない。
この場合、本来はNSWindowの指定イニシャライザにはWindowRefを引数に追加したバージョンを使うのが一番望ましい(実際に内部でどう処理しているか分からないので、もしかしたらそんなことしなくてよいのかもしれないが)。
しかし派生クラスでイニシャライザを作るときは基本クラスの指定イニシャライザを呼ぶようにしなければならないので、NSWindowのような基本的なクラスの指定イニシャライザを変更してしまうというのは、影響範囲が大きすぎて今からでは無理ではないだろうか?。
initWithWindowRefには、もう一つ、Objective-Cの裏技的な方法が使われている。
このセレクタはNSWindowの正規メンバではなく、カテゴリという手法を使って後から追加されたセレクタなのであった。
カテゴリはメンバ変数を追加できないことから、WindowRefは何らかの形でNSWindow内に保持されているものと思われる(もしかしたらいったん何かもう全然別のウィンドウオブジェクトに変換してるのかもしれない)が、それにしてもイニシャライザを外付けするというのはC++では相当する手法がない。
ちなみにウィンドウを作った後、それが普通に動く(他のNSWindowと同様に動く)かどうかはまだ調べていない…。
2003年1月 3日
Dockとコントロールバーの違い?
あけましておめでとうございます。
年末1ヶ月は結構ハードな感じで、こんなの2年ぶりぐらい。
前回は、「こういうのは30前に経験しといてよかった。30過ぎたらきついし」とか思ってたけど、やっぱりそう甘くはなかった。
今年もハードに幕開けする予定で、更新頻度は低くなりそう。
という状況報告は置いておいて、Mac。
気が付けば10.2.3にアップデートされてる。何が変わったのかは全然分からんが。
で、ちょっとずつClipSをいじる。最初のテストバージョンとだいぶ違うものになってきた。
当初はよく分からんからDockのアイコンをクリックするとクリップファイルが作られる、という感じを想定していたけど
- Dockのイベントにクリックがない(Cocoaだから?)
- Docklingもクリックを拾えない
- てゆうかコントロールバーってないの?
- Dockのタイルをクリックするとアプリはアクティブになるんで、通常ハイドしておいてアクティブになったときクリップして即ハイド、てやろうとしたら、アプリメニューの「すべてを表示」とかシステム終了時にアクティブになるため、アウト(そもそもカッコ悪かったが)。
- Info.plistにNSUIElementというキーを文字列型で新規追加して、値として1を設定しておくとDockに表示されない、というのを2chで知る。これこれ、Dockに現われないアプリというかウィンドウを作りたかったんよ。
- 1個ウィンドウを作って、そこにボタンかなんか貼り付ける!
- ところでCocoaで横タイトルバーのウィンドウって作れないの?
ということで、だんだんコントロールバーみたいなのを作りたくなってきてるが、とりあえずほっとく。ClipSはそれなりに形になってきつつある(のではないか?と思いたい)。
それにつけてもAppleのドキュメントのひどさよ。FileManagerのAPIリファレンスもかなり死んでる。結局ヘッダをみるはめに。昔と違ってヘッダの探しにくさが増してるので結構大変。
NSRectがCocoaクラスでなくて構造体で、それをセットするAPIがあるってのも、Appleのサイトでは探せなかった(Javaのしか引っかからない)。
2002年11月13日
Cの変数名
C言語の話(Macにはあんまり関係ないかも)。
会社のあるプロジェクトでコーディング規則を作ることになった。
後輩にざっくり作ってもらったところ、
「局所変数名はアルファベット小文字で始め、単語の区切りは大文字にする(アンダースコアでは区切らない)。例:○someValue, ×SomeValue, ×$someValue」
てなルールが作られた。小文字で始める・アンダースコアは使わない、というスタイルは決めごとなので別段問題はないが、「例:×$someValue」が気になった。
「これおまえどの言語のルール作ってんの?」
「C++ですよ?」
「なんで$とかあるわけ?」
「使えるじゃないですか?だから使わないようにと。」
「マジ?」
というワケで、VC++を調査。確かに以下のコーディングがコンパイル通って実行できてしまった(笑)。
int main()
{
int $a = 3;
$a = 5;
return $a;
}
gccでも通っちゃう。Windows版CodeWarriorでは通らなかったが。
Perlとコーディングレベルで共通なモジュールが作れちゃうかも(ウソ)。
2002年10月22日
ScrapManagerの資料
最初ちらっとみたときから、確かにひどいとは思っていたScrapManagerの資料。まさかこれほどひどいとは。
Carbon サポート対象のほとんどすべてのAPIの資料が間違ってます(泣)。
あと、
#include <Carbon/Carbon.h>
って実際どのファイルがインクルードされているのか知らんかったが(情けない)、ちょっと見た感じでは、
/System/Library/Frameworks/Carbon.framework/Headers/Carbon.h
がインクルードされているようだ(中ではさらにインクルードしてるが、それは
Carbon.framework/Frameworks
の下にあるのを再帰的にたどっていくらしい)。
で、結局、ScrapManagerを使うと、NSPasteboardのdataForType:メソッドを使ったときと違って、Mailからコピーしたデータでも正しく?ShiftJISで取れるようだ。どっちが勝手に変換しているのかは全然分からんが。作って試せばいいのか。
2002年10月20日
ScrapManager
Inside Carbonの資料からCarbon ScrapManagerを探す。無茶苦茶さ加減にビックソ。
OSStatus GetScrapFlavorData ( ScrapRef scrap, ScrapFlavorType flavorType, Size *byteCount, void destination);なんなんだ void destinationって? 説明書きのほうにA pointer to bufferって書いてあるから一応 void* の間違いだと分かる(し、目的考えれば慣れたプログラマならすぐ分かる)が。 他にも GetScrapFlavorCountにも引数の書き間違いがある(やはりポインタ関連のミスだ)から、このドキュメントを清書したやつ(&校正したやつ)は少なくともポインタについて理解していない。
もし今からプログラミングを始めようという人がいたら、Macはやめとけ。
Appleががんばっているのは確かだが、それはそれ。
あなたまで無用な努力をする必要ない。努力もいんだけど、途中で挫折しちゃう可能性も高いからな。
話はちょっとずれちゃうが、Windowsの開発環境(といってもVB/VCぐらいしか知らんが)は、格好良くないがやはり現実的に見て優れている。理想を追ってないというのがすごい。JavaのライブラリとかCodeWarriorのPowerPlantは非常にカッコええが、取っつきにくいのは確か(まあPowerPlant Constructorがもっと使えるやつだったらとはみんな思っているに違いないが)。やっぱりPowerPlantとかはそれこそNext Step、つまり初心者が上級者になるときに挑戦するモノという感じがする。
あとはCocoa。いいけど、結局MacOS Xがまだあんまり良くないからおすすめしづらいというところか。
2002年10月17日
Oracle9i
そういえば、ちょっと前にOracleがMacOS X用のOracle9iを投入するという話をどっかで読んだ。
もともと米本社ではずいぶん前にその話があったのだけど、 日本法人は態度保留のような格好になっていた。それがいよいよ投入、ということになったらしい。
フリーのデータベースとしてはMySQLの日本語対応化が済んでいるらしいが、いよいよ商用DBの本命が登場ということになる。
2002年10月15日
「リソーステンプレート」
MacTechのサイトの古い記事「リソーステンプレート」を見つけて、ClipS Xに導入。
失敗。
メモリ破壊しているらしく、リソースが書き込まれてないし、何より2回実行すると落ちる(もちろんClipS Xのコーディングの問題、のはず)。
gdbでC++テンプレートのデバッグができないため、何が悪いかは徐々に調べることにする。
Handleに対してポインタ外しただけでメンバ変数にアクセスできるようにするという発想は(一瞬、よい!と思ったのだが)結局は使いづらかった。動作が直感とずれてしまうため、何がHandleで何がPtrか分かりにくい。
SetHandleSizeにMemHandleをそのまま渡したとき、PtrとHandleのどっちが渡されるのか、しばらく考えないと分からんというのでは効率悪すぎ(正解はoperator Handle()で返る値なのでHandleなんだろうが)。
2002年10月14日
C++とObjective-Cを組み合わせる
C++とObjective-Cを組み合わせるには、ソースファイルの拡張子は.mmにしなければならない、のか?
.hにFoundation/Foundation.hがインクルードされるように指示してあると、Objective-Cの宣言がいやでも読み込まれてしまい、.cpp/.cp/.ccのままではコンパイルできないようだ。
それはそうと、gdbがC++のテンプレートを解釈してくれず、デバッグできない。マジ?
それとは別に、Objective-Cのクラスのメンバ変数としてC++のオブジェクト(実体)を持たせようとすると、「Objective-Cのメンバはコンストラクタ・デストラクタが呼ばれないよ?いいのん?」というメッセージが出る。あかんにきまっとるがな。
2002年10月 9日
NSSoundでの再生
NSSoundで再生できるのは、AIFF/WAV/NeXT'.snd'ファイルだけ、ってことで、旧漢字Talk7で作ったClipS用のサウンドファイル(もう詳しくは忘れちゃったけど'snd 'リソースを持ったファイル?)は使えないってことになった。
クラシックのサウンドファイルはFinderでは再生できるし、iTunesでも読み込みできるのだが、何故NSSoundでは再生できないのか、ってのはひとまず置いておいて、AIFF/WAVに変換する方法を覚え書き。
まず、サウンドファイルを読み込みできるアプリを探す。これはiTunesでOK。探せばもうちょっとあるような気がするが。で、読み込みできても別形式で保存できないと意味ないが、iTunesは幸いMP3で書き出すことが出来る。
で、MP3に変換したあと、AIFF/WAVのどちらか(NeXTの".snd"ファイルはこの際無視)に再度変換する。AIFF/WAVは結構サポートしてる奴が多くて…
ってあんまりないじゃん!
とりあえず、spwaveのMacOS X対応版をダウンロード。ちょっと分かりづらいが、「別名で保存」のときに拡張子をAIFFとかWAVにすれば、その形式で保存してくれるようだ。
2002年10月 8日
iBookのマイク?
IP電話がこもるのは、iBookのマイクがおかしいせいなのかも知れん、ということで内蔵マイクで録音し、再生してみた。
といきたかったが、録音するプログラムがないじゃん!
代わりに音声認識で遊ぶ。楽しい。
CocoaAPI
Cocoaの補足。
CocoaAPIを呼ぶのはObjective-Cでないとダメだけど、CocoaはObjective-C「だけ」じゃなくてもいい。
メインはC++を使って要所要所でObjective-C、というのでも十分(皮と種はObjective-Cで、果肉はC++というイメージ?)
2002年10月 7日
Carbon API
なんですと!?
という感じだったのが、Cocoaから普通にCarbon APIを呼べちゃうこと。
リソースフォークをどうやって読み書きしようかずっと悩んでたが、なんのことはない、FSpOpenResFileすればよいだけだった。
こうなると、CocoaにするかCarbonにするか、ではなくて、CocoaはCarbonを含んでいるという言い方のほうが正しい。
Cocoa APIはMach-Oからしか使えないうえ、Objective-Cでしか呼び出せないという欠点があるが、クラシックなMacOSを使わんのであれば、もう圧倒的にCocoaがおすすめ。
Objective-Cはかなり良いし。 会社でもObjective-C使いたいくらい(Windowsなんでしょうがないが)。
とりあえず、ClipS Xが動くようになりつつある。ほんとにとりあえずだけど。
クリップボードはCocoaのNSPasteboardを使って扱う。CarbonのScrapManagerって使えるのか?調べようと思ったらdeveloper.apple.comは止まってた。
あと問題は、クリップボードにコピーされているテキストが、UnicodeなのかEUCなのかShiftJISなのか、事前に分からん点。
Mailはドラッグ&ドロップでクリッピングファイルが作れるので、それをDeRezして(リソースエディタはインストールされてないからな)解析。
今分かっているMailの作るフレーバータイプとその中身は以下の通り。
| フレーバータイプ | データ型 |
|---|---|
'TEXT' |
ShiftJISテキスト? |
'styl' |
従来のスタイル付きテキストのスタイル部分。このフォーマットはもともと最大32KByteまでしか扱えない。 |
'ustl' |
なんだ?フォント名が入っているところを見ると、なんか新しいスタイル型なのだろう。 |
'utxt' |
Unicodeテキスト。UCS2だな。 |
'RTF ' |
RTF。 |
ちなみに、MailでコピーしたテキストをそのままRawDataとして書き出してみたらEUCだった。なぜ?仮に変換するとしても、どういう前提で変換して良いものなのか。
2002年9月27日
Rendezvous
2〜3日前のことになるが、Rendezvousがオープンソースになったらしい。ソースもダウンロードできるとのこと。
Windows版のiChatができれば…。
あんまり意味ないかな。
2002年9月23日
iChat
iChatを使ってみる。
Rendezvousが面白い。サーバがなくてもLAN内でチャットできるというのはIP MessengerやYossyみたいで楽しい。
が、互換性のないチャットクライアントがまた一つ増えた、という気がするのも確か。できればAIMだけでなくてICQ、IRC、IP Messenger、MSN Messengerのすべてに対応してほしい。そんなことなったらサービス会社が怒るか(AIMは合意が取れてるんだろうけど、ICQとMSは無理っぽだな)。
Netscape7.0をダウンロード。7.0PR1がJaguarになってから使えなくなってた(起動途中で固まる)。
Windows版は思ったよか軽くて使いやすい(違うって)。
Mac版も起動が重い以外は結構軽いかも。
IEが文字をきちんと表示できないようになってしまったので(OSのせいなんか?)、こっちを標準として使おうかな。
2002年6月 5日
NIAuthenticationButton
おぼえがき。NIAuthenticationButton。
- .nibファイル(LoginWindow.nibがよい?)のウィンドウから自分のnibファイルのウィンドウにコピー&ペースト
- InterfaceBuilderで自分のnibファイルから、ソースファイルを作成させる。
- プロジェクトに登録。
- ProjectBuilderのソースファイル一覧の.mだけチェックボックスを外す。
- /System/Library/PrivateFramework/NIInterface.frameworkをリンク対象に加える。
- ビルドして実行。
認証に通ればdelegateのメッセージが出るはず。
ここまで。delegateから先はまだまだ長そう。
2002年5月23日
NetInfo活用ガイド
NetInfo活用ガイドは求めていたものとまったく違っていた(笑)。
マニュアル的なものかなと思ったら、ドメイン設計ガイドラインみたいな感じだった。結局何ができるのかはさっぱり分からずじまい。
階層的に管理できます、っていうのは分かったが、何を?って感じだ。まさかホームディレクトリとプリンタだけではあるまい。
管理者はNetInfoのドメインと階層構造を慎重に計画する必要があります、とかあるのもイヤンな感じだ。 スケーラビリィティがないよんって言っているのも同然。
というわけでもう少しドキュメントを探す必要があるな。
2002年5月13日
NetInfoについて
NetInfoについて。
なんのことはなかった、「NetInfo活用ガイド」というのがAppleのサイトで公開されていた。
これを見れば多少のことは分かるのかも(分からんのかも)。