The Strange World of Directory Scope

04 June 2016

Most languages today use lexical scope
. A few older languages use dynamic scope
. Imagine my surprise this week, when debugging a Handlebars
template, finding a totally new approach to scope!

What if we required programmers to access scopes explicitly? Sound crazy? In Handlebars, this is a reality!

Handlebars does not let you access variables in outer scopes
. Suppose we have the following context:

var context = {user: "Alice",
               friends: ["Bob", "Charlie", "Diane"]};

We can access user
in the top-level scope:

This user is {{user}}.

renders as:

This user is Alice.

However, we cannot access user
from #each

{{#each friends}}
{{user}} is friends with {{this}}.

renders as:

is friends with Bob.
is friends with Charlie.
is friends with Diane.

Handlebars provides filesystem style syntax
to access the parent scope:

{{#each friends}}
{{../user}} is friends with {{this}}.

renders as:

Alice is friends with Bob.
Alice is friends with Charlie.
Alice is friends with Diane.

Wow! I’d believed there was nothing beyond dynamic and lexical scoping. I’m not aware of a name for this style of scope, so I’m going to call it ‘directory scope’ for the sake of this post.

Directory scope does have its downsides. It makes refactoring more difficult, because templates are very sensitive to context. If you introduce a new block, or move code around, you may need to change how you access your variables.

It has a number of benefits too though. You never need to worry about shadowing variables. You can still access variables in outer scopes, even if they have the same name! No namespacing required.

If you’re not worried about shadowing, then writing new control structures, lisp-style, is easy. A lisp macro author would worry about hygiene in blocks, because they could end up shadowing user-defined variables.

A Handlebars block author can inject variables with gay abandon. Suppose we defined a #with-user
block. This could inject a user
variable without breaking any of our code examples above.

The syntax choice is also clever. You can probably guess what ./foo
means (access the variable in the current scope) and what ../../foo
means (access the variable in the grandparent scope).

This illustrates the value of regularly learning new languages. Starting from a bug — why isn’t my variable in scope? — I ended up a exploring a radically different approach to scoping with a fresh set of tradeoffs.

稿源:Wilfred Hughes Blog (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 后端存储 » The Strange World of Directory Scope

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录