[Seasar-user:1270] Re: Mayaの式言語サポート(Re: Mayaドキュメント初稿第2版)

Masataka Kurihara kurihara
2004年 12月 1日 (水) 21:23:37 JST


栗原です。

> 私の認識では、式言語の開始から終了までを切り出して式言語エンジンにまる
> なげ、です。つまり、MayaテンプレートのパーサはMayaテンプレートをパース
> していって「${」という文字列を見つけると、そこから(ネストを考慮しつつ)
> 式言語記述の終了部までを読み取って切り出し、式言語エンジンに渡します。
> この例の場合は「${(this#)${type}.name}」を渡します。後の解釈は式言語エ
> ンジンが行なうイメージです。(式言語の書式を知っているべきなのはMayaパー
> サではなく式言語エンジンなので、そうするのが美しいかな、と。)

  ということは

> はい、この方式でも私の用途には十分です。重要なのは、「{」「}」の入れ子
> をきちんと認識する、という点ですので、そこだけMaya側でサポートしていた
> だければ大丈夫そうです。

  ですよね?了解しました。あと、横田さんの式言語エンジンをうまく使う方法
で、ネストをサポートしていない式言語エンジンでも対応できますね。たとえば
OGNLはネスト構造をサポートしていませんが、最内側の評価をした後、変数
追加をしながら外側に向かって評価していけばいいので、不可能ではないと
思います。

${ out.println(${type}.name) }

というのがあったとして、

1)typeを評価。値を取得して、evaluated_typeと名づけエンジンに設定
2)式の${type}を#evaluated_typeと置き換える。OGNLでは頭に「#」がつくと
  変数です。
3)out.println(#evaluated_type.name)を評価する。
こういう作業をループで行うものを作れば式言語をサポートしていなくても
大丈夫。エンジンラッパー内部でダイナミックに変数追加できる仕組みを
実装しておけばOK。
http://package.gluegent.com/~kurihara/maya/MayaELImplSample20041201.zip
のサンプル実装では、VariableResolverに対して、ExpressionEvaluatorから
ダイナミックに変数を設定できる仕組みを用意すれば実現できます。サンプル
実装ではVariableResolverもExpressionEvaluatorもJSPのものをそのまま
使っていて、いじってませんが、APIを良く考えてインターフェイスを切れば
対応できます。あとはサンプル中のOgnlExpressionEvaluatorでやってることを
ネスト対応のループ構造にすればよいでしょう。後々、こっそりやっときます。
ご説明いただいて理解したので、瞬殺で実装できる内容になりました。仕様
として出すところは、${  }の囲いを、「{」と「} 」の対応関係で切り出すこと
だけで、デフォルトのOGNLの実装でネスト構造をカバーしたのは伏せると
思います。今のところ、ユーザーシーンとして、ちょっとトリッキーだなあと
思うので。後々、考えかわるかもしれませんが。

> なるほど。ちょっと思ったのですが、なぜMayaではMayaが解釈する式言語
> の指定をJSP仕様と同じ${...}にしたのでしょうか。ぱっと考えた感じでは、
> JSFの#{...}のように、別の指定方式にした方が上記の「評価に関する問題」
> は避けやすいと感じたのですが、何か理由があるのでしょうか。(ひょっと
> してMaya仕様書に書いてあったかもしれませんが読み流してしまったかも。)

  はじめは、JSFにあわせて#{ } としていたのですよ。JSFは#{  }が無いとダメ
で(少なくともMyFacesはハードコーディングされています)、式記述でそう
書くか、JSFに渡す際に囲いなおすかしないといけないのです。評価時期
の区別は、カスタムタグの所属する名前空間がJSFなどのMayaにあらかじ
め教えられているものについては、属性内の式言語バースを行なわずに、
スルーし、一方でデフォルトではMaya側で評価するように考えていました。
このときはJSR245の存在を知らなかったのですが、結果としてニアな感じ
になったのじゃないかなと今では思います。しかし、仕様や実装での重さを
懸念して、${  }に変えました。これは別に@{ }でもognl:{ } でもなんでもよく、
ブロック化だけが要件だったのです。そんな中、馴染みのものとして、${  }
としました。見慣れてるもののほうがいいかなと思いまして。

--
株式会社グルージェント
栗原 傑享(くりはら まさたか)
渋谷区渋谷3-7-6 第6矢木ビル4F
TEL:03-5469-8869 FAX:03-5469-8879
URL:http://www.gluegent.com/
--


> 横田です。
> 
> On Tue, 30 Nov 2004 22:24:13 +0900
> Masataka Kurihara <[E-MAIL ADDRESS DELETED]> wrote:
> 
> > 栗原です。
> 
> 詳しい返答ありがとうございます。
> 
> > > これが例えば「{」と「}」のバランスを考慮して切り出してくれるですとか、「"」
> > > から「"」までの間を切り出してくれるですとか、そのようになっているのでしたら
> > > うれしいのです。
> > 
> >   「"」で囲われた範囲全部を切り出すというのは、ボディ部に記述された
> > 式言語を考慮していないので、記述される箇所に応じて式言語ブロックの
> > 挙動が変わるという問題があります。そこに対応策はいらないのでしょうか?
> 
> はい、「"」の話は一例ですので実際は栗原さんがおっしゃったような問題が
> あると思います。ですので「"」で切り出しはせずにネストを見るようにする
> 方が現実的だと思います。
> 
> >   一方で、「${」と「}」のネストを見る仕組みになると、ネスとされる式言語に
> > 対して、どう評価結果を渡すかを考えなければなりません。例の
> > 
> > ${(this#)${type}.name}
> > 
> >   で、まず評価は、typeを評価します。その結果を外側の式言語にどう
> > 埋め込むかがわかりません。文字列にしてしまっていいのであればそういう
> > 実装も作れないこともないかと思いますが、${ type } をtoString()やコン
> > バーターで単なる文字列に変換してしまってOKなのでしょうか?
> 
> 私の認識では、式言語の開始から終了までを切り出して式言語エンジンにまる
> なげ、です。つまり、MayaテンプレートのパーサはMayaテンプレートをパース
> していって「${」という文字列を見つけると、そこから(ネストを考慮しつつ)
> 式言語記述の終了部までを読み取って切り出し、式言語エンジンに渡します。
> この例の場合は「${(this#)${type}.name}」を渡します。後の解釈は式言語エ
> ンジンが行なうイメージです。(式言語の書式を知っているべきなのはMayaパー
> サではなく式言語エンジンなので、そうするのが美しいかな、と。)
> 
> ただし、式言語エンジンが式言語の埋め込み指定(${...}という形式)を知ら
> ない場合、言い換えると、式言語の埋め込み指定はあくまでMayaテンプレート
> での指定方法であって式言語エンジンはテンプレート内での指定方法に関与し
> ない、という場合は、上記の方法はうまくないです。
> 
> そういう意味で、なかなか難しい問題ではあります。
> 
> 一つの解決策として、Mayaテンプレート側の仕様として
> ・「${」で始まる部分は式言語指定
> ・式言語指定は「}」で終了する
> ・式言語指定は入れ子にできる
> と決めて良ければ、テンプレートのパース時に「${」が出現した時点で入れ子
> 構造を解釈しつつ式言を構成するパーツをツリー構造につなぎあわせて、それ
> をもとに再帰的に式言語エンジンを呼び出す、という方法があります。
> 
> 例えば上記の例では、「${(this#)${type}.name}」を以下のパーツツリーに分
> 解します。
> 
> (root)-+-"(this#)" (文字列)
>        |
>        +-(Aへの参照)
>        |
>        +-".name" (文字列)
> 
>    (A)-+-"type" (文字列)
> 
> これを(root)から再帰的に辿り式言語エンジンを呼び出します。
> 
> 1. "(this#)" はそのまま。
> 2. (Aへの参照) は参照なので(A)の処理へ。
> 2-1. "type" はそのまま。
> 2-2. (A)以下が全て文字列になったので、連結した文字列「type」を式言語エ
>      ンジンに渡す。(以下、式言語エンジンの評価結果を「TYPE」と書きます。)
> 3. ".name" はそのまま。
> 4. (root)以下が全て文字列になったので、連結した文字列「(this#)TYPE.name」
>    を式言語エンジンに渡す。(以下、式言語エンジンの評価結果を「NAME」と
>    書きます。)
> 5. 最終的な結果「NAME」を返す。
> 
> という感じです。
> 
> こうすれば、式言語エンジン自体は入れ子を考えずにMaya中の式言語記述の評価
> が可能になります。
> 
> ただし、入れ子を想定していない言語体系の式言語に関しても入れ子が許されて
> しまうという副作用があります。(実はこれはメリットなのかもしれないですが。
> また、この辺は式言語エンジン毎に入れ子を許す言語体系なのかを指定できても
> よいのかもしれません。)
> 
> いかがでしょうか。
> 
> >   ジャストアイディアですが、私の提案する解決策は、式言語を、
> > 
> > ${(this#)#{type}.name}
> > ${(this#)@{type}.name}
> > ${(this#){type}.name}
> > 
> > という風に書くことです。「#{  }」じゃなく「@{  }」でも、単に「{  }」でも
> > いいです。Mayaは${ }で囲まれているところを式言語としますので、
> > 「{  }」のネストだけをきちんとみれば、切り出すELは
> > 
> > (this#)#{type}.name
> > 
> > となります。あとは、#{  } を式言語エンジンのほうで対応いただくことで
> > できるかと思います。いかがでしょうか?JSFのほうもそういう対応です。
> 
> はい、この方式でも私の用途には十分です。重要なのは、「{」「}」の入れ子
> をきちんと認識する、という点ですので、そこだけMaya側でサポートしていた
> だければ大丈夫そうです。
> 
> >   またさらに蛇足としては、JSP2.1の存在が悩ましいです。JSR文書の
> > 中に、
> > 
> > 「ability to defer expression evaluation until a time of a tag
> > handler's choosing 」
> > 
> > とあります。JSFの式言語も「${  }」でやって、たとえばTLDの宣言など
> > によってスルーで背後に送るのか、JSPプロセッサで評価するのか、また
> > 評価をJSPでする場合に限っても、それはレンダリング時だけか、JSFの
> > コンポーネントツリーの構築のときも評価するか、などのことを制御する
> > ということになりかねないなと。JSP2.1で式言語評価の仕様が変われば、
> > JSP2.1対応のカスタムタグがいずれ出てくることを考慮すると、Mayaで
> > もJSP2.1スペック対応していくことになると思います。
> 
> なるほど。ちょっと思ったのですが、なぜMayaではMayaが解釈する式言語
> の指定をJSP仕様と同じ${...}にしたのでしょうか。ぱっと考えた感じでは、
> JSFの#{...}のように、別の指定方式にした方が上記の「評価に関する問題」
> は避けやすいと感じたのですが、何か理由があるのでしょうか。(ひょっと
> してMaya仕様書に書いてあったかもしれませんが読み流してしまったかも。)
> 
> >   ということで、明日早いので風呂入って、寝ます。おやすみなさい。
> 
> お疲れ様でした&ありがとうございました。
> 
> --------
>   YOKOTA Takehiko
>     [E-MAIL ADDRESS DELETED]
> 
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> http://lists.sourceforge.jp/mailman/listinfo/seasar-user






Seasar-user メーリングリストの案内