SlideShare ist ein Scribd-Unternehmen logo
1 von 90
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 

Kürzlich hochgeladen (20)

Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

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.