2017-10-31 20 views
2

次のことを考えてみましょう:form.vars.attr.dimensions.widthが整数である数字の前に小数点がない場合、句読点/文字列を仮定する小枝?

A) {{ form.vars.attr.dimensions.width * .1875 }} 
B) {{ form.vars.attr.dimensions.width * 0.1875 }} 

以下はダンプのform.vars.attr.dimensionsです。

array:2 [ 
    "width" => 1600 
    "height" => 478 
] 

例Aは、次の例外がスローされます: "" 値の

予期しないトークン "句読点を"。

例Bが正しく出力300.0動作します。

私はそれが文字列として値を解釈する可能性が高いことを理解していますが、私の質問はになるでしょうか?私は引用符で囲まれていないので、リテラルとして見なされるべきではないと思います。私はnumber_format、先行ゼロなどのようなものでこれを回避することができることを認識しています。なぜ、Twigが小数点を正しく識別しないのか本当に不思議です。それとも別のものが欠けているかもしれない。

さらに、バニラPHPに適用したのと同じ論理がこのような状況を生成しません:

<?php 
    $val = 1600; 
    var_dump($val * .1875); 
    // float(300) 
?> 
+0

おそらく、それは 'twig'の実装のためです。 [here](https://twig.symfony.com/doc/2.x/templates.html)の全リストを見ることができます。あなたは少し向けてスクロールする必要があります*実装* – DarkBee

答えて

2

.1875.はすでにテンプレートのレンダリングの最初のステップで句読点トークンとして同定されています。

Twigのドキュメントでは、このプロセスについてTwig Internalsと記載しています。最初のステップで:

レクサーは、ドキュメントのセクションThe Lexerトークンストリーム

にテンプレートソースコードをトークン化し、それがトークンストリーム内にいくつかのソースコードを変換する方法を示しています。

$ex1 = '{{ form.vars.attr.dimensions.width * 0.1875 }}'; 
$ex2 = '{{ form.vars.attr.dimensions.width * .1875 }}'; 

$stream1 = $twig->tokenize(new Twig_Source($ex1, 'example1')); 
$stream2 = $twig->tokenize(new Twig_Source($ex2, 'example2')); 

出力はこのようなものです:私たちはあなたの二つの例でそれを行う場合には、プロセスの次のステップで

Example 1:    Example 2: 

VAR_START_TYPE()   VAR_START_TYPE() 
NAME_TYPE(form)   NAME_TYPE(form) 
PUNCTUATION_TYPE(.)  PUNCTUATION_TYPE(.) 
NAME_TYPE(vars)   NAME_TYPE(vars) 
PUNCTUATION_TYPE(.)  PUNCTUATION_TYPE(.) 
NAME_TYPE(attr)   NAME_TYPE(attr) 
PUNCTUATION_TYPE(.)  PUNCTUATION_TYPE(.) 
NAME_TYPE(dimensions) NAME_TYPE(dimensions) 
PUNCTUATION_TYPE(.)  PUNCTUATION_TYPE(.) 
NAME_TYPE(width)   NAME_TYPE(width) 
OPERATOR_TYPE(*)   OPERATOR_TYPE(*) 
NUMBER_TYPE(0.1875)  PUNCTUATION_TYPE(.)  <---- 
VAR_END_TYPE()   NUMBER_TYPE(1875) 
EOF_TYPE()    VAR_END_TYPE() 
         EOF_TYPE() 

、パーサが木にトークンストリームを変換しようとし、あなたが見ているエラーを引き起こすオペレータの後に句読トークンが意味をなさない。

最初のステップでTwig lexerがそのように動作する理由は、the sourceをチェックすると、式レクサーが入力文字列をステップ実行し、さまざまな正規表現を順番に適用します。数の正規表現は.1875一致しない

'/[0-9]+(?:\.[0-9]+)?/A' 

であり、そして次の工程で、.は句読点として識別されます。

ゼロを付けずに10進数で動作させる方法を見つけようとすると、この回答は役に立ちませんが、動作の仕方を理解することにもっと興味があるように思えますこれは参考になります。

+0

これはまさに私が探していたものです。詳細な説明をありがとうございました!そして、はい、何らかの回避策を見つけようとするよりも好奇心が増していました。感謝します!! –

+0

ようこそ。興味深い質問をしてくれてありがとう。 :) –

関連する問題