Well, let's go through them together.
We could rename "javascript output" to anything as long as we're consistent.
This is very tempting.
Why don't I change this ugly space to an underscore.
Well, the reason is that if the user knew that, in their embedded JavaScript fragment,
they could assign to the variable "javascript_output"
and because we're piggybacking on our environment,
they'd find it, and they'd collide with it.
So rather than printing out the right answer,
we'd print out whatever the value was for this variable "javascript output."
It's super unlikely, very unlikely that the user would happen to name a variable
"javascript_output," but it's a security problem and officially there exists at least
a few programs that won't compute the right answer
if we change it to a variable that the user can collide with.
So we can't actually rename it to anything.
We have to be careful.
When this feeds into the second one, "javascript output" is a good choice
because it has a space in it--yes!
If you think back to our lexer rule for identifiers,
it looks something like this.
Every javascript identifier contains upper or lowercase letters and possibly an underscore
but can't contain a space.
So this means there is no way for the user to have a variable name that has a space in it,
so no way for them to collide with the rest of the environment.
We could also have made a different design decision and had some global variable
that's stored the "javascript output," but this approach, first, piggybacks on something
you've already done, and second, illuminates cool issues like this.
Finally, "javascript output" starts empty to support 0 calls to write.
That does end up working out.
Imagine that trees is the empty list.
They just said begin Javascript, end JavaScript and didn't do any work.
We would want to return a real value rather than having some sort of exception
or look-up error problem.
If I didn't initialize "javascript output" to the empty string,
when we went to look it up here, there might not be anything there.
一緒に見ていきます
“javascript outputという名前は
一貫性があればどのような名前にも変えられる”
魅力的ですね
どうしてこのスペースを
アンダースコアに変えないのでしょうか
それはもしユーザが名前を知っていたら
JavaScriptのコードの中で
javascript_outputという変数に
値を入れることができるからです
今は環境を借りているため
ユーザが探せてしまい衝突します
つまり正解を出力するのではなく
javascript_outputの値を
予期せず出力してしまいます
ユーザがjavascript_outputという
変数名をつけることはあまりないとは思います
セキュリティ上の問題でユーザのつける名前とは
衝突してはいけないことになっています
ユーザのつけた名前と衝突した場合
正しい計算ができなくなります
どのような名前でもよいわけではありません
今のを理解した上で2番目の文章を読みます
“javascript outputはスペースが入って
いるのでよい命名だ” そのとおり!
字句解析の識別子の規則まで戻って考えます
JavaScriptの識別子は大文字、小文字、
アンダースコアのみでスペースは使えません
ユーザはスペースを含む変数名をつけられません
従って他の環境の変数には衝突しないのです
他の設計を選んでグローバル変数を作って
出力を保存することもできました
しかしこの解法は他のものを流用できて
さらに面白い工夫が光ります
“javascript outputは空で始まるので
writeが呼ばれなくとも動く”
確かにそのとおりです
木が空のリストの場合を想像しましょう
JavaScriptの開始タグの直後に
終了タグが来て何もしなかった場合です
その場合でも参照エラーや例外を出さずに
値を返したいですね
もしjavascript outputを
空の文字列で初期化していなかったら
それを参照しようとした時に
存在しないことがあるかもしれません
Bem, vamos ver isso juntos.
1) Podemos renomear "javascript output" para outra coisa, desde que sejamos coerentes.
Isso é muito tentador.
Porque não alterar este espaço em branco para _ ?
Bem, a razão é que, se o usuário souber isso, em seu fragmento de código JavaScript embutido,
ele poderia atribuir à variável "javascript_output",
e, como estamos usando nosso próprio ambiente,
ele o teria encontrado e colidido com ele.
Então, ao invés de exibir a resposta correta,
iríamos imprimir o que quer que fosse o valor para essa variável "javascript_output".
É muito pouco provável, muito pouco provável, que o usuário acabasse chamando uma variável
de "javascript_output", mas esse é um problema de segurança e, oficialmente, existiriam pelo menos
alguns programas que não computariam a resposta correta,
se alteramos o nome para o de uma variável com o qual o usuário possa colidir.
Portanto, de fato não queremos renomear para qualquer coisa.
Temos que ter cuidado.
Quando transportamos isso para 2) "javasript output" é uma boa escolha
porque tem um espaço no meio -- Sim!
Se você se lembra da nossa regra do lexer para identificadores,
ela é algo como isto.
Todo identificador JavaScript contém letras maiúsculas ou minúsculas, e possivelemte _,
mas não pode conter um espaço.
Então, isso significa que não existe maneira de o usuário ter um nome de variável com um espaço,
e portanto não há como colidir com o resto do ambiente.
Nós poderíamos ter adotado uma decisão de projeto diferente: ter alguma variável global
que armazenasse a "javascript output"; mas essa abordagem: 1) usa algo
que você já fez; 2) evidencia questões interessantes como esta.
Finalmente: "javascript output" começa vazia, para tratar o caso de 0 chamadas a write.
Isso acaba funcionando.
Imagine que a árvore seja a lista vazia --
o código é apenas: begin javascript end javascript -- não faz nada.
Vamos querer retornar algum valor, ao invés de ter um certo tipo de exceção,
ou um problema de look_up.
Se eu não inicializo "javascript output" com o string vazio,
quando eu for buscar aqui, pode não haver nada aí.