Bpstudy26

1,570 views
1,493 views

Published on

Published in: Technology, Design
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,570
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
6
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Bpstudy26

  1. 1. Caty Framework 〜Back to Oldies, Back to Basics〜 言い出しっぺ: 檜山正幸 巻き込まれた人:鍬田力
  2. 2. Catyを作り始めた経緯 檜山さんにお任せします。
  3. 3. ちょっくらWebサイトでも * 少しだけ動的 * デザインはプロに頼もう * どうやってデザイナに頼んだらいいんだ? * 周りの人に聞いてみた * … …
  4. 4. ええええーーっ * 当方、「小規模、少人数、少ない予算、短期間」なんですけど * 本格的なフレームワークや方法論はどれもオーバースペック * 全部ひとりでやるってのは確かにあるけど * 「N = 1」 と 「N = それなり」の道具と手段はあるんだな * でも、「N = 2」「N = 3」あたりで適切なんが見あたらない
  5. 5. んじゃ、作ろうか * 当初の目的に適合することが第一 * 他の要求は知らん * だったら、簡単そうじゃん * … … * … … * それでエライことになった人が一人いたりします
  6. 6. 厳密分離の原理 * これだ! * だけど、イマイチなところもあるなー * 分離の境界線を1本から3本にしてみました
  7. 7. 昨日あたりから、いきなり重要キーワード * ロール * スーパーバイザー
  8. 8. デザイナって言葉が曖昧すぎたわけだが * 小規模、少ない予算なら、プロジェクトチームっても、2人くらいでしょう * 狭義のデザイナ、狭義のプログラマのどちらかがスーパーバイザを兼任できそう * 僕(檜山)はやりたくないので、デザイナさん、そっちもお願い * 単機能のプログラム(コマンド)なら書いてもいいし、アルバイト君にも依頼可能
  9. 9. それはそうとして
  10. 10. Catyの問題点
  11. 11. 1. できてない * 動くっちゃ動く * 来週くらいにリリース2 * やることが色々増えちゃってねー * … … * … … * それでエライことになってる人が一人いたりします
  12. 12. 2. ロゴがない
  13. 13. これなんかどうか
  14. 14. これは?
  15. 15. これとか?
  16. 16. 募集中
  17. 17. 檜山さんの野望 厳密分離の実現のために * プログラマに頼らずサイト全体を構築可能 * 三つのロールモデル間の分業 o デザイナー o プログラマー o スーパーバイザー * 特にプログラマーとの間で分業 ※スーパーバイザーはサイト全体の構造・仕様についての責務を負う人とする
  18. 18. 昔は良かった * Webサイト=HTMLだけで構成 * CGIもあったけど、何にせよファイルはモロ見え * ファイラーでサイトの構造が見える ~/public_html/index.html ~/public_html/news/9901.html ~/cgi-bin/forum.cgi : : http://example.com/ http://example.com/news/... http://example.com/forum.cgi : :
  19. 19. 今は便利になったけど(1) * URLマッピングとフィルター・トリガーの嵐 * FWを知らないとサイトの構造が不明 * そして当然それらはFW依存 /app/conf.xml   /handlers/   /filters/   /otherbullshits/ ----------------------------------- <web>  <action path=&quot;/*.act&quot;   class=&quot;Dispatcher&quot;/> </web> http://example.com/ http://example.com/news.act http://example.com/forum.act : : ?
  20. 20. 今は便利になったけど(2) * いくら何でもパワフル過ぎるテンプレート * ちょっとした事を試すにもプログラマ頼み * そのくせデフォルトでXSSに脆弱だったり <html> <title><%= page.getTitle()%><title> <ul> <% for item in page.listItems() %> <li><%= item.someMethod() %></li> <% end %> </ul> </html>
  21. 21. でもそこまでする必要ある? * 近所のラーメン屋のサイト作るとき * 美容院のサイト作るとき * そこらの片手間企業サイトを作るとき オーバースペック
  22. 22. そのやり方でいいの? * HTMLだけ書いてもらいそこにテンプレートのプレースホルダー埋め込み * デザイナーの書いたテンプレートに後から ロジック埋め込み * その辺ゴチャゴチャで脆弱性上等の某ソフト まともに分業できてないでしょ
  23. 23. 基本を忘れてない? 1 ページのデザインに責任を負っているのは誰? 2 動的サイトに必要なプログラムを作るのは誰? 3 それらサイトの構成を把握するべきなのは誰?
  24. 24. 3つのロール * デザイナー * プログラマー * スーパーバイザー Caty の想定するロール
  25. 25. ロール間の分業 * 3つのロール間の責務を可能な限り分離 * 複数のロールを兼務することは当然ある o が、ある瞬間のロールは一つ o やってる事が混線しないような仕組み
  26. 26. そのために何が要る? * ロジックがテンプレートに入り込まない仕組み * プログラマに頼らずに o テンプレートを実行する仕組み o データをマッシュアップする仕組み o サイトの構成を把握できる仕組み * 安全性・整合性を保証する仕組み
  27. 27. でも一番大事なのは 学習の容易さ
  28. 28. 古き良き日々よ再び * URLが存在する=ファイルが存在する * ベタHTMLのサイトが普通に作れる * そこに動的ページを混ぜ込める * ベターなHTML+CGIのモデル
  29. 29. ということを考えていたら * 予想の斜め上のフレームワークが * 作ってる方は死にかけてる * とりあえずはテンプレートから説明します
  30. 30. テンプレートのダメな例 * あるショップのディスカウントセール * お店のサイトで一律値引き表示をさせたい * テンプレートで計算させちゃった♪ <ul> <% for item in page.itemList() %> <li><%= item.name() %>: <%= item.price() * 0.7 %>円 </li> <% end %> </ul>
  31. 31. なぜダメか * 誰がそのロジックを書くのか * 仮にデザイナーだとすると o ロジックを書くのは本業じゃない * 仮にプログラマーだとすると o テンプレートをいじるのは本業じゃない * スーパーバイザー? 指示出す側だろ * 分業にならない * そもそも保守不能なカオス
  32. 32. ってかどうしてこうなった * そりゃあ、出来るからに決まってるだろ * 最初からできなければ良い 低機能なテンプレートエンジンが理想
  33. 33. Catyのテンプレートの機能 <html> <title>{$title|toupper}</title> {if message.exists} <p>{$message.body}</p> {/if} <ul> {foreach from=$list item=i} <li>{$i}</li> {/foreach} </ul> {include file=&quot;footer.html&quot;} </html>
  34. 34. こんだけあれば十分じゃん * 変数参照 * ループ * 真偽値判定 * 他のテンプレートのインクルード * フィルター/モディファイアの適用
  35. 35. こんなのは要らない * ホスト言語の呼び出し * 算術演算 * マクロ定義 あると厳密分離にならなくなるものばかり
  36. 36. 実は言い出しっぺは別にいる * Terrence Parrの論文 - Enforcing strict model-view separation in template engines o http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf * 良いテンプレート=低機能なテンプレート * この厳密分離の方針で実績がある
  37. 37. 厳密分離の次にすべき事 * テンプレートだけでは動作しない * 値を入れて確認できるようにしたい * わざわざプログラマに頼む必要なしにしたい * ロジックは書けなくていい * データを流し込む仕組みは必要
  38. 38. よし、それじゃあJSONだ <?caty-script { &quot;title&quot;: &quot;index page&quot;, &quot;message&quot;: { &quot;exists&quot;: true, &quot;body&quot;: &quot;...&quot; } } ?> <html> <title>{$title}</title> :
  39. 39. 動的データを埋め込みたい * 固定値だけ入れられてもそこまで嬉しくはない * やはり動的なデータの取得が必要 * できればデータをマッシュアップしたい 限られた機能のスクリプトを作ろう
  40. 40. Catyスクリプト <?caty-script { &quot;title&quot;: &quot;index page&quot;, &quot;message&quot;: load-message, &quot;list&quot;: fetch-db | filter } ?> <html> <title>{$title}</title> :
  41. 41. 一体これは何? * ベターJSONとしてのスクリプト * JSONのスカラーの書けるところにコマンドが書ける * コマンド呼び出しはUnixのそれ * コマンドの実態はホスト言語で書かれてる * ロジックはコマンドに書いてください * Catyスクリプトはコマンドを呼び出すのみ
  42. 42. Catyスクリプトにないもの * 関数定義 * ループ * 算術演算など各種演算 * etc * あるとホスト言語との境界が曖昧に * つまり厳密分離にならなくなる
  43. 43. デザイナーの立場からは * HTMLだけでページが作れる * ベターHTMLとしてのテンプレート o 共通フッタのインクルードだけ書くとか * テンプレートの表示確認用にJSONを書く * ベターJSONとしてのCatyスクリプト 段階的な学習
  44. 44. ちょっと視点を変えてみる * スクリプトはテンプレートにしか書けないの? * サイトの構成はどうなってるの? これらはスーパーバイザーの立場
  45. 45. テンプレートに値を渡す方法 * 一つはさっきのやり方(インラインスクリプト) * 別のスクリプト:アウトオブラインスクリプト * CGI * サイトの設定ファイル
  46. 46. アウトオブラインスクリプト /index.html /index.html.caty /news.html /news.html.caty : : * ファイル毎に一つのスクリプトを関連付けられる * 拡張子込みのファイル名+.caty * 中身はCatyスクリプト
  47. 47. どんな時に使うの? * ページの構成要素は決まってる * デザインはデザイナーに任せる * アウトオブラインスクリプトを書く * 対応する空のHTMLファイルを渡す * コマンドが必要ならプログラマに発注
  48. 48. 例えばこんなのはどう? * サイトのトップページを作る o 新着記事一覧 o 雑多なお知らせ 必要な要素はわかってるのでスクリプトに書ける
  49. 49. 書いてみるとこんな感じ { &quot;news&quot;: fetch-news --sort-by-date, &quot;message&quot;: load-message } * 残りの作業はプログラマーとデザイナーがやる * fetch-newsなどをプログラマーが実装 * HTMLテンプレートをデザイナーが作成
  50. 50. CGI * CatyのCGI=Catyスクリプト * つまりロジックは書けません * サイトの表面からはロジックを分離
  51. 51. CGIの例 * リリース2に含まれるWikiのCGI * どれもこれもワンライナー index.cgi: wikititles / | print index.html edit.cgi: editwiki / | print edit.html post.cgi: postwiki /
  52. 52. サイトの設定ファイル * 拡張子毎のデフォルトコマンドを設定できる * が、デフォルト設定でサイトが十分構築できる * よく使いそうなパターンはデモに収録 * URLマッピングの類はない &quot;filetypes&quot;: { &quot;.wiki&quot;: { &quot;is_text&quot;: true, &quot;assoc&quot;: &quot;viewwiki %1 | print page.html&quot; } }
  53. 53. サイトの構成は単純 * URLがある=公開ディレクトリにファイルがある o インクルード専用ディレクトリなどはある * 公開ディレクトリやテンプレート置き場を指定 * 覚えることはあまりないです /mysite _manifest.json <- 設定ファイル /pub <-公開ディレクトリ /index.html /forum.cgi /templates <- インクルードやprint経由でのみアクセス /res  <- コマンドの使うデータ置き場
  54. 54. 一旦まとめ * 古典的なWebサイトの延長 * 個々の要素は限られた機能を持つ * 単純化による学習容易性 * 機能が限られていれば自然と分業できる
  55. 55. Catyの真の姿 * Catyのコア=言語処理系 * 厳密分離の核心がCatyスクリプトにある * その処理系こそがCatyの本質 WebフレームワークとしてのCaty = CatyスクリプトのWebフロントエンド
  56. 56. Catyはこんな構成 Catyスクリプト処理系 シェルフロントエンド Webフロントエンド キーボード入力 HTTPアクセス
  57. 57. コンソールとWebが対等 caty> print --resolve /index.html = GET /index.html HTTP/1.1 caty> {&quot;path&quot;:&quot;Example&quot;}|/edit.cgi = GET /edit.cgi?path=Example caty> {&quot;path&quot;:&quot;Example&quot;, &quot;content&quot;: &quot;hogehoge&quot;} | /post.cgi = POST /post.cgi HTTP/1.1 path=Example&content=hogehoge
  58. 58. Catyスクリプトの仕様書 pipeline -> term ('|' term)* term -> scalar | command | object | list | functor | tag | when | '(' term ')' scalar -> string | integer | number | boolean list -> '[' pipeline (',' pipeline)* ']' object -> '{' item (',' item)* '}' item -> string ':' pipeline command -> symbol option* (symbol|scalar)* symbol -> ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')* tag -> '@' string | symbol option -> &quot;--&quot; symbol symbol | scalar functor -> symbol '{' pipeline '}' when -> &quot;when&quot; '{' case (',' case)* '}' case -> symbol | string &quot;=>&quot; | &quot;==>&quot; pipleline
  59. 59. 改めてCatyスクリプトを説明(1) * あくまでもテンプレートとホスト言語の仲立ち * Unixのパイプの発想 * ネイティブデータはストリームではなくJSON * スーパーバイザーとデザイナーが対象に入る * プログラマが書いても悪くはないよ?
  60. 60. 改めてCatyスクリプトを説明(2) * JSON構文はそのまま使える &quot;string&quot; [1, 2, 3] {&quot;name&quot;:&quot;鍬田力&quot;, &quot;job&quot;:&quot;自称料理研究家&quot;} * JSON構文にコマンドを入れ込める print /index.html [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;] | concat { &quot;blogTitles&quot;: blog:recentBlogEntries , &quot;wikiTitles&quot;: wiki:recentUpdatedWiki }
  61. 61. 改めてCatyスクリプトを説明(3) * タグディスパッチによる分岐 loggedin --as kuwata | when { OK => print -e /secret.html, NG => &quot;/login.html&quot; | redirect } * Catyでは任意のデータにタグが付けられる @person { &quot;name&quot;:&quot;檜山正幸&quot;, &quot;job&quot;:&quot;キマイラ飼育記の中の人&quot; } * object型にpersonというメタ情報が付く * メタ情報が付いた型は元の型とは違う
  62. 62. 改めてCatyスクリプトを説明(4) * 繰り返しの代わりのeach(map関数) [&quot;foo&quot;, &quot;bar&quot;, &quot;buz&quot;] | each {toupper} 通常使うCatyスクリプトの要素はこれで全部
  63. 63. 余談:普通は使わないコマンド * テストの実行時のみ有効なコマンド: eval [&quot;print /index.html&quot;, {...}] | eval = {...} | print /index.html * 通常のコンソールやWebでは使えません * その理由は……
  64. 64. こんな事が書けてしまう test:list-testfiles / | each { { &quot;testcase&quot;: pass, &quot;testresult&quot;: ( [&quot;readFile --readfrom testfiles &quot;, pass] | concat | [pass, &quot; &quot;] | eval | [pass, &quot;&quot;] | eval | each { { &quot;command&quot;: getpv command, &quot;results&quot;: [{&quot;command&quot;: getpv command, &quot;data&quot;: getpv data}, findpv setup, findpv teardown] | [ nth 1 | when {EXISTS => [pass, &quot; &quot;] | eval, NO => pass}, nth 0 | [getpv command, getpv data | unzip | nth 0, getpv data | unzip | nth 1] | [[nth 0, nth 1 | length] | repeat, nth 1, nth 2] | [[nth 0, nth 1] | zip | each {eval}, nth 2] | zip | each { eq | when { &quot;Same&quot; => &quot;[OK]&quot;, &quot;Diff&quot; => [&quot;[NG] &quot;, toString] | concat, } } | enumerate, nth 2] | [nth 2 | when {EXISTS => [pass, &quot; &quot;] | eval, NO => pass}, nth 1] | nth 1 } } ) } | expand testresult.txt } | concat | chop
  65. 65. さらなる悪夢 &quot;[pass, pass] | eval&quot; | [pass, pass] | eval * 無限に再帰します * ってか Y コンビネータです * 即ちチューリング完全
  66. 66. チューリング完全性との戦い * あくまでもCatyスクリプトは低機能が第一義 * あまりパワフルだと弊害が多い o 静的検証への悪影響 o 安全性への悪影響 o そもそも使うのも学のも難しくなる * ただし、evalが必要なケースがある o テスティングフレームワーク
  67. 67. Catyスクリプトの型 * パイプは確かに気軽に使える * でも繋げるコマンドを間違えることもある * 可能な限り実行前に検出したい JSONスキーマによる型付け
  68. 68. JSONスキーマの基本型 * スカラー型 string, binary, integer, number, boolean, null * 配列・リスト・タプル型 array [integer, string*], list[string], tuple [string, integer] * オブジェクト型 object {&quot;name&quot;: string, &quot;job&quot;: string, &quot;age&quot;: integer} * 特殊型 any, never, void * 型変数 _S, _T, _U...
  69. 69. JSONスキーマの型構築子 * |:ユニオン型 o string | null で「stringあるいはnull」 * &:インターセクション型 o A & B で「A, B両方の要素を持つ」 o object にしか使えません * ?:オプショナル型 o object {&quot;name&quot;:string, &quot;email&quot;:string?} o &quot;email&quot;プロパティがないかも * @tag:タグ o @person {&quot;name&quot;:string, &quot;age&quot;:integer}
  70. 70. JSONスキーマの例 type httpResponse = object { &quot;header&quot;: { *: string }, &quot;body&quot;: string | binary, &quot;status&quot;: string, };
  71. 71. スキーマによる型付け * あらゆるコマンドは入出力の型を持つ * コマンド同士の結合時には型チェックがされる o 今はちょっと適当 o そのうちきちんと実装します * 型チェックの基準 o A | B の結合が成立する条件 o Aの出力型がBの入力型に包含されている * 型変数を導入したので多相コマンドが書ける * 型変数は型推論されて型チェックされる
  72. 72. 今日は説明しませんでしたが * コマンドの型を指定するための機構もあります * そちらはDIの宣言にもなってます * 宣言しないとファイル・DB・セッションなどへのアクセスがほぼ不可能です * 宣言時に読み込み・書き込みの指定もします * つまり、型宣言をみれば副作用の有無がわかります
  73. 73. まとめ * フロント部分は素朴な構造 o 学習容易性が大事 o 限られた機能で自然な分業 * バックはガチガチに定式化 o 宣言的な仕様の記述 o 強い型システム
  74. 74. ご清聴有難うございました

×