ラベル guidance の投稿を表示しています。 すべての投稿を表示
ラベル guidance の投稿を表示しています。 すべての投稿を表示

2010年11月14日日曜日

mysqlかpostgresqlかNoSQLか

postgresqlとmysqlとどっちを使えば良いかは、
いやっちゅーほど繰り返されてきた議論ですが、
両者とも明確なメリット&デメリットがあり、
極論するなら、消去法で選択するしかありません。

postgresqlの場合

  • insertが比較的早い
  • updateを繰り返すと、性能が落ちてくる。vacuumが必要。
  • vacuumするには、テーブルロックが必要。な場合がある。
  • レプリケーションが未実装。
  • connectは比較的遅い。


mysqlの場合

  • readだけなら早い→そんな案件今時あるの?
  • レプリケーションが比較的簡単&安定→readonlyスレーブ増やして負荷分散、はよくある発想。面倒だが。
  • innodb insert/updateが激遅い。
  • sqlに方言がやたら多い。
  • 複雑なsqlを投入すると、最適化に失敗する。と言うか最適化する気がないっぽい。
  • connectは比較的早い。
  • myisamは結構壊れる。(しかも普通に使っていて)
  • innodbも稀に壊れる。(しかも普通に使っていて)


エンタープライズ業界なら、これの何れか、もしくはOracleでイイヤ、
って話になるでしょうけど、
ソーシャルゲームであると、データ量、時間あたりの処理量が
指数的に増大します。


テーブル分割に対する実装コストも馬鹿になりません。
であれば、NoSQLを使ってしまえ、というのは手です。

NoSQLは数有りますが、近頃実績が増えてるっぽいのが、mongodbでしょう。
http://www.infoq.com/jp/news/2010/10/4square_mongodb_outage
これらのトラブルも、過渡期であるが故です。

それにこのトラブルは、会員数300万人とかのレベルなんで、
仮にmysql/postgresqlで運用していたとしても、
別のトラブルが有ったであろう人数と言えましょう。知らないけど。

シャードの不均一化が原因だって話なんで、
最初から、細かいテーブル(コレクション)に分割してしまえば済む話かも知れません。
メモリ使用的にもその方が有利らしいし。
http://www.mongodb.org/pages/viewpage.action?pageId=18448682

こんな事が出来るのも、スキーマレス、create tableイラズだからです。

2010年4月23日金曜日

pythonにはnew演算子がない

pythonでは、インスタンスの作成で、new演算子を使いません。
というか、「new演算子」という構文が存在しません。

PHPやJavaやらCやらの経験者からすると、
これはやや気持ち悪い。
具体的には小生がそうでした。

ただし、その方法論が腑に落ちると、「new「演算子」」のある言語が「オブジェクト指向言語」に見えなくなってきます。少なくとも小生はそうです。

順番に行きましょう

pythonでは、普通の言語でいうところの「クラス宣言」は有りません。
しかし、同等の機構はあります。クラスオブジェクトの作成です。

http://www.python.jp/doc/2.4/tut/node11.html#SECTION0011320000000000000000

下記の例で言うと、anyclass変数に、クラスオジェクトが入ります。
 class anyclass(object):  pass
インスタンスの作成はどうするかというと、作って有るはずの、クラスオブジェクトをcallしてるわけです。だからnew演算子を付けちゃいけません。「呼んでる」だけだから。
instance_object = anyclass()
これはpython的には、「class宣言は、type型インスタンスを作ってるだけで、それはcallableである」というところです。フツーの言語が、new演算子を起点にして、「コンパイル時」にやってることを、callableを経由して「実行時」にやってる。ここがpythonの肝です。

もちろんこんな空っぽのクラスは何の役にもたちません。とりあえずメソッドを足します。
class hasmethod(object):
 def method1(self): pass

pythonは、言語としては珍しく、メソッドの引数として「自分インスタンスオブジェクト」を第1引数に書かなければなりません。

インスタンスを作ると、クラスメソッドとインスタンスオブジェクトが結びつきます。
instance1 = hasmethod()
instance1.method1()

ここでのポイントは、

instance1.method1() と、hasmethod.method1() は別物である。

ということです。

  • 前者は、インスタンスに結びついたメソッドオブジェクト
  • 後者は、結び付いてないクラスメソッドオブジェクト。
後者は、「結びついてない」ので、
インスタンスオブジェクトをどうにかして渡す必要があります。

それで第1引数 self の出番というわけです。

前者は、「結びついてる」ので、pythonがselfを勝手に足してくれます。故に、インスタンス関数呼び出しでは、self 以外の引数だけを書くわけです。


instance1 == self
とは言え、この調子だと、普通の言語で言うところの、静的メソッドは?このままでは無理です。しかし方法は有ります。

class statichas(object):
 @staticmethod
 def method1(): pass

@staticmethodデコレータを挟むだけです。

フツーの関数宣言は、selfが必要ですが、今度は逆に、selfを入れると怒られます。pythonは、selfを引数に勝手に加えるのを辞めます。staticmethodは、そういうマーキングをやってるらしい。この状態では、method1を直接呼び出すことができます。 http://docs.python.org/c-api/structures.html#METH_STATIC

statichas.method1()

ただしこれでは問題が無くもありません。関数の中からは、クラスもインスタンスも解らないので、クラス内の他のメソッドも使えません。

#逆に、一人完結してます。というアピールに#@staticmethodを使うのは、筆者はアリだと思います。

前述のクラスメソッド表記で呼び出せなくもありませんが、クラスを継承する状況を想定すると、固定で書くのは避けたいですね。

ハイ。そこで出てくるのは、@classmethodデコレータです。フツーの言語の、静的メソッドに相当するのは、むしろコッチでしょう。
class statichas(object):
 @classmethod
 def method1(cls1):pass
引数に必ず1個入ります。わざわざclassmethodと付けたのは意味がもちろんあって、
「「インスタンスオブジェクト」で無いモノ」を付けてね」という意味です。らしい。http://docs.python.org/c-api/structures.html#METH_CLASS 前述のtype型インスタンスなので、歴史的&一般的にselfとは付けません。世間一般にはclsとだけ付けるっぽいですが、小生は3文字変数に辛い思い出があるので、"cls1"にしてます。
statichas.method1()
表面上は、さっきのstaticmethodと同じ使い心地です。しかし、cls1には、statichasクラスオブジェクトが入ってます。classmethod同士を呼び出す分にはこれで行けますね。

statichas == cls1

しかも継承すれば、継承後のクラスオブジェクトがcls1に入っている。

という寸法です。

面白い発想ですね。

具体的には、app engine python-SDKのgoogle.appengine.ext.db.Model.get がlassmethodです。小生は、この辺りの実装を眺めていて、感動すら覚えました。

class「定義」の構文は、フツーの関数定義を「メソッド呼び出しに変換する」処理であると考えれば、腑に落ちると思います。故に、$thisを暗黙で「渡さない」方が何かと都合が良いわけです。

これを利用して、定義済みクラスじゃなくてtypeオブジェクトに、メソッドを後付けできます。「class定義」がコンパイラの仕事じゃないから出きることですね。真の動的言語の何たるかを見た気がします。

そんな訳ですので、フツーのインスタンスメソッドから、classmethodを使うときにはどうするか?構文を区別する必要があります。
self.__class__.method1()
static::method1とか書くより解りやすい気がすると思うのですが、どうでしょう。ダブルコロンとかバックスラッシュとか要らないわけです。オブジェクトだから。

今まで、インスタンス作成、メソッド呼び出し、と色々述べましたが、

表記上の違いはほとんどありませんし、Python内部でのメカニズムの違いも殆どありません。 他の言語でいうところの「クラス定義」は、「タイプ型オブジェクト」でしかないので、「◯◯オブジェクトのメンバ関数を呼ぶ」という機構は統一できてるわけです。


  • インスタンスメソッドを呼び出す場合
    • instace1インスタンスオブジェクトのmethod1メンバをcallする。
    • 特にmethod1にマークは付いてないので、引数の先頭にinstance1を挿入する
  • staticmethodを呼び出す場合
    • class1タイプオブジェクトのmethod1メンバをcallする。
    • staticmethodマークが付いてるので、引数には何も足さない。
  • classmethodを呼び出す場合
    • class1タイプオブジェクトのmethod1メンバをcallする
    • classmethodマークが付いているので、引数の先頭にclass1を挿入する。



呼び出し可能なオブジェクト(特にcallableと呼ぶ)を、呼んでる(call)だけ。

これに付きます。


これが腑に落ちると、途端に「new演算子のあるオブジェクト指向言語」が駄目言語に見えます。

筆者はここまで徹底したオブジェクト指向を他に知りません。
#ご存知の方は、教えてくれなくてもいいです。長くなりそうなんで。

識者が言うところによると、pythonは、広義には関数型言語らしい。
haskelには気絶しそうになりましたが、大分判りやすくて助かります。

2010年4月20日火曜日

appengineの制限は、グーグルにとっても制限

この記事の内容は既に古く、有料に限り(無料分はありますが、どうせ週$2取られるので)、専用インスタンスを無限に動かせるようになってます。
https://developers.google.com/appengine/docs/python/backends/overview?hl=ja

ただし、小生のスタンスは変わってないので、この記事自体は据え置きます。

基本的には、「30秒も要らねえよ」ってスタンスなので、解決方法は書いてません。それを探しに来たかたは悪しからず。

http://code.google.com/intl/ja/appengine/docs/roadmap.html
appengineのロードマップ的には、taskqueueやcronに限り、30秒ルールを撤廃する可能性があるらしいのですが。筆者はあまり困ってません。「悩まされてるデベロッパー」ってJavaで書いているのんじゃないでしょうか?

筆者はJavaは遅い、と思ってます。JSPの、「あー今コンパイルしてるな」なタメ時間もあり得ません。スピンアップ時間の無駄使い。

「スピンアップ終わったら、速いんだよ」とか言わない事を祈ります。そりゃあ当たり前というか。全部遅かったら目も当てられない。多分アナタも使わないでしょう。

ちなみにpythonの「スピンアップ」は2秒ぐらいっぽい。速いと見るか遅いと見るか。

もしくは、Slim3というフレームワークが速いらしいので
使ってみたらどうかと思います。ひょっとしてそれで済む話かもしれません。

そもそも、appengine は、社内で使ってるクラウドの一部を切り売りしているだけ。の筈。グーグルでも30秒ルールに従ってるのです。

datastoreの実装も、「あーこれならGmail作れるな」というものばかり。ラベルは、StringListProperty使ってるんだろうな。とか。

フツーのRDBMだったらリレーション使うところはReferencePropertyで、かなりやっていけます。またはModelクラスのメソッド実装で引っ張ってくるとかね。発想の転換が大事です。

1回のトランザクションで、データを1000個しか取り出せないのもグーグルにとっても同じです。Gmailや、Readerの件数表示が、1000以上は表示できないでしょう?件数も詳細を出さないで、800件ぐらい、とかサボってます。

と言うわけで、30秒撤廃は、グーグル内部のサーバ運営の根幹に関わるのでそうそう簡単では無いでしょう。想像ですが。

まあグーグル自身がやる、って言ってるんで可能性は0ではありませんが。まあ有料Quotaでしょう。

同じく、MapReduceをサポートするかもしれない!とか喜んでいる人が多いですが、何をするつもりなんでしょう?
#db.Model.count()が遅いから。じゃないですよね。

っていうか、
Support for mapping operations across datasets
って書いてあるんだけど、これってMapReduceなの?
違うんじゃね?

仮に使えるようになったとしても、無料はあり得ない。端的に言えば、MapReduce Quotaという項目が増えます。

30秒ルールとは別の意味で、
想定以上のリソースを食いつぶされる可能性がありますからね。

関数と戻り値と例外

値を返さなくても、「関数」とはこれ如何に?

ソフトウエアでいう「関数」は値を返さない事もあります。

関数が「値を返す」と言っても、その関数を呼んだ側が、変数に入れなければ、返さないのと同義ではあります。ただし、関数の実装としては、返すのと返さないのとはおお違いです。

perlでは、関数の最後の「式」を返します。なんか過激な実装ですが、何かしら値は戻るでしょう。

pythonとPHPは、return文の式の値が戻ります。しかし、returnを書かなくてもインタプリタは怒りません。更に、関数を呼んだ側でもエラーにはなりません。

変数の中身には?null/Noneが入っています。

これは、ハマる場合がままあります。

実装者の趣味次第だとは思いますが、
  1. 配列を渡して
  2. 何らかの処理をさせて
  3. 出来上がった配列を返す
そういう関数を想定してください。しかし、例によって、プログラマは間違えますので、
変なデータ(上の場合には、空の配列とか)をもらった場合には、何かしら「変でしたよ」って言わなきゃなりません。

変だったなりに処理を続けるか、エラーにするかは悩みどころです。

エラーの場合にはnullを返す。のは割とよく考えると思います。あれ筆者だけ?しかし、returnを忘れてもnullが帰ります。


  • エラーだったのか?
  • return忘れだったのか?


デバッグが面倒臭いことになります。

そこで例外の出番です。

「例外処理」を何故「エラー処理」と命名してないかというと、「エラー」とは限らないからです。より上位の処理で、回復できる&代替できる可能性があるからです。ユーザには、「エラー」と言わないケースもあります。

例えば、営業職の人が、顧客に怒られた。しかし、上司が出張ってくれば、オトナの解決法があるかもしれません。これが例外処理です。

顧客からクレーム系は、まあエラーと言っちゃってもいいかも知れませんが、不可抗力やら外的要因やら、色々あります。

当事者の手に余る自体は、「例外」です。上司に連絡しましょう。

入力間違いなんかは、本来は、「処理関数」に入れるまえに処理すべきでしょう。そういう意味では「処理関数」の手には余ります。「処理関数」の立場では、「エラーだ」とも言えません。

Javaは、例外を馬鹿正直に実装した言語の代表と言えましょう。

関数宣言で、自分が出す予定の例外を列挙しなきゃなりません。さもないと、関数内部で、thrawさせてもらえない。しかも、呼び出す方では、必ずcatchしなければならない。

悪い手ではありませんが、面倒臭くなりがちなので、とにかくcatchを書くけど、何もしない、みたいな形骸化する可能性はあります。面倒臭いからnullを返しちまえ。とか。

とは言え、例外補足を要求しない言語だと、そのまま例外が画面表示まで貫通しちゃって、ようやく思い出すので、どっちもどっち。

って言うかね。
appengine pythonだと、return忘れとか、
例外が画面まで出ちゃったりとか。

とりあえず次回は忘れないようにエントリを書いている次第です。

2010年4月19日月曜日

世の中は完全にunicodeですが

昔話です。

今は猫も杓子もUTF-8。VistaもubuntuもUTF-8。

UTF-8は、Unicodeの8ビットエンコーディング方法なので、
Unicodeありきです。

しかし1993年に提唱された時には、アジア圏ではかなり物議を醸しました。
usenetで結構盛り上がったので、筆者もその有様は覚えています。

unicodeは、Apple/IBM/Microsoft等、アメリカ企業が決めたものであって、
ぶっちゃけ、日本語版&中国版&韓国版を
バラバラに作るのが面倒だったんだろうと。

例えば、日本ではJISコードが或るわけですが、
漢字類は概ね、音読み順に並んでいます。

unicodeの何が物議を醸したかというと、
現地に現存する国語コードを完全に無視してるんですね。

あろうことか、文字のカタチで並べてしまった。
しかも、日本語の漢字と、中国語の漢字を、混同してます。


凄い順番でしょう?

何が困るかというと、現地エンコーディング(JIS漢字)とは、
変換表を用意するしかない訳です。

結局、変換表は、アチコチで内蔵しちゃってるんですが。

例えば、「CGI言語」として有名なperl。その漢字モジュールjcode.pm

「WEB言語」として有名なPHP。

漢字コード変換フィルタnkfのunicode対応版
http://sourceforge.jp/cvs/view/nkf/nkf-2/nkf-utf8/utf8tbl.c?view=markup

仕事を増やす仕事に絶望した!

とは言え、
英語圏のプログラムに日本語対応するには、
それ以前ではオープンソースであっても、何某かの改造が必要でした。

今では「UTF-8対応」で作っておいてくれれば、
メッセージは英語のままでもデータは日本語が通っちゃいますし、
後でメッセージデータを揃えれば済んでしまう訳です。

ソフトウエア業界の全体でいえば、楽にはなってるのでしょう。

unicodeは必要悪でもあります。
故に、今更文句を言う人はいません。
10年以上経っちゃったんだなあ。


2010年4月16日金曜日

USB2.0は、あんまり早くない。USB3.0でもいいけどその前にIEEE1394を使ったらどうか

筆者は、USB(2.0以下)を信用してません。期待してない、と言った方が正しいか。

USBは、本来はキーボート&マウスなど、低速デバイスの接続を意図したものでしたが、
マスストレージクラスに対応してはいても所詮はマウス用。低速もいいとこでした。

USB2.0で大幅高速化。ハードディスクでの接続が実用的になりました。

なのは良いのですが、筆者はこの時期に、強引にWindows98で、USBストレージを使おうとして苦労した経験があり、それが不信感につながっています。

まず、USB1.0と2.0は、上位互換なので、USB2.0デバイスでも、USB1.0でつながってしまう場合がある。何かの間違いで、って事は21世紀ではもうないと思いますが、
「面倒なんで前面の(USB)端子に挿しちゃった」ってのは多いでしょう。

PC筐体の前後にそれぞれUSB端子がありますが、前はキーボード用なのでUSB1.0、
後ろはストレージ用なのでUSB2.0、というオヤクソクがあるらしいのです。

お蔭さんで、USBフラッシュメモリを挿すのが面倒臭いです。いや、前に挿してもいいんですが、遅いでしょう?

ヘビーユーザの方なら、割と早い時期に気づいているでしょう。USB2.0は、ハブを経由すると、スピードがキッチリ半分になります。また、ハブに、USB1.0/2.0を混在すると、USB1.0の巻き添えで、USB2.0機器のスピードが下がります。

筆者はなんとなく気づいてましたが、USB3.0の説明で、理由が判りました。
「(USB2.0の通信は)半二重だから」ですね。

半二重は、通信用語です。

道路工事で、片車線しか通行できない。アレです。往路と復路が、同時に通信できません。

つまり、Aドライブへの書き込み(往路?)と、Bドライブからの読み込み(復路?)が同時には出来ないってことです。更に、ファイルコピーとなると、一旦PCにデータを戻さなきゃいけないので、ハブ〜PCの経路の帯域で、頭打ちになります。繋げば繋ぐほど、速度的に損をします。

Y字路を想像してもらって、Yの右上から左上に行き来したいんだけど、かならず下の根元を経由しなきゃならないんです。しかも根元部分は、片車線通行です。
渋滞するに決まってます。

USBハブに接続した、ハードディスク同士のファイルコピーが遅いのはそういう事ですね。USB2.0の理論的速度は、そうそうは出ません。

一方、筆者がストレージ用として信頼しているのは、IEEE 1394です。

アップル社が、Firewireとして考案?した奴ですが、
ビデオ同士の接続用として、PC以外では割と普及してるかな?

1394ハードディスクは、USB2.0に比べて、1.4倍ぐらい早いです。早さは、繋いだだけで分かると思います。

2年前の比較ですが、グラフにしてくれてる人が居ました。
グラフの形は一緒ですが、メモリの縮尺が違うので注意。

いざ繋ごうとすると、
ノートPCでは、地味に1394端子がある機種も、あります。
最近流行りの、超小型デスクトップでは、USBオンリーだから無理。

しかし、1394外付けハードディスクの値段も1.3倍ぐらい高かったりします。
概ね、同容量のUSB2.0機に対して、+5000円ぐらい。

wikipediaの記述を信じるなら、特許料金の違いらしいです。故に周辺機器がどうしても高くなる。え、5000円もするの?

一方、USB3.0規格が始まったのはいいですが、出始めなので、ドライバが熟れてないかもしれません。Windows98の時のトホホ経験が、走馬灯のように。

今のところ、対応ストレージの価格帯は、IEEE1394b用と同程度ですね。

じゃあ、1394bでいいんじゃね?と思いました。

最近では、SATA/eSATAという選択肢もあります。実際かなり早いのですが。
アレは本質的にIDEの継承者なので、ポート1個から、何台も繋げることを意図していません。端的に言えば、SATAカード1枚につき、4台づつです。
まあ十分っちゃ十分かも知れませんが。

IEEE 1394の場合は、デイジーチェーンと言いまして、PCからハードディスク1台めに繋げる。1台めの開いてるポートから、2台めに繋げる。以下略。と言うことが出来ます。スピードはあまり落ちないと思いました。正確に図っては居ません。

更に、「ハブ」が要りません。「ハブの電源」の心配も要りません。USB機器をお使いの皆さんは、沢山のACアダプタで、コンセント回りが大変なことになってますよね?

「お前がそこまで言うなら、IEEE 1394を使ってみようかな?」と思った貴方。いや知らないけど。ショップ製で1394内蔵のものは稀なので、増設が必要です。

増設カードの中で、USB2.0/IEEE1394/ギガビット、なんて欲張りのも、何種類かありますが、これは、IEEE1394ポート以外は余りスピードが出ません。理由は、内部的にPCIブリッジが入ってるらしいので。なので、それぞれのインターフェース専用カードにしましょう。2000円しません。

2010年4月15日木曜日

XMLは「固い」とお嘆きの貴兄に、YamlとJSON。

ソフトウエア業界で、XMLを知らない人は、
21世紀の現代では居ないでしょう。
15年以上前の、発祥当時は、
知る人ぞ知る的な面が多かったのですが。

XMLは、端的に言えば、HTMLのイトコです。
厳密には、HTMLのXML準拠がXHTMLで?
XMLの複雑版(?)のSGMLが、だったか?

#調べてもらえば済む話なんで、本稿では正確さは目指しません。

不等号によるタグで、囲んだり挟んだりして、
データの階層構造を表します。
HTMLのFONTタグやらAタグやらが、
まさしくそうですよね。

しかし、XMLはエンタープライズ界隈発祥なので、
Javaと同じ業を背負っています。「固い」です。

XMLは、様々なソフトウエアの「定義ファイル」として
使われているので、どこでデモ見つかります。

http://technet.microsoft.com/ja-jp/library/ee909429.aspx


面倒臭そうでしょ?
とにかく文字が多い。ギチギチです。

エンタープライズ界隈で、コレを面倒だと言う人は居ません。
面倒なのはコレだけじゃないので、
麻痺しちゃってるんじゃないでしょうか。
もしくは、Eclipse等で編集します。

まあ、データ交換言語として発祥したので、
プログラムで生成する分には構いません。

手で書かせちゃいかんだろ、って話です。

データの構造を表すのに、何通りか方法が有っちゃうのも
混乱を招く&学習しにくくなる理由でしょう。

「XML技術者認定制度」って欲分からない組織もありますね。
仕 事を増やす仕事に絶望した!

Java業界は、Eclipseを使うしかない、から良いのですが、
pythonやらPHPやらは、Eclipseに依存は無いので、
わざわざxmlの編集だけに使う、って非合理的です。
#実際、流石の使い勝手ではあるのですが。

故に、xml専用の編集ツールも、幾つか存在します。


しかし、別のエントリでも筆者が何度となく申している通り、
手段の為に、別の手段を必要とするのは、回り道ですらありません。
仕事を増やす仕事に絶望した!

結論だけ言っちゃえば、既に別の選択肢が現れています。
データ型を絞り込む事で、記述の簡素化&再構築をしています。

javascriptベースで、サーバと通信するならjson
XMLとの比較も載ってるので、エラくあっさりしたのが判るでしょう。

javascriptやpythonの、静的データ構文に酷似してるので、
プログラマには非常に馴染みやすい形式の筈。

手で書くのも苦にはなりませんが、
javascript以外でも、変換関数が付属してたりします。

更に、手で書いてもラクな(それを目指した)
フォーマットもあります。yaml
サンプルを見ると「そういうことね」と思えるでしょう。

ここまでシンプルになれば、
CSVの代替として現実的でしょう。
見た目はもちろん互換性は無いけど、用途的にね。

CSVだったら、カラム順を合わせなきゃなりませんし、
ダブルクオーテーションを含むカラムの表現がアレだったり
カンマだったり、カラムの途中で改行してくれちゃったり
取り込みはかなり面倒臭いです。

yamlはデータ構造の表現が有るので、心配は要りません。

殆どの言語向けの実装があるので、
とりあえず設定ファイルはyamlにしちゃえ、
と言うのもアリです。

2010年4月14日水曜日

句読点フリーで文章を難読化

最近、ブログやらなにやらで、文章の総量が増えても居るでしょうし、
大量の文書を読むようになったこともあるのかも知れませんが、

句読点フリーな文章が、実に多いんですね。

例えば、こんな文章があります。とある週刊誌の4/27号。
ただ画面が大きい
iPhoneではない。

一瞬、どこで切るのか悩みませんか?改行は原文のままです。
iPhoneの直後に、句読点を入れればそれで解決する話です。
しかし、大きい、で一旦改行しちゃってる。体裁の都合でね。

結構有名なサイトでも、長々と書いちゃってるサイトは多いですね。
たとえばここ。

http://gigazine.net/index.php?/news/comments/20091028_nttdocomo/

このリリースによると、NTTドコモは新設される基本使用料780円の料金プラン「タイプシンプルTM(バリュー)」と月額315円のiモード付加機能使用料月額の合計1095円を毎月支払うだけでドコモだけでなく他社の携帯電話などに対してもメールが送受信し放題となる「メール使いホーダイ」12月1日から開始するそうです。


読みにくくね?
javascriptの難読化が、まさにこんな感じでしょ?

日本語に句読点があるのは、必要だからです。
英語は、英数字しかありません。英単語の区切りは、
空白を入れなければなりません。

一方、日本語は、漢字&ひらがな&カタカナが入り混じっているので、
なくても単語の区別は、不可能ではありません。
しかし、前述の例のとおり、漢字が6文字以上も続いちゃったら、
熟語なんだか、助詞を忘れてるんだか、非常に読みにくくなります。

適切な句読点、あるいは、適切な助詞があったほうが
格段に読みやすくなるはずです。

更にありがちな文章が、その説明も、説明が先で品詞が後で出てくる。
「○○は、△△である」って書けばいいのに
「△△である○○」って書いてしまう。
格好イイ気がするので、使いたくなる気持ちは判るのですが、
実はこの文体は、判りにくいです。

何の説明だったのかが、最後にやっと判るからです。

更に困ったことに、△△の説明の途中で、□□の説明を始めちゃう。
こんな事したら、文章がどんどん長くなるに決まってます。

筆者は個人的には、再帰的説明保留と呼ぶことにします。

上の例では、料金のプラン名の話、サービス内容の話、詰め込み過ぎですね。
パワーポイントで、日夜大量の書類を作ってるアナタ。も、同じ病気です。

階層構造で表現するならこうなります。

  • NTTドコモは
  • 合計1095円を毎月支払うだけで
    • 新設される基本使用料780円の料金プラン「タイプシンプルTM(バリュー)」と
    • 月額315円のiモード付加機能使用料月額
  • 「メール使いホーダイ」
    • ドコモだけでなく
    • 他社の携帯電話などに対しても
    • メールが送受信し放題となる
  • 12月1日から開始するそうです。

合ってる?間違ってても責任取りませんけど。

説明の階層が2段、それが2組あったら、もうこれは読みにくい。
上の文章がその証拠です。

筆者私見では、限界は2段×1組です。
無闇につなげても、判りにくくなるだけってことです。

筆者が添削するとこうです。
  • NTTドコモは、料金プラン「タイプシンプルTM(バリュー)」を新設した。
  • これと従来のiモード付加機能を合わせて、「メール使いホーダイ」ドコモを含む各社携帯電話などに対してもメールが送受信し放題となります。
  • 料金は、タイプシンプルM 780 + iモード付加機能使用料月額315円 = 合わせて1095円の固定
だいぶ読みやすくなったと思うのですが、どうでしょうか。
内容が正しいかどうかは、気にしないことにします。

って言うか、料金プランも判りにくいんで、説明しにくいのは確か。
筆者も、こうやって「解析」してみなけりゃ、何のこっちゃ判りませんでしたから。

読まないで欲しいjavascriptを、難読化するなら判ります。
呼んでほしい筈の文章を、難読化してどうすんのかと。

2010年4月13日火曜日

納品物件としての、設計書類

受注開発稼業、
納品はプログラムだけじゃなくて文書も必要です。

「ドキュメント」という単語は一般名詞ですが、
この業界で言えば、設計書類の事を指す。らしいです。

20年ぐらい前までは、ドキュメントの厚さで、
受注金額が決まるという良く判らない風潮がありました。
作った方からすれば、ある程度の達成感がありますが、
受け取った側はそれを使うかって言ったら使わないです。

ウォーターフォール型の、古典的開発スタイルは、
最初の設計書類と、後期のプログラム実装とでは、必ず乖離があります。
なぜって、修正が面倒臭いから。

故に、納品後で、「別人」が修正しなければならない場合はままあります。
契約方法にもよりますが、ソース付きで納品してしまったら、
それは納品先でも修正できてしまうので、
わざわざ発注するより、自前でやっちまえ、というのは正しいです。

その場合でも、プログラムに付いてきたであろうドキュメントは使いません。
そもそも、大量のドキュメントを受け取っても途方に暮れるだけです。
実際、途方に暮れました(実体験)

仮に読んだとしても何のこっちゃ判りません。
4.5次元の「仕様」を、2次元未満の文書に落とす訳ですから
自分の期待している「次元」でなければ、推理小説読むようなもんです。

有る程度の熟練者なら、プログラムを読んでしまった方が早い。

そして、その別人の修正によって、
さらにドキュメントとプログラムでの乖離が大きくなります。

なぜそんな事が起こるのか?

理由は簡単です。
ドキュメントに細かい事まで書きすぎたからです。。

関数名とか引数の意味ぐらいまでなら、まだ良いのですが、
関数内部のフローチャートとか描いちゃったらもうダメです。
変数名とかの話をせざるを得なくなる。乖離の危険が大幅アップ。

そもそもフローチャートを書こうというのは、
プログラムの修正コストが、非常に高価だった時代の名残り。
ディスプレイもキーボードも無かった時代。

  • パンチカードだの、
  • 紙に書いてパンチャーに渡すだの。
  • 順番待ちだの。

黙って待ってる訳にもいかないので、紙と脳みそでデバッグするしか無かったのです。

昔話です。筆者は伝説でしか知りません。

フローチャートが全面的に要らない。とは言いません。
製作者が、思考を整理するためには非常に有効です。
ただし、納品物件としては、要らないんじゃね?と思う。

20年前ぐらいまではまだ良かった。予算はあったので。

ところが21世紀になってみたら
物件自体が、小規模化&短期化&低予算化してますので、
ドキュメントを書く時間すら惜しかったりします。

本当に細かい話は、ソースを読んでしまった方が確実です。
そして、納品物件としてのドキュメントは、
オヤクソクではなく、目的を考えるなら、
ソースを「補間するモノ」でなければなりません。

要件定義だけはすり合わせる必要がありますが、
クライアントの想像力が豊富でないと、大抵何の話か通じません。
結局、修正せざるを得なくなります。
じゃあもう作ったの見せちゃった方が早くね?

それでも依然として、「COBOLで慣らした」感じの方々は
エクセルで罫線を作り込んだフォーマットを持ってきて
そこに文章を入れたくて仕方ないらしい。
「帳票」って奴ですね。

エクセルやらワードやらを、
結局「清書ツール」としか使ってないので
運用は、「紙文書」を逸脱して居ません。
ということに気づいているのか居ないのか?

それはそれで問題があるのですが、それは別の機会に。

2010年4月12日月曜日

C/C++言語の反省

色々なエントリにバラバラに書いちゃったので
一旦纏めます。

21世紀現在に至っても、
世の中の手続き型プログラミング言語は、
どこかしらC/C++に似た部分があります。

言い換えると、C/C++言語の反省点を踏まえて
言語設計をしていると言えます。

C/C++言語の、筆者の考える反省点は次のとおりです。

  • boolean型が無い。
  • 関数の戻り値として、1個しか返せない。
  • 生ポインタ。
  • 故にメモリ管理が手動
  • (template)
  • プリプロセッサ
  • #include
  • (例外)
  • (名前空間)
  • (多重継承)
そもそもの話、C言語自体設計が古いので、
現状のメモリ事情やら、ソフトウエア技術やらに即して居ません。

象徴的なのが、「きめ細かいメモリ管理」を「人間がやる」ところ。

メモリが狭いって言ったって、携帯電話でもメガの単位はあります。
キロバイト単位を節約して、8ビットCPUを絞り出していた時代とは違います。
その証拠に、イマドキのケータイアプリは、概ねJavaです。

ポインタはC/C++の歴史的魔道と言えます。
メモリ管理方法が極めて少ないので、多重ポインタで実装するしかありませんが。
その中のどこかに構造体ポインタが挟まってたらもう駄目です。
この宣言がどエラい苦労します。
もはや呪いのアイテムです。

Cの時代は、メモリ確保と、その用法が完全に無関係なので、
何バイト確保しようが、それをいくらでも逸脱できます。
故に、バッファオーバーラン等の危険が常に付きまといます。
気をつけます、って言ったって、限界があるでしょうそりゃあ。

C++では、一応class宣言があって、new/deleteが有りますが、
deleteが手動だったりしますし。

プリプロセッサは、
プログラムソースを、コンパイラに入れるまえに書き換える。
コンパイラの機能があまりにも少ない故の、魔道具です。

「構造体宣言の前半の中括弧まで」を展開するマクロとか
ソースとマクロ定義のどっちを見ても、気持ち悪そうな実装が出来ます。

「関数の宣言に、特定のナニかを付け加えるマクロ」なんかは、
オープンソース業界の、軽量言語の実装では今でも散見します。

#includeは、
関数定義を、外部ファイルからサラリと読み込む方法がないので、
ソースプログラムを書いたら、*.c/cppと*.hの一組を書くのが「お約束」で、
「ウチの関数を使いたかったら#includeしてね?」って事になってますが、
その*.hは、利用のためだけじゃなくて、本体の実装のためでもあるので、
あちこち#includeを渡り歩いています。

これがまた面倒くさい。
多重include防止の為の #ifdef とか、もう生活の知恵の極致です。

#includeの向こう側が書き換わっちゃってると、
関数の引数とか、構造体の形が変わっちゃってるかもしれないので、
全てリビルドせざるを得ません。

そのためのmakeやらmakefileやらはもちろん或る訳ですが、
仕事を増やすための仕事に絶望した!

関数の戻り値が、1個しか戻せないのは、結構あちこちでハマリます。
構造体をnewしてreturnするとかは、C++ではあまりやりたくないので
1個だけreturnして、残りは引数に、参照渡しで入れ物を貰う。

C++では、「オブジェクト指向っぽいナニカ」が出きるようになりましたが、
多重継承という呪いのアイテムも付いてきました。

仮想関数やら、オーバーライドやらは、Cの延長線上では、
関数ポインタで実装するしかないわけですが、
ネイティブコンパイラであるが故に、「関数の順番」が非常に重要です。
#コンパイルしちゃった後は、オフセットでしか参照してないらしいので。

マイクロソフトも、MFCやらOLEやらで、七転八倒した形跡があります。
#そして、やっぱり辛くて、C#を産むわけですよ。

とまあ、反省することしきりですが、

筆者がC/C++を使わなくて済んでいるのは、
(例えば)python/PHPの作者がC/C++で実装しているお陰。

ありがたいことです。

2010年4月11日日曜日

Javaは「固い」とお嘆きの貴兄に

Javaは、1990年、C++の反省を踏まえて、
Sunの誰かさんが作りました。


と、言う訳で、
プログラマに「要らん苦労をかけさせる全て」を、
Javaで、解消しようとしたわけです。
実際、前述の問題点は概ね解消してますが。

新しい別の苦労が産まれてしまった、というオチ。

  • 1ファイルにつき、publicクラスは1個づつ。
  • パッケージ名は、同名のディレクトリに置く。

それ故に、深い深いディレクトリに、
細かいファイルがドッサリ出来る事になってしまった。

#大規模&分担開発がやりやすくはなってる。と思うけど。

これはこれで、人間が管理するのは現実的ではないでしょう。

IBM程の企業が「eclipseを開発するしかなかった」のも道理。

一昔前までは、Java至上主義みたいなところがあり
そういう人々は、軽量言語をカス呼ばわり。
「PHPだと遅くて駄目ですね」みたいな論調が多かったのですが、
大事な話が抜けてます。

  • エンタープライズなサーバPCは、そりゃCPUが強いし、メモリも広大。
  • 故に、「重たい」JVMを動かしても、そりゃ早いでしょうよ。
  • 故に、「軽い」PHPなら更に早くなる筈なんだが?
#重い重いと評判のWindows Vistaですが、
#同じPCに、Windows 95を入れると、目の覚めるような早さ。らしい。
#インテルの苦労は、マイクロソフトが全て無にしています。

「楽天がPHPを採用」あたりから風向きが変わってきました。

言語は、所詮は道具なんで、客観視が大事です。
色々使い比べないと、良さも悪さも判りません。

Java VM上で、「Javaでない言語」を動かす試みも結構あります。


いわゆる軽量言語寄りのラインナップが印象的ですね。

全く新しい言語も


そうです。Javaでの開発は、皆も辛かったんです。

2010年4月10日土曜日

appengineの真骨頂は、pythonにあり

日本の、エンタープライズ界隈の方々は強情で、
app engineのdatastoreを難解だと感じている様です。+

JavaのJVMによる、他言語実装、例えばrubyもあり、
http://jruby.org/
app engineでrubyを使う人も居るには居るらしい。
http://code.google.com/p/appengine-jruby/

RDBのJava実装がありまして、
OpenOfficeのBaseでも内蔵してる代物なんですが、
http://hsqldb.org/

これをdatastoreのミドルウエアとして使った人も居ます。
http://www.littlesoft.jp/sql4g/

確かに、RDBMを使えれば、リレーション使いまくりですが、
そもそもJavaは、「固い」言語なので、datastoreの柔軟さが活かせません。

って言うか、そこまでpython使いたくないですか?と聞きたい。

pythonのwsgirefとか、webappは、JavaのServletに近い考え方ですね。
どっちが先だか私は知りません。
しかし、app engineの真骨頂はdatastoreにあります。

RDBに、GUIツールが存在するのは、「管理が面倒臭い」の裏返しです。
Java自身のためのEclipseが存在するのと同義です。

しかし、datastoreのORマッピングなら、ソースを修正するだけです。
pythonなら多重継承すらできます。

いやもう、SQLなんか書いてられませんよ。面倒で。

JavaのJDOとやらからでも、比較的簡潔な記述が書けますが、
http://code.google.com/intl/ja/appengine/docs/java/datastore/dataclasses.html

pythonのそれとは簡潔さが比較になりません。
http://code.google.com/intl/ja/appengine/docs/python/datastore/entitiesandmodels.html

記述量は、5倍以上ですね。
筆者は(python版の切り口に対して)「え?これだけでいいの?」と素直に感動しました。

pythonのアレを強引にJavaで例えるなら、
classのstatic変数の初期化で、カラム名&型の定義をしています。
しかもnewすると、同名の変数が、データカラムとして使えるという。
Javaでそんな記述は不可能です。pythonだからこそ可能です。

しかしこれはpython djangoのORマッピング機能上に実装したものらしいので、
http://docs.djangoproject.com/en/dev/ref/models/instances/
python djangoが、もともとイカしていたといった方が良いでしょう。

datastoreが難解なわけじゃなくて、
JDOのアノーテーションが気持ち悪いのです。
見比べでつくづく思いました。

2010年4月8日木曜日

Windowsの「ソフトウエアの追加と削除」

WindowsのXP以降は、概ね皆さん、お使いだと思います。筆者の仕事場というか自宅でも、仕方なく、1台稼働しています。

でもWindowsって、年がら年中「重要な更新」来ますよね。

なんかもう、「一生のお願い」を何回も言う人みたいで、笑えませんか。いや、笑えないでしょう。仕事で使ってる人は。

初代のXPは、それはもうセキュリティホールだらけ。らしい。インストールしっぱなしで、ネットに繋いで2時間放置。もうウイルスだらけになるらしい。私は試してません。週刊アスキーの記事で読みました。

網戸が穴だらけ、みたいなものです。蚊が入り放題ですよ?

それだけじゃなくて、地球上のWindows利用者が、ウイルスを培養してるので、無くなりません。って話なんですけどね。

#最近では、P2Pによる、ファイル漏洩の方が問題だったりしますが。
#色々と。

サービスパック2を入れると、だいぶマシになるらしいですが、その前に「サービスパック」じゃねえだろ。何のサービスだよ。善意じゃねえだろ。責任だろ。と思いませんか?

エラッタ(errata)と呼んでみたりとかね。「既知の問題を許容するための仕組み」らしい。オイオイ、誰も許容してねえだろ。
探してみると、フィルタリングを許容と訳しているらしい。
これは日本語訳のセンスの問題でしょうか。

Windows2000 Server辺りを未だに運用してる部署でも、サービスパック毎月入れるのが大変すぎなので、やってない。とかも聞きます。また聞きです。固有名詞は知りません。

「linuxはフリーだからねえ」で懸念するクライアンドは、最近はだいぶ減ってきましたが、逆にWindowsの何を信用しているのかお伺いしたい。

「文句を言う相手が欲しい」
→でもそれでマイクロソフトが何か修正してくれることないですよね。

「(linuxだと)操作が判らない」
→イヤイヤ、Windowsはもっと判らないですよ?

「GUIで設定するしかない」のに、「必要な機能を何処から呼び出すのか判らない」でしょう?#やっぱり、信用してないじゃん。というのは置いといて。Windows95の時に、思いませんでしたか?「プロパティって何?」

「設定の並べ方の、センスが悪い」のもありますね。Office2000辺りから、メニューが勝手に隠れるようになりましたが、あれは本末転倒もいいとこです。「いつも使う機能」は「いつもと同じ場所にあるべき」。マイクロソフトのアイツラ(誰?)は、それが判ってないんです。

Windows95から、ソフト開発のガイドラインを儲けて、「Program Filesに入れてね」なんて話になりましたが、これも実は形骸化しています。

DLL類の一部は、依然としてC:\WINDOWS\SYSTEMに「インストール」しています。

未だに、Windowsのソフトウエア管理は、無法地帯である、という証明だったりするんですが、気づいている人は少ないですね。

「インストーラ」が「インストールする」DLLの一部は、マイクロソフト自身が(開発者に)配布しているものですが、これは単体で配布できない、というライセンスになってます。

試しに、Cドライブで、mfc*.dllがいくつあるか検索してみてください。結構出てくると思います。しかもバイト数が違う。故に中身も若干づつ違う筈です。知らないけどね。

#って筆者が自分で試そうとしたら、ナニコレWindows Searchって。
#何時インストールしたっけ俺?
#「ココをクリックして検索コンパニオンを使用します」
#何を言っているのかお前は

そうであるが故に、ソフトウエアの配布側としては、自分が使ったmfc*.dllを付属させるしかない。訳です。

インストーラのやってるのは、自分に必要なファイルだけを入れること。

アンインストーラは、自分が入れた「筈」のファイルを削除すること。

なんかお役所仕事?

しかも、前述の通り、似て非なるファイルを、C:\WINDOWS以下にいれざるを得ない場合もままあり、こういう時は、アンインストーラは自信なさげに言います。

「このDLLは他のプログラムから使ってないようです。削除しますか?」
お前が入れたんじゃないのか?!お前が判らんでどうするのか?ゆとり世代か?!

コントロールパネルにある「プログラムの追加と削除」では「アンインストーラの管理」をやってるだけです。

アンインストーラに丸投げ。
アンインストーラは、人間に丸投げ。

2010年4月7日水曜日

MySQLはそれほど速くないし、PostgreSQLはそれほど遅くない in 2010

MySQL 5.0時代(2011年後期現在での最新は5.5.17)と、
PostgreSQL 8.0時代(2011年後期現在での最新は9.1.1)の知識で言います。

今では更に事情が変わってる可能性があります。
まあ、昔話と一般論を述べてると思ってもらえれば結構です。

同時期に作成したらしいベンチマークが或るので、貼らせてもらいます。





#大小文字の打ち分けが面倒なので、固有名詞は小文字で圧します。

端的に言えば、mysqlはマニュアル車、postgresqlはオートマチック車です。

mysqlは実は、特定状況下でのみ、高性能を発揮します。らしいです。
特定状況下は、筆者は存じません。

大量のチューニングパラメタが或るのも、特徴でしょう。
これは、悪い特徴です。適当に使うと、まったく性能は出ません。

mysqlの強力なアドバンテージは、レプリケーションの内蔵。
それに「尽き」ます。それだけしか無い。
レプリケーションの設定は、非常に簡単です。
「同期」とは言えませんが、更新のタイムラグは概ね無視できる範囲でしょう。

一方、mysqlは、不可避レベルの「苦手」が幾つかあります。

SQLの文中で、select以外では、テーブルの自己結合が出来ません。
insertの文中で、既存のレコード数を数えて、+1してinsertしたい、
って良くあると思うですが、mysqlのinnodb/myisamではこれは不可能です。

これに限らず、複雑なSQLを投入すると、
不適切なindexを使う、もしくはindexを諦める場合があります。
2段サブクエリ程度で、もう駄目な感触です。
そのための FORCE INDEX なる、SQLの独自構文があります。
#どんだけ手動なのかと

mysqlで、大量のinsert/delete/updateをすると、
性能がゴッソリ落ちます。
大量の、というのは、数十万レコード、程度ですね。

故に、遅延insertなる方言があります。
なんかindexの作成が、下手なのかなあ。という感触です。

ランダム文字列系の、ランダム順insertは、かなり遅い。と思う。
postgresqlで同程度のクエリを流したときの、
数10倍、時間が掛かることがあります。

ちなみに、postgresqlで30分で終わるinsertが、
mysqlのmyisamで3時間、innodbで12時間でした。
信じるも八卦。信じないも八卦。

また、全部deleteする場合は、trancateを使おうね、とか
いや、運用でそんなケースそんなにあるのか?と
逆に聞きたいのですが。
手動でやってるなら、truncate使いますよそりゃあ。

postgresqlの問題点としては、vacuumを懸念している人は多いと思いますが、
実は、mysqlもvacuumをやっているのです。
しかも1レコードづつ。

いや、オフィシャルで「mysqlでvacuumやってます」
なんて記述は一つもないのですが、
遅いなあ、と思ってstraceしてみたら、
ファイルコピーしてやがった事がありました。
いや俺今delete fromしたよね?なんでファイルコピーが必要?みたいなね。

トランザクション量がもの凄い多い場合、begin〜commitが遠い場合は、
これまた性能がゴッソリ落ちます。
数10レコードづつcommitすれば劇的に改善しますが。

あと、myisamテーブルは壊れる可能性があります。
修復コマンドがあるくらいですから。

実は筆者の経験で、innodbが壊れたことも一度ありました。
実験機だったので、テストデータを入れ直しましたが。

mysql自身の苦手、とは違いますが、いや筆者が苦手ってことか。
ユーザ登録をgrant構文でやるのはどうにも気持ち悪いです。

一方、postgresqlは、設定項目が非常に少なく、
起動するだけならすぐです。

しかも、結構複雑な、3段サブクエリを投入しても、
なんとか結果を返します。
適切にindexを貼れば、ちゃんと使ってくれます。
普通に使ってたら、特に「○○が苦手」という感じはありません。

postgresql-8以降、使ってないので判りませんが
(しばらくmysqlの案件が続いたので)
簡易なvacuumをマメにやるようになってるらしいので、
テーブルロックレベルのvacuumは短時間で済むようになってる。らしいです。

とは言え、大量のinsert/updateを続けると、徐々に性能が落ちてくるのは確か。

数千レコードを舐めて再構築するタイプのトリガを、書かざるを得なかった事があり、
いや、仕事で書いてね、って頼まれたんですが、
テストで何度か回しているうちに、あれ?遅くなってきた?みたいな感触はあります。
ただそれでも、2分が5分になるだけです。
倍にはなってるんだけど、元々が「待っていられる」時間です。

最悪、トランザクションスクリプトにvacuum fullを含めちゃうのは手でしょう。

総評としては、

mysqlは、SQLサポートそのものが不完全なので、SQLの記述に手間取る。
結構ありがちな状況で、ゴッソリ性能が落ちやすい感触。

postgresqlは、問題の先送りで、
更新が多いっぽいときは、トランザクションにvacumm fullと書いちまえ。

結論としては、

どうしてもレプリケーションを使いたければmysqlしかない。
その他は、postgresql使っとけ。

もうそんな気持ちです。

2010年4月5日月曜日

zero-install パッケージ管理システム

前フリです。

ディストリビューション依存というか、
それぞれ標準的なパッケージ管理システムがあるわけですが、
大別して、deb系/rpm系に、2分しちゃってると言ってよいでしょう。

ubuntu, debian apt, dpkg
fedora, redhat rpm, yum

筆者は、redhat系からubuntuに鞍替えしました。本家debianの、debシステムを継承しつつ、openofficeまで入ってたりの充実したパッケージ群。普通にデスクトップOSとして使えます。そうやってディストリビューション配布のパッケージを使う限りはまるで問題はありませんが、そうでない場合に困ることが色々あります。

例えば firefox。本家の最新版は、3.6.2ですが、ubuntu-8.04の標準は、未だに3.0.x系です。ディストリビューションごとアップグレードするのも色々アレです。

ディストリビューションとしては致し方ないことですが、オープンソースのボランディアベースと言えど、配布にはある程度の責任が伴うので無闇に最新バージョンを追いかけるわけには行きません。

しかたがないから、自分で入れるわけですが。

バイナリの*.tgzも配布している製品もありますが、
/opt/ナントカに掘って、シンボリックリンク張って、とか。
別にルートパーティションに入れる必要はないのですが、
ホームに入れるのも気持ち悪かったりとか。

外部の人間が、「ubuntu-○○用」として配布しているリポジトリもありますが、
実際使ってみると、意図しないパッケージ群までドッサリアップグレード掛かったりして、
動かなかったらどうしよう?と結構不安です。


本題です。

linux用の、
ディストリビューション非依存の、パッケージ管理システムとして、
zero-install http://zero-install.sourceforge.net/
と言うものがあります。

もっと有名になっても良いと思います。

日本語説明もあるにはありますが、
記事が古いのと、事情の説明に終始しています。
http://sourceforge.jp/magazine/07/02/21/0133253

端的に言えば、パッケージ名の代わりに、URLを使います。まあURLの正体は、パッケージ定義ファイルな訳ですが、ソフトウエア特定の方法としては悪くないでしょう。
ダウンロード&展開は自動です。展開は、自分のホームディレクトリ .cache/0install.net/ を掘って、その界隈でなんとかしてくれます。気持ち悪い気がしますが、管理はzero-installがやるので実害はありません。

一方、ダウンロード済み&そのディレクトリに展開済みのものは、サラっと起動します。

運用は簡単です。例えば、
0launch http://0install.net/2006/autopackage/Lincity.xml
これだけで、lincityが動きます。root権限も要らないので、気楽っちゃ気楽です。
アップグレードも自動です。xmlファイルの中身の更新が何かしらあれば、「更新しますか?」とは聞かれます。

zero-installの成り立ちは、何がしかのオープンソースソフトウエアの作者が、各ディストリビューションに自分の成果物を入れてほしい時ですね。ところが前述の通り、それぞれディストリビューション毎に流儀が違いすぎて、色々面倒です。ディレクトリ構造しかり。

2010年4月4日日曜日

ソースプログラムのバージョン管理 mercurial のススメ(1)

プログラムは、ソースを1文字でも変更すると、
それは別プログラムだ、という位(筆者が言ってるだけですが)
デリケートなものです。

しかし、別エントリでも何度となく申しているように、
人間は間違えるものなので、
修正を繰り返すうちに何時の間にか動かなくなったり、
一つのバグを修正したら、別の機能が動かなくなった、
と言うのも、残念ながら良くあることです。

何処を修正したのかすら思い出せない。のもあり得ます。
「今までで一番マシだった状態」まで遡るのが一番です。

ディレクトリ丸ごとコピーなんてやっては居ると思いますが、
それはバージョン管理ではありません。バックアップです。
そして大抵は、忘れた時に一大事が起こります。
文字通り、ゲームのセーブデータみたいなもんです。

バージョン管理は、やはり専用ツールを使うのが一番です。
今すぐダウンロードしましょう。

結論から言うと、mercurial系が最適です。
プラットフォームを選ばず、
インストーラ一発で全てが揃うからです。


mercurialの競合と言うかライバルとして、gitがよく挙がりますが、
Windowsで、となると、cygwin入れたり面倒臭そう。
「道具」を入れるのに苦労するのは本末転倒です。

普通にオープンソースというと、C/C++で書くのがフツーでしたが、
mercurialは9割以上がpythonなので、
プラットフォーム依存が非常に少ないのでしょう。
と言うかpython本体が頑張ったお陰。移植が簡単。
故に、Windows及びMacOS X用まであったりします。
そういうのって、オープンソースで有名なのは
eclipseとかfirefoxぐらいでしょうか。

筆者がmercurialを知ったのは5年ほど前ですが、
python恐るべし、と思ったものです。
#当時はPHPで仕事してました。

バージョン管理は、必須業務です。
一人でも、ファイル1個でも効果があります。
やらないのは色々無駄です。

本家サイトで、まさしくmercurial自身で、
mercurialのソースを管理している模様。
リポジトリブラウザ機能は、外部からでもイジらせてもらえます。
便利っぽいでしょう?

こっちの方が「便利さ」は解りやすいかな。
バージョン遷移のグラフ表示です。
上はツリーの便利さ(面白さ)を感じてもらうために派手な部分を選んでます。
最新版はこっち
http://selenic.com/repo/hg-stable/graph/

私はlinuxのコマンドラインベースでモリモリ使ってますが、
Windows用では、シェルエクステンションが有るので、
右クリックから使えます。
あー、でも、日本語化は遅れていたと思った。
#って言うか、プログラマなら英語に恐怖感を持っちゃ駄目です。

オフィシャルサイトでもガイドがありますが、
日本語紹介記事もアチコチにあります。
分散バージョン管理論の話まで行っちゃってるので、お得です。

知人に「リリース以前は、バージョン管理は要らない」なんて言ってる人が居ますが、
リリースバージョンと、ソースバージョンの話を混同してますね。
そうだと思いたい。

バージョン管理は、基本的には「今までで一番マシだった状態」な状態を
段階的に記録していくものです。段階は、細かければ細かいほど良いです。

別の派生バージョンに修正を適用したり、がやりやすくなります。

ちなみに、リリースバージョンは、タグ ブランチ として管理すると良いです。

2010年4月3日土曜日

pythonは、標準関数を置き換え放題

全くの不可抗力で発見しましたが。

pythonって、"str"を変数として使っても怒られません。
str = ""
通常、「ビルトイン関数str」として使っているモノは、
実は、変数strの中身がcallableだった、というだけなのです。

知る人ぞ知る、かも知れませんが、わざわざこんな事をやる馬鹿は居ません。しかし、筆者はまだpython歴1年なので、勘弁してください。

こうすると復活します。
import __builtin__
str = __buitin__.str

言語のセキュリティとしては、かなり緩いですね。「変数を書き換え」を制限する方法が存在しないので、第3者のモジュールを持ってきて、無改造でもかなり色々出来ます。

例えば、appengineのdjango.utils.simplejsonは、datetimeを受け付けません。not serializableとか言って、例外で落ちます。

しかし、その例外を出してる関数は、呼ばれていきなりraiseしています。オーバーライドしてね。と言わんばかりです。これを外側から書き換えてやれば、datetimeを変換できるようになります。

gistに貼っておきました。
http://gist.github.com/358287

pythonで商用ソフトを作ろうか、と思うと、この辺りで躊躇しますね。メソッド名も全部__dict__で見えちゃいますし。最終的には、難読化しなきゃならんのかと。javascriptがそうである様に。

しかし、デコレータは、この機構を最大限活用しての事なので、pythonでは必要悪と言えるかもしれません。

2010年4月1日木曜日

pythonのデコレータは

pythonのデコレータは、なかなか面白い発想ですね。

pythonでは、
関数宣言は、「callableオブジェクトの作成」でしかない、ので、
関数宣言自体を、他の関数の引数に渡せる、と言うことであって、
それだけでも、wrapper関数を、サラリと書ける。
と言うことなのだろう。と思う。

python2.3以前でも、
staticmethod「ビルトイン関数」を通して、
同じ変数(メソッド名)に入れ直す、みたいな構文はあったのですが、

python2.5からのデコレータ構文を、
class文の中で使って、デコレータ関数からcallableオブジェクトを返すと、
どうやらそれを新しい関数宣言として使ってくれる。らしい。

まあ2.5自体、2年以上前のリリースなので、時期的には今更ですが、
筆者個人は、python歴1年生なので、筆者としては衝撃です。

オブジェクト指向の軽量言語ならではの発想です。
軽量言語であっても、関数類の再定義を認めてないものが殆どです。

C++/Cまで遡れば、構造体の関数ポインタを入れ直す感じに似てますね。

関数をサラリと再定義できるのさることながら、
1行書き足すだけで使える、のが素晴らしい。

とりあえず思いついたのは、appengineのRequestHandler。
SDKでテストしているうちは何とも無かったのだけど、
appengineに突っ込んでみたら、Quota系例外がボコボコ出るので、
基本、try/exceptは遣っておいた方が良い。
のですが、デバッグ中は逆に面倒だったりします。

そこでデコレータの出番です。
作ってみた。gistにあり升

http://gist.github.com/351412

2010年3月30日火曜日

仕事で使いたくないプログラム言語

結論から書きます。続編あり升

仕事で(プロが)使うなら、次のことをサポートすべき。
言い換えると、私が使うならサポートして欲しい。

  • 概ねオブジェクト指向 → 大規模開発に必要
  • 多重継承 → コピペ禁止。mix-inには必須。
  • 豊富なシンタックスシュガー → 細かい事なんか気にしてられない
  • 名前空間 → 大規模開発に必要
  • 豊富な標準ライブラリ。もちろん名前空間で適切に隔離していること。
  • 例外処理 → 大規模開発に必要
細かい話は、別エントリを書く予定なので、とりあえず割愛します。

日本では何やら、エンタープライズ界隈を中心に、
Java信仰なるものがあるっぽいですが、
Javaは小規模の仕事にはまるで向いてません。
10人月以上の案件に使うべき。
シンタックスシュガーが無いのもダメです。

今大流行りPHP系も、正直気は進みません。
重要な、名前空間と多重継承が使えません。
別エントリでも書いてますが、暗黙型変換が暴発してるので、
故に、今度は大規模開発には向いてません。
豊富すぎる標準関数が、名前空間を食いつぶすのもダメです。
PHPタグで始めなきゃいけない点も萎えます。

C++/C系は、生ポインタがある時点で、正直勘弁です。
言語は道具でしかありません。
受注金額がゴリゴリ落ちてるこのご時世、
メモリ確保と開放の心配までやってられません。
人間のやることですから、メモリ開放なんて、忘れるに決まってます。

Perlは、「CGI言語」として定着しましたが、
最近はPHPにその人気を奪われがちです。
オブジェクト指向の切り口が特異なのと、例外処理が無い点で、
仕事言語としてはマイナスです。
Mooseとやらのお陰で劇的に改善しては居るらしいですが。
いや、嫌いじゃないですけど。括弧を省略できたりとかね。
わざわざ「Perlで書いてね」なんて酔狂な顧客は居ないでしょう。

ケータイアプリプラットフォーム事情2009年度版

アプリ紹介ではありません。
プラットフォームとしての考察です。

日本でケータイアプリというと、キャリア毎にそれぞれ1仕様。

docomo→iアプリ。javaベース。DoJa系
au→ezアプリ。C++
softbank→V/Sアプリ。javaベース。MIDP系

同じjavaでも、docomo/softbankではフレームワークが違ってたり、
例えばezアプリ範疇であっても、機種毎にメモリや解像度やら大違いだったりで、
作ってみても、実機で動くとは限らない。らしい。
だからezアプリのサイトの「対応機種」は、あんなに一杯書かなきゃならない。

さらにezアプリJava版も始まっちゃって、混乱に拍車を掛けてます。
とは言え、C++ベースの開発が、評判悪かったに違いない。

日本のケータイアプリSDK付属のエミュレータは、
いわばフレームワークエミュレータ。と言うべきか。
ハードウエアレベルの保証はできて ません。

iPhoneも有るけど。プラットフォームとしては、
世界共通さらにiPod touch互換なので、
非常に好意的な意味で、事情が違う。
ケータイアプリだと思わない方がうまく行きそうな気はします。

実際に製作している現場の苦労は尋常じゃない。らしい。

ezアプリの開発では、「検証センター」というのがあるらしく、
auの実機が大量にあるらしい。それを端から試していくわけです。

こんな「機種依存」の激しい業界って、ありえなくね?
16ビット未満のノリですよ。正直。

まあ何処かの政治家に言わせると、
産業の創出、って奴にはなってるのかも知れませんが。
いや聞いたことはありませんが。

こういった事情に一石を投じよう、というのが本来のAndroidの姿勢。だと思う。

ケータイアプリで苦労した経験のある人は、
Android SDK付属の「エミュレータ」を疑ってるんだけど、
CPUレベルエミュレータ だから、互換性が尋常じゃない。
docomoのアレとは大違いです。

そうは言っても、
日本のケータイ事情を考えれば、今まで散々作っちゃったアプリがあるから、
Androidに移行してハイさようなら、って訳にはいかないでしょう。
そういう意味では、HT-03aの発売には、一定の評価はしています。

ezアプリは、ベンダーに苦労のさせっぷりが尋常でない。らしいので、
docomoよりさらに呪縛がキツイと思う。
auがAndroid参入が出遅れたのは、致し方ない。と勘ぐります。
それにしても遅すぎ。docomoより先に出すべきじゃないか?芸風的には。

一応筆者は、iアプリの製作経験もあるにはありますが、
作り比べてみると、Androidは、プラットフォームとしては優秀です。
ケータイアプリの範疇を、最初から逸脱してますから。
例えば、電話の着信を拒否、を実装できる。

ただいずれも、開発にはある程度の熟練を要する、という点では一緒です。

とは言え、softbank以外は、Androidを出すことになるらしいですから、
ケータイアプリ開発業の皆さんも、ある程度楽にはなるでしょう。