metaprogramming javascript
TRANSCRIPT
Metaprogramming JavaScript
Adam [email protected]
Making JavaScript Suck Less
Kicking Ass with JavaScript
an (extremely contrived ) example
Specification:- show state field when country is “United States”
Prototype makes it easy
…but then specs change:
- change state field to us-state, and add a province field- show us-state field when country is "United States"- show province field when country is "Canada"- show Brutus when us-state is "Ohio" or "Michigan"
(because we can)
Metaprogramming to the rescue!
details implementation
“what” “how”
details implementation
“what” “how”
details implementation
frequency of change
“what” “how”
details implementation
configuration file?
mini language?
xml? plain text?
executable code?
“what” “how”
details implementation
configuration file?
mini language?
xml? plain text?
executable code?
DSL
A Rails Example
A Rails Example
These are just calls to class methods,what’s the big deal?
It just feels right.
A DSL for dynamic form behavior
Sounds great!
…but…
Where do we start?
start with the specs
start with the specs
start with the specs
language does not mirror the problem domain
let’s try again
let’s try again
Dependency DependencyTrigger
now handle the change event
everything is “wired up”, now make it behave
It works!!!
but it needs cleaned up
let’s avoid top-level functionsby creating our own namespace
Dependency DependencyTrigger
DependencyManager
Form.Behavior
breaking encapsulation
check dependencies when page loads
Fix “domino” bug: when an element is shown/hidden, it may contain trigger fields; check dependencies on these fields
Fix “domino” bug: when an element is shown/hidden, it may contain trigger fields; check dependencies on these fields
Fix “domino” bug: when an element is shown/hidden, it may contain trigger fields; check dependencies on these fields
Fix “domino” bug: when an element is shown/hidden, it may contain trigger fields; check dependencies on these fields
Fix “domino” bug: when an element is shown/hidden, it may contain trigger fields; check dependencies on these fields
hidden fields should have no value –flag them here so we can identify them later
circular reference
DOM Element JavaScript Object
circular reference: resolved
DOM Element JavaScript Object
Our DSL is too rigid, let’s allow some variation:
or
resolves tothis.show()
orthis.hide()
Extensibility
Dependency DependencyTrigger
DependencyManager
Form.Behavior
Actionsextends
More duplication!
It must go.
separate “what” from “how”
mini-language mirroring problem domain
self-documenting code
reuseableeasy to maintain
Metaprogramming Review
keep it object-oriented
method chaining for sentence-like syntax
use with() and English-like method names
don’t fear evalincremental implementation
JavaScript Tools & Tips