2008-05-23

日本の技術系プレゼンテーション参加者のためのハブサイト

perl-users.jpのインスパイヤブームの流れで、こんなサイトを立ち上げてみました。

今後、セミナーとかイベントで撮ったり公開した動画はそっちの方に投稿すると思います。 こっちはプログラミング関係のブログとして残します。

2008-05-20

perl-users.jp

perl-users.jp - 日本のPerlユーザのためのハブサイト というのを id:yappo が立ち上げてくださいました。

www 上の日本語で書かれている perl 情報は本当に玉石混合で困ってたので、このサイトが内容充実しつつ "perl" で検索して最初の3つぐらいになったら素敵だとおもいます。というわけで支援。

2008-05-19

YAPC::Asia 2008 Larry's keynote and DeNA room sessions

先週行われたYAPC::Asia 2008の動画、 Larry の Keynote と、私が担当した DeNA room の二日分をニコニコ動画にて公開しました。

YAPC::Asia 2008 のスケジュールページからリンクされている、セッション詳細情報のページにも埋め込みされています。

A Standard That Is Meant To Be Broken, 本当に! - Larry Wall

※ この動画はi-revoの堂前さん・川合さんが撮影されたものを id:lopnor さんにテープから吸い出していただいたものを公開用にエンコードしました。ありがとうございました!

DeNA room (Day 1) 7セッション

※ cog の動画だけ、撮影機材のトラブルでうまくとれなかったので Xacti で撮った動画になっています。スライドが見づらくて申し訳ないです。

DeNA room (Day 2) 8セッション

講堂とArchTypeルームでのセッション動画は、動画撮影チームでとりまとめて編集・エンコードをしているところです。

ちょっとトラブルもあったので1〜2週間かかるかもしれませんが、でき次第随時公開出来ると思います。

2008-05-19 17:18 追記

公式サイトのニュースでも告知がでましたー

2008-05-17

open の実装

arg.c:282

まとめ

  • ファイルがすでに開かれてたらいったん閉じる
  • open 引数の記号列でfopen時の書き込み・追記などを制御する。記号列とファイル名の間にはスペースを入れてもいい。
    • | 書き換え
    • >> 追記
    • > 書き換え (但しファイル名が - の場合は標準出力)
    • < 読み込み (但しファイル名が - の場合は標準出力)
  • 引数の末尾が | で終わっている場合は popen
  • 記号列自体がない場合はファイル名が指定された読み込みと同じ扱い

2008-05-18 1:13 追記

おもいっきり誤読してた。

  • | 書き込みモードで popen
  • 末尾が | の場合は読み込み専用モードで popen

2008-05-11

リストと配列 その2 push/popとshift/unshift

昨日の続きで、リストと配列の実装を追います。今日はpush/popとshift/unshiftです。

まずは push/pop。配列の末尾に追加(push)、末尾から削除(pop)するものです。

store に処理を任せてますね。要素数を一個増やして末尾に追加。 次はpop。

array.c:103

要素数を一個減らして末尾を Nullstr で埋めて、それまで入ってた奴を戻すと。

さて次は配列の先頭を操作するshift/unshift。まずは先頭から一つ取り出す shift。

配列1つめから末尾までのデータを先頭にコピーして、 要素数を一つへらしつつ最後の要素に Nullstrを入れると。

次は先頭に追加するunshift。

array.c:116

ダミー要素を末尾に store を利用して追加した上で、 既存の要素ポインタを一個づつずらして言ってます。 引数が num であることからどうも aunshift 自体は要素を追加するわけではなくて、 先頭に追加する要素分だけスペースを空けるだけのようです。

というわけで aunshift が呼ばれている部分を見てみます。 呼び出し元はやはり arg.c の eval でした。

arg.c:2059

if AF_SPECIAL else のほうで aunshift で一つスペースを空けた上で、 ゼロ番目にastore しています。AF_SPECIALのほうでやってる do_unshift は配列を指定されたときかな?

do_unshift は同じく arg.c の中にありました。

arg.c:827

どうもそんな雰囲気です。最初に eval して配列を取得した上でその要素だけ指定された配列の先頭に aunshift、astore してます。

AF_SPECIAL というのが何かよくわかりません。arg の内容が問題です。

そろそろ eval の引数を詳しく見た方がいいかもしれません。また今度やります。

2008-05-10

リストと配列 その1

Perl学習の続き。今日は「はじめてのPerl」第3章、「リストと配列」の前半をやりました。

  • 3.1 配列の要素にアクセスする
  • 3.2 配列の特別なインデクス
  • 3.3 リストリテラル
    • 3.3.1 qw ショートカット
  • 3.4 リスト代入
    • 3.4.1 pop演算子とpush演算子
    • 3.4.2 shift演算子とunshift演算子
  • 3.5 配列を文字列の中に展開する
  • 3.6 foreach 制御構造
  • 3.7 Perl お気に入りのデフォルト: $_
    • 3.7.1 reverse演算子
    • 3.7.2 sort演算子

ひっかかったこと

  • push/pop と unshift/shift の違い
  • foreach で受ける変数は要素そのもので(参照?)、代入すると配列の要素自体が変更される
  • デフォルト変数 $_ はどこでいじられてるのか。内部表現

というわけで、とりあえず配列の内部表現を見てみようとまた Perl 1.0 のソースを見ます。

今回は簡単で、 array.h と array.c にまとまっているようです。

array.h (コメントは溝口)

atbl は perl.h で typedef struct atbl ARRAY; と定義されています。

では配列の作成をしてるらしい anew を見ます。

array.c:69

要素のバッファを多少余分にとって確保してることがわかります。ary_max を見ると4個分?1個は末尾マーカーかな?

safemalloc は util.c で定義されてて、引数チェックと、メモリが確保できなかったときの異常終了をしています。bzero は perl.h で #define bzero(s,l) memset(s,0,l); されてます。

配列からの取得は afetch

array.c:16

key が取得したい要素のインデックス番号。ここでみると数値を期待してますね。範囲外の要素は undef (Nullstr) を返すようです。

次、要素をいれるっぽい astore

array.c:26

オーソドックス。

配列の要素数以上のkeyにstoreされると、要素の枠を追加で確保して、要素数(ary_fill)、最大インデックス(ary_max)を更新した上で、上書きされる要素をstr_freeし、最後に上書きする。上書きがあった場合は1を返すようです。

要素枠の追加時は、既存の最大要素数の5分の1だけバッファを用意して、連続追加でもパフォーマンスが落ちないようにしてるみたいですね。

さて、ここまではわかりましたが、eval のなかからここまでどうやって呼ばれるんでしょう。あと配列の作成、解放のタイミングも気になります。

それらは奥が深そうなので、いったん気になるまま置いておいて、明日は pop / shift の違いと foreach, デフォルト変数周り、あとざっと reverse, sort も実装を見ようと思います。

2008-05-09

Perl の == と eq の実装の違い

Perl学習はじめました」でハマった以下の文字列比較に eq ではなく == を使ったコードがなぜ期待したとおりに動かなかったのか、調べてみました。

まず == は数値を期待していて、ここに文字列をわたすと Perl の文字列から数値への変換ルールで入力文字列が(だいたい) 0 になり、同様に 'quit' も数値変換されて 0 になるため 0 == 0 として必ず while を抜けるのは理解できました。

で、いい機会なので実装がどうなってるのかを見ようと思って Perl 5.8.8 のソースコードを見てみました。でも、O_SEQ というのが eq の opname だということ、 O_EQ というのが == の opname だということまではわかったのですが、そのバイトコードを処理する実装を見つけられませんでした。

そこで Perl 1.0 のソースコードなら単純だろうと当たりをつけて、このサイトから Perl 1.0 のソースコードをダウンロードして、いろいろ調べてみます。

でいろいろ追っかけると以下のような流れでバイトコードを実行してるみたいです。

  • main (perly.c)
  • cmd_execute (cmd.c)
  • eval (eval.c)

というわけで見つけた実装

まず文字列比較の eq

arg.c:1782 handy.h:20

というわけで単純に strcmp してました。

次、数値比較の ==

arg.c:1508

perl.h:56

str.c:83

ふむ。文字列を atof で double に変換しちゃうということで。なるほどねー

Perl 5.8 での実装が見つけられなかったのがちょっと悔しいけど、これからまた「はじめてのPerl」の続きをします。

ちなみに STR 型は str.h で定義されてました。でも最近のは utf-8 フラグとかいろいろ拡張されてるらしいので、あまり意味ないかもしれないなあ。

以前のログ