開発日誌の最近のブログ記事

アセトアルデヒドの勢いで変な物を書いたような気がします。書きかけですけれども。

Games::DateTime - A simple date and time object on any games

screenshot_of_p5-games-datetime.png

たまには脇道に逸れて、ff14.nameおよびff14.asia向けの部品的なモジュールを書くというのも、気分転換に良いかも知れません。何に対しての気分転換かというと、独り身の帰宅路で涙にむせぶ件といったところでしょうか。

上掲のスクリーンショットのような「時計」であればFlashやJavaScriptでもよく見掛けるのですが、「ローカルタイムな地球現在時→仮想世界の現在時」以外に

  • 仮想世界の日時→地球の日時方向への変換
  • ローカルタイム以外のタイムゾーンへの対応
  • 地球日時もしくは仮想世界の日時の指定
  • 時間計算(地球および仮想世界の両方)

などが出来る「日付時刻クラス」というのは寡聞にして知らないので、書きました。取り敢えずググって要件を見つけられたのはFF11だけでしたが、起点日時の対称が見付かれば、プレースホルダー的に置くだけ置いたEverQuestなどの実装にも対応出来るかも知れません。

ちなみにスクリーンショットの時計はライブラリー本体ではなくexamplesディレクトリー以下のおまけであるGames::DateTime::Clockです。ff14.nameやff14.asiaでは、最終的にはこれとGames::DateTimeをJavaScriptに移植することになります。

なお、Acme::*以下の名前空間にするかどうかは考え中です。また、テストは酔いが覚めてから書く予定です。などと書いていると肝臓が明日も泣きそうな気がします。

備忘録ですが、MooseX::AbstractFactoryで、ファクトリーメソッドに指定する具象クラス名(の一部)を指定する際にエイリアスを使えるようにしています。ただしHashRefを渡さずにエイリアスクラス名(の一部)を渡す際には、宝箱を開ける為の鍵が当該宝箱の中にあるような状態で、いまいちです。

Mooseの型制約を遅延設定するMooseX::Types::Games::DateTime辺りの小細工(実装クラスに依存してwhereブロック内の振る舞いを規定する、など)については、稿を改めようと思います。

  • 1日24時間という世界の具象クラスではhour0 <= $_ && $_ < 24の範囲になり、
  • 1日30時間という世界の具象クラスではhour0 <= $_ && $_ < 30の範囲になる

という要件があったときに、事前に(静的に)それぞれ別の型制約を作らずに、最大値を具象クラスから引っこ抜いて型制約で使うということです。これもまたいまいちな実装ですけれども。

追記: テストを薄く書いてバグを除いたほか、見本の時計はロケールにも対応させました。また、cp932でなくUnicodeなコンソールでの字詰めの問題等々を解消しています。上記スクリーンショットも差し替えています。全角半角の「文字幅」の取り扱い方については、(時間があれば)稿を改めて備忘録を起こす予定です。

Mooseクラスでのクラス定数は、MooseX::ClassAttributeで定義する方法もありますが、素直なのはクラスメソッドとして実装してしまうことでしょう。これならば、ロールとの相性も良いです。

しかし、クラス定数(のように使うクラスメソッドの戻り値)が単純な値であればともかく、何かの値を元に計算して導出するような代物だった場合、クラス定数(のように......以下略)を使う度に計算されたのではたまりません。

こうした場合には、Memoizeによるメモ化(memoization)が定番の処方箋となります。また、(もはやメモ化の文脈での例としては定番である)フィボナッチ数の計算など、クラス定数として使うものでないメソッドについても、同様にメモ化は強力な最適化方法論です。

Mooseクラスでは単純にMemoizeモジュールを使えば良いのですが、Mooseロールでは少々込み入った手順で使う必要があることが分かったので、備忘録的に書いておきます。

Mooseクラスの生成時に、コンストラクター引数として与えられたハッシュまたはハッシュリファレンスに着目して処理を行いたい場合があります。

例えば、初期化ハッシュキーを跨いだ検証などが挙げられます。triggerの使い方についての記事で説明用に作った、元号と西暦のアトリビュートを持つ昭和クラスで想定してみます。

元号と西暦の両方を指定された場合、その両方のアトリビュートが未指定になります。undefという値が入っているのではなく、has_imperial_eraなどのpredicateメソッドの戻り値が偽であるという意味です。

それでは困るので、コンストラクター引数に指定するのは元号と西暦のどちらか一方のみに制限する......という要件が出て来たこととします。その場合、ハッシュとハッシュリファレンスの両方でキーを見付ける処理をBUILDARGSに書くのではなく、親クラス(最終的な親はMoose::Object)のBUILDARGSを呼ぶようにすると、素直に書けます。

# ...

around BUILDARGS => sub {
    my $next  = shift;
    my $class = shift;
    # ここでは@_はハッシュかも知れないしハッシュリファレンスかも知れない

    # 親クラス(Moose::Object)のハッシュリファレンス化はBUILDARGSに任せる
    my $init_args = $class->$next(@_);  # ここではハッシュリファレンス

    confess 'Initialization argument must be '
          . 'any one of imperial_era or christian_era'
            if exists $init_args->{imperial_era} 
            && exists $init_args->{christian_era};

    return $init_args;
};

# ...

こんなものは常識なのでしょうけれども、意外とこういう初歩的なところの認識が甘くて、今までは(後述するように)ハッシュリファレンスのみを食べるような偏屈APIを撒き散らしていました。反省反省。

以下は補足情報です。

MVCのModelをWAFから切り離しつつ、Modelも(DBとの仲立ちをさせる)ORM用スキーマと(ビジネスロジックを書く)ドメインモデルとで分けたいと思い、ここ数日調査や試行をしています。私はPoEAAを読んで、かっとなって「どうせ趣味で書くならドメインモデルしかない!」と思い込んでいます。これがまず出発点です。今回の記事は、そのモデルの守備範囲をどうしようか、というお話です。

まず、CatalystなどのWAFからMVCのMを切り離すことについては、牧さん(lestrratさん)の『モダンPerl入門』(pp.116-121)などで明快に解説されています。

次に、サービスクラスとモデルクラスの使い分けについても、dannさんのCatalystCon #1でのCatalystからModelを切り離せ - MVCのMのあるべき姿 -の発表でも言及があります。

それでは、ドメインモデルはDAO/DTOやORMの方面まで面倒を見るべきなのでしょうか。

今回細々と開発しているFF14ユーザー向けウェブサービスであるAmikecoでは、ORMとしてDBIx::Classの使用を想定しています。また、サービスクラスやモデルクラスは、Mooseクラスを想定しています。

というような状態での具体的な実装方法について、調べてみたところいくつかの類型があるので、試行してみての感想を添えて備忘録として書いておきます。

  1. MooseクラスでDBIx::Classを継承して、ドメインモデルにスキーマを兼務させる
  2. DBICx::Modelerを使って、スキーマクラスとモデルのMooseクラスを分離する
  3. MooseX::DBICを使う
  4. 永続化非対象の情報をどう持つか
  5. 番外編: Moosified ORMを使う
  6. まとめ

ここのところPerl勉強日誌的な記事が続いていますが、ff14.nameff14.asiaの開発は細々と続いています。それはもう申し訳ないほどに細々としていますが......(一方で、「やや真面目なサイト」としてサイドバーに晒してあるエスペラント日本語翻訳システムは、かなり遅滞気味です)。

これらサービスのそもそもの開発動機の一つが自分自身の勉強ということもあって、色々と新進気鋭のモジュールを試しながら使わせていただこうとして出発点を置きましたが、少なからぬ依存モジュールの数々を、新進気鋭のモジュールではなく、定番系のモジュールに切り替えようとしています。これは、定番系の重厚長大モジュールでさえ深く使い込んでないのに、新進気鋭の軽薄短小なモジュールを巧く使いこなせずに開発が遅滞するということが、早すぎる最適化の一類型に当てはまるのではないか、という危惧に由来するものです。最終決定はまだ先ですが、10月20日版の主要依存(予定)モジュールなどでは、その辺りの弱気が透けて見えるかも知れません(「or」の前後をかなり入れ替えています)。

具体的には、例えば

  • やっぱりまだまだRDB的な考えからKVS的な考えに切り替えが出来ない私は、Data::Modelではなく、まずはDBIx::Classで一通りを組んでみようと考えを改めました
  • 出来るだけAny::Moose経由でMouseを使うようにしていたのですが、まずはMooseの豊富な拡張モジュール(MooseX::*)にお世話になってプロトタイピングにいそしもうとしました

などという点です。

この方針の転換は、すべて私の能力の至らなさによるものです。8月中旬頃まで色々試行錯誤をしていたのですが、色々な使いどころの妙を得ずに開発をしていて、プロトタイピング自体で蹴躓くことが多かったという体験があります。ということで、最初から完成形のアプリケーションを作れるわけでは当然ないにせよ、まずは形を作ってからそれから新進気鋭のモジュールの使用を試みようというような、私の身の丈にあった開発をしようと思います。モジュールそれ自体が冒険的ということでは全くなくて、モジュールを自分が十全に使いこなせないという冒険的な開発を改め、多少なりとも安定的にプロトタイプを作れることを優先するということで。

などと書いた舌の根も乾かぬうちにというか打鍵音も静まらぬうちに......。

Moose入門研修(Introduction to Moose)のスライドを日本語訳してみました。

演習問題(未訳)を含む日本語版の一式はGitHubのリポジトリに置いています。興味のある方は、git clone git://github.com/gardejo/moose-presentations.gitするなどして入手してみてください。

石垣さん(charsbarさん)のとてもわかりやすいMooseドキュメント日本語訳には及びもつかない翻訳ですが、用語の訳語を適宜剽窃しつつ、今回は取り敢えず粗訳・試訳からの出発ということで一発japaneseブランチを切ってみました。

原書はDavid Rolskyさん(DROLSKY)さんによる力作です。git clone git://git.moose.perl.org/moose-presentations.gitで入手出来ます。CC-BY-SA 3.0でライセンスされていますので、日本語版という派生物を今回公開させていただきました。日本語版のライセンスも、原書を継承してCC-BY-SA 3.0です。

補足事項や所感などを以下に簡単に述べます。

YAPC::Asia 2009で、宮川さん(miyagawaさん)と松野さん(tokuhiromさん)の夢の共演「PSGI - Perl Server Gateway Interface」を拝聴しました。

詳しいレポートは技評の記事などを参照していただくとして(下記参照)、

WAF開発者でない、つまりWAFユーザー(Webアプリケーション開発者)である私の感想を記しておきます。この記事の題名は意味不明で恐縮ですが、それぞれの熟語を以下の文中で使っていることに由来するものです。

なお、GitHubでスライドも公開されました

追記 : id:antipopさんによるPSGI/Plack勉強会という記事が公開されました。実装周りが綺麗にまとめられた素晴らしい記事です。是非ご覧ください。

追記 : PSGI/Plackサイトが立ち上がりました。

  1. PSGI/Plackとは
  2. 仕組みの詳細
  3. HTTP::Engineと何が違うのか
  4. HTTP::Engineは停止、ただし後方互換性は維持
  5. PSGI/Plackの今後
  6. エンドユーザーへの恩恵
  7. 全体を通して

YAPC::Asia 2009で、村瀬さん(typesterさん)のトーク「ark - framework inspired by Catalyst」を拝聴しました。スライドはstfuawsc.comにあります

目下のところ"Amikeco"ではArkのお世話になって実際に実装していますし、このサイトでも(最近少々更新を滞らせていますが)サンプルアプリケーションの作成を通じて紹介していたりします。

Arkはとても合理的なWAFなので、是非一度お使いになることをお勧めしたいです。Catalyst的に使えますし、前のhide-kさんもトークで槍玉に挙げたようなCatalystの微妙な一部記述もしなくて済みます。CatalystはPerlのWAFの定番で大変良くできたものですが、このトークでArkユーザーの方も増えてくれれば嬉しいですね。

そんなこんなで熱く注目している私ですが、さりとて毎回の変更を事細かく拝見出来ているわけでないので、恥ずかしながら、軽い浦島太郎状態に陥ってしまいました。一番驚いたのは先月末から今月頭にかけて、KAYAC社の実アプリのリソース一式がGitHubで公開されていたことです。

ということで、いくつか感想を挙げてみます。

  1. PSGI/Plackでも安心
  2. Ark::Modelsの使い方を悔い改めます
  3. HTML::ShakanからArk::Formに切り替えるかも
  4. Ark::View::JSONは既にありました
  5. 全体を通して

FF14のプレイヤー向けウェブシステム"Amikeco"について、前回機能概観を記したついでに、ER図もどきを晒しておきます。

ER図を作成する前に、軽くExcelでお絵描きしてみました......という位置付けですが、そもそもこのファイルが出来た原因は、画面遷移図もどき(1)および画面遷移図もどき(2)におまけとして載せていたスキーマもどきが肥大化してカオスな状態になったことを憂えたためです。しかしリレーションの線を引っ張ってみたらゴルディオスの結び目になってしまったという笑えない結末が待っていたというのは、前回記したとおりです。

以下にそのファイルを添付してますが、正直なところ、Excel方眼ドキュメントの粋ともいえるオートシェイプ地獄の後進性を、改めて強く認識させられる代物となっています。

ER図「もどき」を書くことで次第に像を結び始めたFF14のプレイヤー向けウェブシステム"Amikeco"の説明文を増補しました。「何ができます」というハイライトの紹介だけではなく、実際のサブシステムの一覧と、その簡単な説明を加えています。

個人情報管理システム辺りはData::ModelArkなどとの連携のイメージ作りとしてプロトタイピングという位置付けで実装とテストを行っていますが、この辺でシステム全体の概観に言及しておくのも悪くない頃合いだと思いましたので。

以下に説明文の増補部分の抜粋を記しておきます。

筆者"Gardejo"について

  • Twitter: @gardejo
  • GitHub: gardejo
  • CodeRepos: gardejo
  • CPAN: MORIYA

このサイトについて

Eorzea System Worksは、架空のシステム開発結社です。

FF14.name (FinalFantasyXIV.name)では、アヴァター(プレイヤーキャラクター)の管理システムやイベント出欠・リマインダシステムや、リンクシェル(LS)運営・管理システムやDKPシステムなどを設計・開発・公開する予定です。

関連サイト

関連サイトでは、他にもFF14に関連するサイトをいくつか紹介しています。

リンク, トラックバック歓迎

このブログへのリンク(どのページでも構いません)やトラックバックを歓迎します。

設計・開発・運用の参考にさせていただきますので、コメントもお気軽にお寄せください!

個別の記事に対するご意見などのほか、目安箱もご用意しています。

このアーカイブについて

このページには、過去に書かれたブログ記事のうち開発日誌カテゴリに属しているものが含まれています。

前のカテゴリは未解決です。

次のカテゴリは雑記です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

最近のコメント

2014年2月

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28  

やや真面目なサイト