SlideShare a Scribd company logo
1 of 90
Download to read offline
The Hidden Power
of HTMLBars
or, Scope in Ember.js Templates
EmberCamp 2015
@mixonic
Ember.js Core Team
201 Created
Consultants in NewYork City
BrooklynLondon
BrooklynLondon
BrooklynLondon
BrooklynLondon
BrooklynLondon
Chips Fries
BrooklynLondon
Chips Fries
Crisps Chips
BrooklynLondon
Chips Fries
Crisps Chips
BrooklynLondon
Chips Fries
Crisps Chips
Fries
BrooklynLondon
Chips Fries
Crisps Chips
Fries Crisps
BrooklynLondon
Chips Fries
Crisps Chips
Fries Crisps
Metric
BrooklynLondon
Chips Fries
Crisps Chips
Fries Crisps
Metric
FREEDOM
Chips
Crisps
Fries
?
“Hey, look at those chips”
“chips”
? ?
? ?
?
? ?
?
BrooklynLondon
42-48˚ F50-57˚ F
10–14˚ C 5-9˚ C
Scope
EntityScope + Rules + Label
EntityScope + Rules + Label
cold beer
cold beers

are served in NYC
“chips”
thin, flat, and fried

slices of potato
1 {{! app/templates/components/british-pub.hbs }}
2 <h2>{{name}} Menu</h2>
3 <ul>
4 {{#each snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
1 {{! app/templates/components/british-pub.hbs }}
2 <h2>{{name}} Menu</h2>
3 <ul>
4 {{#each snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
Label
1 {{! app/templates/components/british-pub.hbs }}
2 <h2>{{name}} Menu</h2>
3 <ul>
4 {{#each snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
Scope
Rules
1. Dynamic Scope
2. Lexical (Static) Scope
Dynamic Scope
“In languages with dynamic
scope the name resolution
depends upon the program state
when the name is encountered
which is determined by the
execution context or calling
context.”
Wikipedia
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name;
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # local_sub: Fry
6 # show_name: Crisp
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name;
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name;
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp";
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # local_sub: Fry
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # local_sub: Fry
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # local_sub: Fry
6
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # local_sub: Fry
6 # show_name: Crisp
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # local_sub: Fry
6 # show_name: Crisp
7 sub local_sub {
8 local $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "local_sub: ", &local_sub(), "n";
18 print "show_name: ", &show_name(), "n";
What context do you
need to understand the
value of $name?
“In languages with dynamic
scope the name resolution
depends upon the program state
when the name is encountered
which is determined by the
execution context or calling
context.”
Wikipedia
Lexical (Static) Scope
“In languages with lexical scope (also
called static scope), name resolution
depends on the location in the source
code and the lexical context, which is
defined by where the named variable or
function is defined.”
Wikipedia
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # my_sub: Crisp
6 # show_name: Crisp
7 sub my_sub {
8 my $name = "Fry";
9 return show_name();
10 }
11
12 sub show_name {
13 return $name;
14 }
15
16 print "$name: $namen";
17 print "my_sub: ", &my_sub(), "n";
18 print "show_name: ", &show_name(), "n";
1 #!/usr/bin/perl -w
2 use strict;
3
4 our $name; # $name: Crisp
5 $name = "Crisp"; # my_sub: Fry
6 # show_name: Crisp
7 sub my_sub {
8 my $name = "Fry";
9 return show_name($name);
10 }
11
12 sub show_name {
13 return shift || $name;
14 }
15
16 print "$name: $namen";
17 print "my_sub: ", &my_sub(), "n";
18 print "show_name: ", &show_name(), "n";
“In languages with lexical scope (also
called static scope), name resolution
depends on the location in the source
code and the lexical context, which is
defined by where the named variable or
function is defined.”
Wikipedia
Benefits of Static Scope
1. Possible to optimize at compile time
2. Easier for developers to read
3. JavaScript and pretty much all
languages use it
1 {{! app/templates/index.hbs }}
2 <h2>{{name}} Menu</h2>
3 <ul>
4 {{#view 'localized-menu' model}}
5 <li>{{name}}: {{model.price}}</li>
6 {{/view}}
7 </ul>
Ember 1.x
1 {{! app/templates/index.hbs }}
2 <h2>{{name}} Menu</h2>
3 <ul>
4 {{#view 'localized-menu' model}}
5 <li>{{name}}: {{model.price}}</li>
6 {{/view}}
7 </ul>
Ember 1.x
• Index controller
• Index controller model
• New context from
localized-menu
• Helper
Dynamic
1 {{! app/templates/index.hbs }}
2 <h2>{{name}} Menu</h2>
3 <ul>
4 {{#view 'localized-menu' model}}
5 <li>{{name}}: {{model.price}}</li>
6 {{/view}}
7 </ul>
Ember 1.x Ember 2.x
1 {{! app/templates/index.hbs }}
2 <h2>{{model.name}} Menu</h2>
3 <ul>
4 {{#each model.snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
1 {{! app/templates/index.hbs }}
2 <h2>{{model.name}} Menu</h2>
3 <ul>
4 {{#each model.snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
Ember 2.x
• Property on packet
• Helper
Static
1 {{! app/templates/index.hbs }}
2 <h2>{{model.name}} Menu</h2>
3 <ul>
4 {{#each model.snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
Ember 2.x
• Property on packet
• Helper
Static
1 {{! app/templates/index.hbs }}
2 <h2>{{model.name}} Menu</h2>
3 <ul>
4 {{#each model.snacks as |packet|}}
5 <li>{{packet.name}}: {{packet.price}}</li>
6 {{/each}}
7 </ul>
1 function buildIndex(model) {
2 let html = `<h2>${model.name} Menu</h2>`;
3 html += '<ul>';
4 model.snacks.forEach(packet => {
5 html += `<li>
6 ${packet.name}: ${packet.price}
7 </li>`;
8 });
9 html += '</ul>';
10 return html;
11 }
Ember 2.x
Creating a template system with static
scoping is an intentional goal of
HTMLBars/Glimmer, and directs the
underlying architecture.
Tools for Static Scope
Closures
Closures
1 function generateSayName() {
2 let name = 'Chips';
3 return function() {
4 alert(name);
5 };
6 }
7
8 var sayName = generateSayName();
9
10 console.log(sayName()); // alerts: Chips
1 function generateSayName() {
2 let name = 'Chips';
3 return function() {
4 alert(name);
5 };
6 }
7
8 var sayName = generateSayName();
9
10 console.log(sayName()); // alerts: Chips
Closures
Ember Actions as Closures
1 {{#with (action 'alert' name) as |sayName|}}
2 <button {{action sayName}}>Say the name!</button>
3 {{/with}}
Ember Actions as Closures
1 {{! app/templates/components/generate-say-name.hbs }}
2 {{yield (action 'alert' name)}}
1 {{! app/templates/index.hbs }}
2 {{#generate-say-name name='Chip' as |sayName|}}
3 <button {{action sayName}}>Say the name!</button>
4 {{/generate-say-name}}
Ember Actions as Closures
1 {{! app/templates/components/generate-say-name.hbs }}
2 {{yield (hash
3 sayBritish=(action 'alert' 'Crisp')
4 sayAmerican=(action 'alert' 'Chip')
5 )}}
1 {{! app/templates/index.hbs }}
2 {{#generate-say-name as |ux|}}
3 <button {{action ux.sayBritish}}>Say the name!</button>
4 {{/generate-say-name}}
Ember actions are just
JavaScript functions.
Ember Components as Closures
1 {{! app/templates/index.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{#ux.sayBritish}}Say the name!{{/ux.sayBritish}}
4 {{/generate-say-name}}
1 {{! app/templates/components/generate-say-name.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-name-button' name='Crisp')
4 sayAmerican=(component 'say-name-button' name='Chip')
5 )}}
Pods, Local Lookup, and Closures
bit.ly/pods-local-lookup
speakerdeck.com/rwjblue/a-tale-of-two-pods
Pods
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 routes/
6 index/
7 template.hbs
Pods
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 routes/
6 index/
7 template.hbs
1 {{! app/routes/index/template.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}}
4 {{/generate-say-name}}
Pods
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 routes/
6 index/
7 template.hbs
1 {{! app/routes/index/template.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}}
4 {{/generate-say-name}}
1 {{! app/components/generate-say-name/template.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-name-button' name='Crisp')
4 sayAmerican=(component 'say-name-button' name='Chip')
5 )}}
Pods
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 routes/
6 index/
7 template.hbs
1 {{! app/components/generate-say-name/template.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-name-button' name='Crisp')
4 sayAmerican=(component 'say-name-button' name='Chip')
5 )}}
Pods
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 routes/
6 index/
7 template.hbs
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 say-name-button/
6 template.hbs
7 routes/
8 index/
9 template.hbs
1 {{! app/components/generate-say-name/template.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-name-button' name='Crisp')
4 sayAmerican=(component 'say-name-button' name='Chip')
5 )}}
Pods
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
1 {{! app/components/generate-say-name/template.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-name-button' name='Crisp')
4 sayAmerican=(component 'say-name-button' name='Chip')
5 )}}
Local Lookup
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
1 {{! app/components/generate-say-name/template.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-name-button' name='Crisp')
4 sayAmerican=(component 'say-name-button' name='Chip')
5 )}}
Local Lookup
1 {{! app/routes/index/template.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}}
4 {{/generate-say-name}}
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
Local Lookup
1 {{! app/routes/index/template.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}}
4 {{/generate-say-name}}
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
Local Lookup
1 {{! .../say-name-button/template.hbs }}
2 <button {{action 'alert' name}}>{{yield}}</button>
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
Local Lookup
1 {{! .../say-name-button/template.hbs }}
2 <button {{action 'alert' name}}>{{yield}}</button>
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
Local Lookup
1 {{! app/routes/index/template.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}}
4 {{/generate-say-name}}
1 app/
2 components/
3 generate-say-name/
4 template.hbs
5 components/
6 say-name-button/
7 template.hbs
8 routes/
9 index/
10 template.hbs
Local Lookup
bit.ly/pods-local-lookup
speakerdeck.com/rwjblue/a-tale-of-two-pods
Tools for Static Scope
Partial Applications
Partial Application
1 function generateSayName() {
2 let name = 'Chips';
3 return function(honorific) {
4 alert(`${honorific} ${name}`);
5 };
6 }
7
8 var sayName = generateSayName();
9
10 console.log(sayName('Mr.')); // logs: Mr. Chips
1 function generateSayName() {
2 let name = 'Chips';
3 return function(honorific) {
4 alert(`${honorific} ${name}`);
5 };
6 }
7
8 var sayName = generateSayName();
9
10 console.log(sayName('Mr.')); // logs: Mr. Chips
Partial Application
1 function generateSayName() {
2 let name = 'Chips';
3 return function(honorific) {
4 alert(`${honorific} ${name}`);
5 };
6 }
7
8 var sayName = generateSayName();
9
10 console.log(sayName('Mr.')); // logs: Mr. Chips
Partial Application
Ember Actions with Partial Application
1 {{! app/templates/index.hbs }}
2 {{#generate-say-name as |sayName|}}
3 <button {{action sayName 'Mr.'}}>Say the name!</button>
4 {{/generate-say-name}}
1 {{! app/templates/components/generate-say-name.hbs }}
2 {{yield (action 'alert' 'Crisps')}}
Ember Actions with Partial Application
1 {{! app/templates/index.hbs }}
2 {{#generate-say-name as |sayName|}}
3 <button {{action sayName 'Mr.'}}>Say the name!</button>
4 {{/generate-say-name}}
1 {{! app/templates/components/generate-say-name.hbs }}
2 {{yield (action 'alert' 'Crisps')}}
1 actions: {
2 alert(name, honorific) {
3 console.log(`${honorific} ${name}`);
4 }
5 }
Ember Components with Partial Application
1 {{! app/templates/components/generate-say-name.hbs }}
2 {{yield (hash
3 sayBritish=(component 'say-button-name' honorific='MP')
4 sayAmerican=(component 'say-button-name' honorific='Rep')
5 )}}
1 {{! app/templates/index.hbs }}
2 {{#generate-say-name as |ux|}}
3 {{ux.sayBritish name='Chips'}}
4 {{ux.sayAmerican honorific='Mr.' name='Fry'}}
5 {{/generate-say-name}}
1 {{! app/templates/components/say-button-name.hbs }}
2 <button {{action 'alert' name honorific}}>Say the Name</button>
Tools for Static Scope
Recursion?!
emberjs.jsbin.com/fubutusejo/1/edit?html,js,output
Ember templates have the scoping rules
and consistency of a real language.
Develop using the patterns and tools you
would use in a real language.
Thanks!
@mixonic

More Related Content

What's hot

Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type Systemabrummett
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16Ricardo Signes
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)brian d foy
 
Créer une base NoSQL en 1 heure
Créer une base NoSQL en 1 heureCréer une base NoSQL en 1 heure
Créer une base NoSQL en 1 heureAmaury Bouchard
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlordsheumann
 
Advanced modulinos trial
Advanced modulinos trialAdvanced modulinos trial
Advanced modulinos trialbrian d foy
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The AnswerIan Barber
 
Get into the FLOW with Extbase
Get into the FLOW with ExtbaseGet into the FLOW with Extbase
Get into the FLOW with ExtbaseJochen Rau
 

What's hot (20)

Pop3ck sh
Pop3ck shPop3ck sh
Pop3ck sh
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)
 
pts_ldap
pts_ldappts_ldap
pts_ldap
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
PHP code examples
PHP code examplesPHP code examples
PHP code examples
 
Perl6 one-liners
Perl6 one-linersPerl6 one-liners
Perl6 one-liners
 
Créer une base NoSQL en 1 heure
Créer une base NoSQL en 1 heureCréer une base NoSQL en 1 heure
Créer une base NoSQL en 1 heure
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
PHP Tips & Tricks
PHP Tips & TricksPHP Tips & Tricks
PHP Tips & Tricks
 
Advanced modulinos trial
Advanced modulinos trialAdvanced modulinos trial
Advanced modulinos trial
 
ZeroMQ Is The Answer
ZeroMQ Is The AnswerZeroMQ Is The Answer
ZeroMQ Is The Answer
 
03 tk2123 - pemrograman shell-2
03   tk2123 - pemrograman shell-203   tk2123 - pemrograman shell-2
03 tk2123 - pemrograman shell-2
 
Get into the FLOW with Extbase
Get into the FLOW with ExtbaseGet into the FLOW with Extbase
Get into the FLOW with Extbase
 

Similar to The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)

Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday DeveloperRoss Tuck
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation TutorialLorna Mitchell
 
One Sass File, So Many Sites
One Sass File, So Many SitesOne Sass File, So Many Sites
One Sass File, So Many SitesMina Markham
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
JSON Schema in Web Frontend #insideFE
JSON Schema in Web Frontend #insideFEJSON Schema in Web Frontend #insideFE
JSON Schema in Web Frontend #insideFEHiroyuki Anai
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Lecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administrationLecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administrationMohammed Farrag
 
Programming in perl style
Programming in perl styleProgramming in perl style
Programming in perl styleBo Hua Yang
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!Boy Baukema
 
Redis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationRedis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationrjsmelo
 
Working with web_services
Working with web_servicesWorking with web_services
Working with web_servicesLorna Mitchell
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Elixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding themElixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding themDan Janowski
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 

Similar to The Hidden Power of HTMLBars (or, Scope in Ember.js Templates) (20)

Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday Developer
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
One Sass File, So Many Sites
One Sass File, So Many SitesOne Sass File, So Many Sites
One Sass File, So Many Sites
 
Subroutines
SubroutinesSubroutines
Subroutines
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
JSON Schema in Web Frontend #insideFE
JSON Schema in Web Frontend #insideFEJSON Schema in Web Frontend #insideFE
JSON Schema in Web Frontend #insideFE
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Lecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administrationLecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administration
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
Programming in perl style
Programming in perl styleProgramming in perl style
Programming in perl style
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!
 
Cleancode
CleancodeCleancode
Cleancode
 
Redis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your applicationRedis & ZeroMQ: How to scale your application
Redis & ZeroMQ: How to scale your application
 
My shell
My shellMy shell
My shell
 
Working with web_services
Working with web_servicesWorking with web_services
Working with web_services
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Elixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding themElixir and Dialyzer, Types and Typespecs, using and understanding them
Elixir and Dialyzer, Types and Typespecs, using and understanding them
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 

More from Matthew Beale

Ember.js Module Loading
Ember.js Module LoadingEmber.js Module Loading
Ember.js Module LoadingMatthew Beale
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017Matthew Beale
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component PatternsMatthew Beale
 
Ember Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkEmber Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkMatthew Beale
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
New Component Patterns in Ember.js
New Component Patterns in Ember.jsNew Component Patterns in Ember.js
New Component Patterns in Ember.jsMatthew Beale
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector emberMatthew Beale
 
Testing Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyTesting Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyMatthew Beale
 
Parse Apps with Ember.js
Parse Apps with Ember.jsParse Apps with Ember.js
Parse Apps with Ember.jsMatthew Beale
 
Snappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsSnappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsMatthew Beale
 
Client-side Auth with Ember.js
Client-side Auth with Ember.jsClient-side Auth with Ember.js
Client-side Auth with Ember.jsMatthew Beale
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.jsMatthew Beale
 
Complex Architectures in Ember
Complex Architectures in EmberComplex Architectures in Ember
Complex Architectures in EmberMatthew Beale
 
Ember and containers
Ember and containersEmber and containers
Ember and containersMatthew Beale
 

More from Matthew Beale (15)

Ember.js Module Loading
Ember.js Module LoadingEmber.js Module Loading
Ember.js Module Loading
 
LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017LA Ember.js Meetup, Jan 2017
LA Ember.js Meetup, Jan 2017
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component Patterns
 
Ember Community 2016 - Be the Bark
Ember Community 2016 - Be the BarkEmber Community 2016 - Be the Bark
Ember Community 2016 - Be the Bark
 
Attribute actions
Attribute actionsAttribute actions
Attribute actions
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
New Component Patterns in Ember.js
New Component Patterns in Ember.jsNew Component Patterns in Ember.js
New Component Patterns in Ember.js
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector ember
 
Testing Ember Apps: Managing Dependency
Testing Ember Apps: Managing DependencyTesting Ember Apps: Managing Dependency
Testing Ember Apps: Managing Dependency
 
Parse Apps with Ember.js
Parse Apps with Ember.jsParse Apps with Ember.js
Parse Apps with Ember.js
 
Snappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember AppsSnappy Means Happy: Performance in Ember Apps
Snappy Means Happy: Performance in Ember Apps
 
Client-side Auth with Ember.js
Client-side Auth with Ember.jsClient-side Auth with Ember.js
Client-side Auth with Ember.js
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Complex Architectures in Ember
Complex Architectures in EmberComplex Architectures in Ember
Complex Architectures in Ember
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 

Recently uploaded

Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 

Recently uploaded (20)

Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 

The Hidden Power of HTMLBars (or, Scope in Ember.js Templates)

  • 1. The Hidden Power of HTMLBars or, Scope in Ember.js Templates EmberCamp 2015
  • 16. “Hey, look at those chips”
  • 19. Scope
  • 21. EntityScope + Rules + Label cold beer cold beers
 are served in NYC “chips” thin, flat, and fried
 slices of potato
  • 22. 1 {{! app/templates/components/british-pub.hbs }} 2 <h2>{{name}} Menu</h2> 3 <ul> 4 {{#each snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul>
  • 23. 1 {{! app/templates/components/british-pub.hbs }} 2 <h2>{{name}} Menu</h2> 3 <ul> 4 {{#each snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul> Label
  • 24. 1 {{! app/templates/components/british-pub.hbs }} 2 <h2>{{name}} Menu</h2> 3 <ul> 4 {{#each snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul> Scope
  • 25. Rules
  • 26. 1. Dynamic Scope 2. Lexical (Static) Scope
  • 28. “In languages with dynamic scope the name resolution depends upon the program state when the name is encountered which is determined by the execution context or calling context.” Wikipedia
  • 29. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 30. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # local_sub: Fry 6 # show_name: Crisp 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 31. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 32. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 33. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 34. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 35. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 36. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 37. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # local_sub: Fry 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 38. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # local_sub: Fry 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 39. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # local_sub: Fry 6 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 40. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # local_sub: Fry 6 # show_name: Crisp 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 41. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # local_sub: Fry 6 # show_name: Crisp 7 sub local_sub { 8 local $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "local_sub: ", &local_sub(), "n"; 18 print "show_name: ", &show_name(), "n"; What context do you need to understand the value of $name?
  • 42. “In languages with dynamic scope the name resolution depends upon the program state when the name is encountered which is determined by the execution context or calling context.” Wikipedia
  • 44. “In languages with lexical scope (also called static scope), name resolution depends on the location in the source code and the lexical context, which is defined by where the named variable or function is defined.” Wikipedia
  • 45. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # my_sub: Crisp 6 # show_name: Crisp 7 sub my_sub { 8 my $name = "Fry"; 9 return show_name(); 10 } 11 12 sub show_name { 13 return $name; 14 } 15 16 print "$name: $namen"; 17 print "my_sub: ", &my_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 46. 1 #!/usr/bin/perl -w 2 use strict; 3 4 our $name; # $name: Crisp 5 $name = "Crisp"; # my_sub: Fry 6 # show_name: Crisp 7 sub my_sub { 8 my $name = "Fry"; 9 return show_name($name); 10 } 11 12 sub show_name { 13 return shift || $name; 14 } 15 16 print "$name: $namen"; 17 print "my_sub: ", &my_sub(), "n"; 18 print "show_name: ", &show_name(), "n";
  • 47. “In languages with lexical scope (also called static scope), name resolution depends on the location in the source code and the lexical context, which is defined by where the named variable or function is defined.” Wikipedia
  • 48. Benefits of Static Scope 1. Possible to optimize at compile time 2. Easier for developers to read 3. JavaScript and pretty much all languages use it
  • 49. 1 {{! app/templates/index.hbs }} 2 <h2>{{name}} Menu</h2> 3 <ul> 4 {{#view 'localized-menu' model}} 5 <li>{{name}}: {{model.price}}</li> 6 {{/view}} 7 </ul> Ember 1.x
  • 50. 1 {{! app/templates/index.hbs }} 2 <h2>{{name}} Menu</h2> 3 <ul> 4 {{#view 'localized-menu' model}} 5 <li>{{name}}: {{model.price}}</li> 6 {{/view}} 7 </ul> Ember 1.x • Index controller • Index controller model • New context from localized-menu • Helper Dynamic
  • 51. 1 {{! app/templates/index.hbs }} 2 <h2>{{name}} Menu</h2> 3 <ul> 4 {{#view 'localized-menu' model}} 5 <li>{{name}}: {{model.price}}</li> 6 {{/view}} 7 </ul> Ember 1.x Ember 2.x 1 {{! app/templates/index.hbs }} 2 <h2>{{model.name}} Menu</h2> 3 <ul> 4 {{#each model.snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul>
  • 52. 1 {{! app/templates/index.hbs }} 2 <h2>{{model.name}} Menu</h2> 3 <ul> 4 {{#each model.snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul> Ember 2.x • Property on packet • Helper Static
  • 53. 1 {{! app/templates/index.hbs }} 2 <h2>{{model.name}} Menu</h2> 3 <ul> 4 {{#each model.snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul> Ember 2.x • Property on packet • Helper Static
  • 54. 1 {{! app/templates/index.hbs }} 2 <h2>{{model.name}} Menu</h2> 3 <ul> 4 {{#each model.snacks as |packet|}} 5 <li>{{packet.name}}: {{packet.price}}</li> 6 {{/each}} 7 </ul> 1 function buildIndex(model) { 2 let html = `<h2>${model.name} Menu</h2>`; 3 html += '<ul>'; 4 model.snacks.forEach(packet => { 5 html += `<li> 6 ${packet.name}: ${packet.price} 7 </li>`; 8 }); 9 html += '</ul>'; 10 return html; 11 } Ember 2.x
  • 55. Creating a template system with static scoping is an intentional goal of HTMLBars/Glimmer, and directs the underlying architecture.
  • 56.
  • 57. Tools for Static Scope Closures
  • 58. Closures 1 function generateSayName() { 2 let name = 'Chips'; 3 return function() { 4 alert(name); 5 }; 6 } 7 8 var sayName = generateSayName(); 9 10 console.log(sayName()); // alerts: Chips
  • 59. 1 function generateSayName() { 2 let name = 'Chips'; 3 return function() { 4 alert(name); 5 }; 6 } 7 8 var sayName = generateSayName(); 9 10 console.log(sayName()); // alerts: Chips Closures
  • 60. Ember Actions as Closures 1 {{#with (action 'alert' name) as |sayName|}} 2 <button {{action sayName}}>Say the name!</button> 3 {{/with}}
  • 61. Ember Actions as Closures 1 {{! app/templates/components/generate-say-name.hbs }} 2 {{yield (action 'alert' name)}} 1 {{! app/templates/index.hbs }} 2 {{#generate-say-name name='Chip' as |sayName|}} 3 <button {{action sayName}}>Say the name!</button> 4 {{/generate-say-name}}
  • 62. Ember Actions as Closures 1 {{! app/templates/components/generate-say-name.hbs }} 2 {{yield (hash 3 sayBritish=(action 'alert' 'Crisp') 4 sayAmerican=(action 'alert' 'Chip') 5 )}} 1 {{! app/templates/index.hbs }} 2 {{#generate-say-name as |ux|}} 3 <button {{action ux.sayBritish}}>Say the name!</button> 4 {{/generate-say-name}}
  • 63. Ember actions are just JavaScript functions.
  • 64. Ember Components as Closures 1 {{! app/templates/index.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{#ux.sayBritish}}Say the name!{{/ux.sayBritish}} 4 {{/generate-say-name}} 1 {{! app/templates/components/generate-say-name.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-name-button' name='Crisp') 4 sayAmerican=(component 'say-name-button' name='Chip') 5 )}}
  • 65. Pods, Local Lookup, and Closures bit.ly/pods-local-lookup speakerdeck.com/rwjblue/a-tale-of-two-pods
  • 66. Pods 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 routes/ 6 index/ 7 template.hbs
  • 67. Pods 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 routes/ 6 index/ 7 template.hbs 1 {{! app/routes/index/template.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}} 4 {{/generate-say-name}}
  • 68. Pods 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 routes/ 6 index/ 7 template.hbs 1 {{! app/routes/index/template.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}} 4 {{/generate-say-name}}
  • 69. 1 {{! app/components/generate-say-name/template.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-name-button' name='Crisp') 4 sayAmerican=(component 'say-name-button' name='Chip') 5 )}} Pods 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 routes/ 6 index/ 7 template.hbs
  • 70. 1 {{! app/components/generate-say-name/template.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-name-button' name='Crisp') 4 sayAmerican=(component 'say-name-button' name='Chip') 5 )}} Pods 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 routes/ 6 index/ 7 template.hbs
  • 71. 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 say-name-button/ 6 template.hbs 7 routes/ 8 index/ 9 template.hbs 1 {{! app/components/generate-say-name/template.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-name-button' name='Crisp') 4 sayAmerican=(component 'say-name-button' name='Chip') 5 )}} Pods
  • 72. 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs 1 {{! app/components/generate-say-name/template.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-name-button' name='Crisp') 4 sayAmerican=(component 'say-name-button' name='Chip') 5 )}} Local Lookup
  • 73. 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs 1 {{! app/components/generate-say-name/template.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-name-button' name='Crisp') 4 sayAmerican=(component 'say-name-button' name='Chip') 5 )}} Local Lookup
  • 74. 1 {{! app/routes/index/template.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}} 4 {{/generate-say-name}} 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs Local Lookup
  • 75. 1 {{! app/routes/index/template.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}} 4 {{/generate-say-name}} 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs Local Lookup
  • 76. 1 {{! .../say-name-button/template.hbs }} 2 <button {{action 'alert' name}}>{{yield}}</button> 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs Local Lookup
  • 77. 1 {{! .../say-name-button/template.hbs }} 2 <button {{action 'alert' name}}>{{yield}}</button> 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs Local Lookup
  • 78. 1 {{! app/routes/index/template.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{#ux.sayBritish}}Say the Name{{/ux.sayBritish}} 4 {{/generate-say-name}} 1 app/ 2 components/ 3 generate-say-name/ 4 template.hbs 5 components/ 6 say-name-button/ 7 template.hbs 8 routes/ 9 index/ 10 template.hbs Local Lookup
  • 80. Tools for Static Scope Partial Applications
  • 81. Partial Application 1 function generateSayName() { 2 let name = 'Chips'; 3 return function(honorific) { 4 alert(`${honorific} ${name}`); 5 }; 6 } 7 8 var sayName = generateSayName(); 9 10 console.log(sayName('Mr.')); // logs: Mr. Chips
  • 82. 1 function generateSayName() { 2 let name = 'Chips'; 3 return function(honorific) { 4 alert(`${honorific} ${name}`); 5 }; 6 } 7 8 var sayName = generateSayName(); 9 10 console.log(sayName('Mr.')); // logs: Mr. Chips Partial Application
  • 83. 1 function generateSayName() { 2 let name = 'Chips'; 3 return function(honorific) { 4 alert(`${honorific} ${name}`); 5 }; 6 } 7 8 var sayName = generateSayName(); 9 10 console.log(sayName('Mr.')); // logs: Mr. Chips Partial Application
  • 84. Ember Actions with Partial Application 1 {{! app/templates/index.hbs }} 2 {{#generate-say-name as |sayName|}} 3 <button {{action sayName 'Mr.'}}>Say the name!</button> 4 {{/generate-say-name}} 1 {{! app/templates/components/generate-say-name.hbs }} 2 {{yield (action 'alert' 'Crisps')}}
  • 85. Ember Actions with Partial Application 1 {{! app/templates/index.hbs }} 2 {{#generate-say-name as |sayName|}} 3 <button {{action sayName 'Mr.'}}>Say the name!</button> 4 {{/generate-say-name}} 1 {{! app/templates/components/generate-say-name.hbs }} 2 {{yield (action 'alert' 'Crisps')}} 1 actions: { 2 alert(name, honorific) { 3 console.log(`${honorific} ${name}`); 4 } 5 }
  • 86. Ember Components with Partial Application 1 {{! app/templates/components/generate-say-name.hbs }} 2 {{yield (hash 3 sayBritish=(component 'say-button-name' honorific='MP') 4 sayAmerican=(component 'say-button-name' honorific='Rep') 5 )}} 1 {{! app/templates/index.hbs }} 2 {{#generate-say-name as |ux|}} 3 {{ux.sayBritish name='Chips'}} 4 {{ux.sayAmerican honorific='Mr.' name='Fry'}} 5 {{/generate-say-name}} 1 {{! app/templates/components/say-button-name.hbs }} 2 <button {{action 'alert' name honorific}}>Say the Name</button>
  • 87. Tools for Static Scope Recursion?! emberjs.jsbin.com/fubutusejo/1/edit?html,js,output
  • 88. Ember templates have the scoping rules and consistency of a real language.
  • 89. Develop using the patterns and tools you would use in a real language.