記事

Last Modified:

Release Slack-v0.5.0 #Perl #Slack

この文書は以前のバージョンv0.4.0とv0.5.0の変更点を記述しています。

このリリースには以前のバージョンと互換性の無い変更が含まれています。

インターフェースの追加

ビューを定義するための新しいキーワードviewが追加されました

これはSlackにとって非常に大きな一歩です。 Slackはついにビューを外部に委譲する機能を獲得しました。

Slackは必要十分かつ非常に小さくなるように注意深く進められています。 このインターフェースの追加は、ビューの実装をSlackから切り離すための重要な痛みです。 今後ユーザーは好みのテンプレートエンジンを使って自由にビューを構築できます。

具体例はt/view.tを参照してください。

以前のバージョンではSlackはTemplate-Toolkitに依存していましたが、もはやそれはなくなりました。

拡張子にマッチする特別なパターンが追加されました

拡張子にマッチする特別なパターンとして{ extension => ... }が追加されました。

あえて特別なと紹介したのには理由があります。 単に拡張子にマッチするアクションであれば、これまでの正規表現での指定

view view => qr/.*[.]html/ => sub { };
で良さそうですが、そうではないからです。

{ extension => 'html' }で指定された場合は、actionの探索時にその拡張子が取り除かれます

つまり/foo.htmlというリクエストに対して

action foo => sub { };
view view => { extension => 'html' } => sub { };
であればaction,viewともにマッチしますが、
action foo => sub { };
view view => qr/.*[.]html/ => sub { };
であればviewにはマッチしますがactionにはマッチしません。 何故ならactionqr{\A/foo\z}にマッチするのであってqr{\A/foo[.]html\z}にマッチするわけではないからです。 もちろんaction foo => 'foo.html'=> sub { };であればマッチします。

なおこの{ extension => ... }構文は新たに追加されたviewのために用意された構文ですが、パターンにハッシュリファレンス{}を指定できるようになったことは、将来的な拡張性を示唆していると考えられるでしょう。恐らくそれは正しい考えです。 今後のSlackにおいて非常に重要な進化であることは間違いありません。

Slack::Contextが追加されました

v0.4.0で削除されたコンテキストオブジェクトがSlack::Contextとして再び追加されました。

コンテキストオブジェクトは以下のアクセサを持っています。

app
アプリケーションオブジェクト
req
リクエストオブジェクト
res
レスポンスオブジェクト
action
マッチしたアクションオブジェクト
view
マッチしたビューオブジェクト

Slack::Matcherが追加されました

actionviewの探索に用いられるオブジェクトとしてSlack::Matcherが追加されました。

探索においてマッチしたとき、Slack::Matcherオブジェクトはc->actionまたはc->viewに格納され、コンテキストオブジェクトを通じて参照できます。

Slack::Matcherオブジェクトは以下のアクセサを持っています。

controller
コントローラーオブジェクト
name
アクション名
pattern
パターン
code
コード節
extension
拡張子
priority
優先度

アクションコードが見つからなかった場合にHTTP_METHOD_NOT_ALLOWEDが返るようになりました #5

アクションは見つかったもののRequestMethodに対応するアクションコードが見つからなかった場合、HTTP_METHOD_NOT_ALLOWEDが返るようになりました。 Allowヘッダも自動生成されます。

HEADに自動的に対応する機能が追加されました #4

ユーザーはもはやHEADに対応するコードを記述する必要は無く、また記述するべきではありません。

HEADリクエストを受けた場合、GETの場合と同様の処理が行われた後、ResponseBodyが空に設定されます。

res->query_parameters,res->body_parametersが復元されました

ユーザーはもし使いたければres->query_parameters,res->body_parametersを使うことができます。

例えばPOSTにおいてQueryStringを参照したい場合などです。 Slackはもはやそれを引き止めることはしません。

インターフェースの変更

複数マッチした場合に選択されるアクションの優先順位が変更されました

実行するアクションは1つだけであるため、複数のアクションがマッチした場合はどれかを選択しなければなりません。 そのための優先順位が変更されました。

優先順位は、まずアクションが属するコントローラーのprefix階層の深さによって決定されます。

sub prefix { '/' }
action 1 => qr/.*/ => sub { };

sub prefix { '/foo/' }
action 2 => qr/.*/ => sub { };
この定義に対する/foo/barリクエストの場合、'/' + 'foo/bar'より'/foo/' + 'bar'の方が優先度が高いため2の方にマッチします。

深さが同じ場合は、パターンの指定方法によって決定されます。優先度が高い順に示します。

  1. 文字列
  2. ハッシュリファレンス
  3. 正規表現

これはCatalystを参考にしました。Catalystにおいて:Regexの優先順位は低くなっています。

パターンの指定方法も同じ場合は、先に書かれたアクションが優先されます。

以前のバージョンではマッチに成功した部分文字列の長さで決定していました。 これは概ね期待通りに動きましたが、パターンの記述方法によっては混乱を招いていました。

パッケージ名から得られるprefixの単語区切りが-に変更されました

パッケージMyApp::PascalCaseのprefixは/pascal-case/になりました。

以前のバージョンでは/pascal_case/でした。この変更には2つの理由があります。

  1. 一般的に単語の区切りは_ではなく-です。
  2. /pascal_case/を得るためのMyApp::Pascal_Caseは記述できますが、/pascal-case/を得るためのMyApp::Pascal-Caseは記述できません。

今後は、/pascal_case/を得たいならばMyApp::Pascal_Caseを、/pascal-case/を得たいならばMyApp::PascalCaseを使ってください。

正規表現パターンに\zが追加されるように変更されました

パターンは全て\A\zによって囲まれるようになりました。

以前のバージョンでは、パターンが文字列の場合は\A...\zだったのに対し、パターンが正規表現の場合は\A...であり、一貫性がありませんでした。

インターフェースの削除

app->configからenvironmentが取り除かれました

app->configからenvironmentが取り除かれました。

実装の変更

PATH_INFOがデコードされるようになりました

パターンとPATH_INFOを容易にマッチングさせるため、PATH_INFOがデコードされるようになりました。

しかしながらこの仕様は不安定であり、将来的に変更される可能性があります。

UTF-8で符号化されているという前提(=バグ)が既にあります。
どこで誰がデコードするかは今後の課題となっています。#20

ソースフィルタの性能が向上しました #2

要求するperlのバージョンがv5.14.0になりました

use re qw(/flags)re-0.14を要求し、re-0.14perl-v5.14.0を要求するためです。

example/t/に移動し、スペックコードとして再構築されました #3

仕様とテストを一体化するため、example/にあった例はスペックコードとしてt/に移動されました。

Smart::Commentsの出力にアクションテーブルが追加されました

Text::Table::Tinyが導入されている場合、アプリケーション起動時にアクションテーブルが表示されるようになりました。 これはCatalystを参考にしました。

各コンポーネントでSmart::Commentsが有効になりました

use Slack qw(...)によって拡張されたコンポーネントにおいて、自動的にSmart::Commentsが有効になるようになりました。

以前のバージョンではwarnings::importを乗っ取って、use warningsしている全モジュールを対象にしていましたが、 Smart::Comments用ではない###が含まれたファイルで問題を起こすことが分かりました。

いくつかの問題が修正されました

内部的な変更