are digital gardens blogs

This commit is contained in:
Wouter Groeneveld 2021-10-06 11:51:37 +02:00
parent 5721cb1a51
commit 7d533545aa
7 changed files with 171 additions and 130 deletions

View File

@ -1,40 +1,33 @@
---
title: "Hi, Im Wouter Groeneveld"
subtitle: "And I'm currently a level 35 multiclass ..."
subtitle: ""
bigimg: About Me.jpg
accent: purple
disableComments: true
---
## ... Baker
And I'm currently a level {{< lvl >}} multiclass ...
* I hold a [professional bread baker's degree](/post/learning-to-become-a-baker/) so naturally I love to think of myself as a real baker. I highly respect the craft and enjoy kneading dough with my hands.
* I specialize in _sourdough bread_, as you can read at my [bread baking blog](https://redzuurdesem.be). I love to rekindle the interest in sourdough by organizing workshops.
* I've written a book on [the science of sourdough bread](https://redzuurdesem.be/het-boek).
### ... Baker
## ... Researcher
I hold a professional bread baker's degree so naturally I love to think of myself as a real baker. I highly respect the craft and enjoy kneading dough with my hands. I specialize in _sourdough bread_, as you can read at my [bread baking blog](https://redzuurdesem.be). I've written a book on [the science of sourdough bread](https://redzuurdesem.be/het-boek) (in Dutch).
* I am a PhD researcher at the [Faculty of Engineering Technology](https://iiw.kuleuven.be/english), KU Leuven.
* My academic research focuses on identifying and amplifying non-technical skills in software engineering education, primarily targetting _creative problem solving_.
* I mainly employ qualitative methods and prefer to mix disciplines such as computing education, cognitive psychology, and architecture.
### ... Researcher
## ... Programmer
I am a PhD researcher at the Faculty of Engineering Technology, KU Leuven. My academic research focuses on identifying and amplifying non-technical skills in software engineering education, primarily targetting _creative problem solving_. I sometimes [blog about my work](/tags/phd).
- I'm an experienced software engineer and took on various roles from agile coaching to technical lead. I hold a Master of Computer Science from [Hasselt Univeristy](https://www.uhasselt.be/edm). Take a look at my [<svg class='icon'><use xlink:href='#github'></use></svg>Github account](https://github.com/wgroeneveld).
- Im a heavy Test Driven Development fan and I bark at those who dont. I taught agile software engineering techniques in both industry and academia.
- I dislike specializing in one particular programming language: the more there is to learn, the better, although I prefer dynamic languages.
### ... Programmer
I'm an experienced software engineer and took on various roles from agile coaching to technical lead. I hold a Master of Computer Science. I also dabble in open source through my [<svg class='icon'><use xlink:href='#github'></use></svg>Github](https://github.com/wgroeneveld) account. Im a big Test Driven Development advocate. I teach software engineering techniques in both industry and academia.
## ... Writer
### ... Writer
* I'm a [fountain pen addict](/post/fountain-pens-first-look/) and avid [<svg class='icon icon-text'><use xlink:href='#book'></use></svg>journaler](/post/journaling-in-practice/). I love jotting down stuff.
* [This blog](/post) is the ideal place to write down my _freshly baked thoughts_ about virtually anything, primarily intended to amuse myself, and hopefully also others.
* Oh, and as said, I've published a book on [the science of sourdough bread](https://redzuurdesem.be/het-boek) and occasionally take part in [National Novel Writing Months](https://nanowrimo.org) - with varying results.
I like fountain pens and [<svg class='icon icon-text'><use xlink:href='#book'></use></svg>journaling](/tags/journaling/). I love jotting down stuff and possibly converting that into blog posts, academic articles, books, or any other medium where I can express my enthusiasm.
## ... Teacher
### ... Teacher
* Transforming knowledge into well-digestible material is my mission. As they say: _the best way to learn something is to teach it_ - I couldn't agree more.
* Besides various formal teaching assignments at KU Leuven, I've also coached software developers in different companies, and occasionally organize bread baking workshops.
Transforming knowledge into well-digestible material is my mission. As they say: _the best way to learn something is to teach it_ - I couldn't agree more. Besides various formal teaching assignments at KU Leuven, I've also coached software developers in different companies, and occasionally organize bread baking workshops.
---

View File

@ -10,11 +10,11 @@ date = "2013-10-01"
categories = ["programming"]
+++
# Javascript Inleiding
# Javascript Inleiding
### Primitives
### Primitives
#### Soorten
#### Soorten
In javascript zijn er slechts 3 primitives:
@ -24,14 +24,14 @@ In javascript zijn er slechts 3 primitives:
Primitives zijn **immutable**! Toekennen van properties maakt ook een tijdelijk object aan, dus dit heeft geen nut.
##### Soort afchecken
##### Soort afchecken
Aangezien JS loosely typed is, kunnen we nooit weten wat er nu in `var variabele;` steekt op een bepaald moment in de code.<br/><br/>
Om dit op te lossen kan men `typeof` gebruiken, een functie die een string teruggeeft wat het type van die variabele is.
Typeof retourneert in het geval van een object, de string `object`, in alle andere gevallen de bovenstaande primitive namen.
#### Object coercing
#### Object coercing
-> *(Lees eerst het stuk over objecten etc aub!)*
@ -71,7 +71,7 @@ Als we weten dat een object aangemaakt wordt zodra we een property oproepen, vra
Zie [Mozilla MDC Docs: JS Reference: Number](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Number) voor wat mogelijke functies zijn op `Number`.
### Objecten en Functies
### Objecten en Functies
Douglas Crockford:
@ -83,7 +83,7 @@ Een *functie* in JS kan net zoals andere waarden toegekend worden aan een variab
Een object bevat properties. Een functie is een rij van expressies die één waarde retourneert voor dezelfde input te evalueren. Bekijk een "functie" als zijn mathematische beschrijving: `f(x)`.
#### Object Literals
#### Object Literals
Een object definiëren gaat heel makkelijk:
@ -110,7 +110,7 @@ var Ezel = {
Hier wordt een object door middel van een **literal** gedefiniëerd. De correcte manier om de ezel te laten balken is `Ezel.balk()`. Merk op dat `Ezel` een gewoon object met wat simpele properties is, bekijk het als een map. Dit is een instantie van `Object`: `typeof Ezel` retourneert dit.
##### JSON en Object Literals
##### JSON en Object Literals
[JSON](http://www.json.org/js.html) ((JavaScript Object Notation)) is een subset van JavaScript, dus door de JS Compiler op te roepen met `eval()` is het heel eenvoudig om JSON Strings te evalueren. Een JSON Object is in feite een JS Object Literal:
@ -127,7 +127,7 @@ Dat object kan via een string opgebouwd worden door `eval()` te gebruiken, maar
Om de omgekeerde weg uit te gaan, van object naar string, gebruik `JSON.stringify()`. Meer uitleg, zie bovenstaande link.
#### Functie Literals
#### Functie Literals
Een functie definiëren gaat op drie manieren:
@ -161,7 +161,7 @@ Ezel.prototype.constructor
De correcte manier om de ezel te laten balken is `new Ezel().balk()`.<br/><br/>
Meer info over hoe `new` werkt om de ezel instance de poten en de balk functie toe te kennen: zie inheritance.
##### Functies zijn objecten
##### Functies zijn objecten
> Functions are first class Objects!
@ -174,7 +174,7 @@ Function.prototype.__proto__ == Object.prototype;
Dus functies zijn *ook* associatieve maps, dus `(function(){}).bla = 3;` werkt perfect! Zie scoping, deel "Object/Class Member variables".
##### De kracht van closures
##### De kracht van closures
In Javascript is élke functie een *closure*! In sommige andere talen kan enkel een closure "deep bindings" uitvoeren (= scope chain bijhouden, zie scoping deel), of een functie opnieuw retourneren. In JS is er geen verschil tussen een literal function en een gewone, buiten de notatie - een literal bind een anonieme functie aan een variabele. Zoiets kan dus perfect:
@ -196,7 +196,7 @@ a()()() // 60
Merk op dat de `()` operator een functie uivoert, en hier alles 3x genest is, maar toch de binnenste functie een referentie naar `aGetal` kan gebruiken, gedefiniëert in de buitenste functie! Lees hierover meer in het scoping gedeelte.
##### Declaratie van functie literals
##### Declaratie van functie literals
In javascript worden variabelen die met `var` gedeclareerd worden **altijd** vooraan geplaatst, ook impliciet. Dit wil zeggen dat wanneer ik een function literal definieer, eigenlijk het volgende gebeurt:
@ -224,9 +224,9 @@ Dat wil zeggen dat wanneer je twee keer x probeert toe te kennen aan een getal
!! Uitzondering: een formeel argument met naam `arguments` heeft voorrang op lang-defined `arguments`. Bad practice...
##### Itereren over properties van objecten #####
##### Itereren over properties van objecten
Vergeet niet dat in Javascript alle objecten (zowel object literals als instanties van functies) zich gedragen als een {{< wp "Associative array" >}} - en dat we dus ook kunnen lopen over alle keys:
Vergeet niet dat in Javascript alle objecten (zowel object literals als instanties van functies) zich gedragen als een Associative array - en dat we dus ook kunnen lopen over alle keys:
```javascript
var N = { one: 1, two: 2 };
@ -237,7 +237,7 @@ for(key in N) {
Om de value van een bepaalde key op te halen kan je natuurlijk ook `eval('N.' + key)` gebruiken - alle wegen leiden tot Rome...
##### Controleren of een key in een object/array beschikbaar is
##### Controleren of een key in een object/array beschikbaar is
Dit kan op enkele manieren:
@ -270,13 +270,13 @@ f(1, 2) // == 3
Indien er geen argumenten gespecifiëerd zijn, zijn ze allemaal *optioneel*! Dit wil zeggen dat een functie aangeroepen kan worden zonder het aantal argumenten 100% te laten overeen komen.
###### anonymus functions en recursie ######
###### anonymus functions en recursie
`arguuments` heeft nog een speciale property: `arguments.callee(...)` dat de huidige functie voorstelt, hiermee kan je jezelf aanroepen!
!! Dit gaat een syntax error geven bij ECMA Script standaard 5 in *strict* mode
###### verplicht alle argumenten invullen ######
###### verplicht alle argumenten invullen
```javascript
function f(x, y, z) {
@ -289,7 +289,7 @@ f(1, 2) // == 3
Het is natuurlijk makkelijker om `!= 3` hardcoded te plaatsen, maar dit kan extracted worden naar een aparte functie.
###### Function overloading ######
###### Function overloading
Overloading bestaat niet in JS aangezien de tweede definitie van de functie de eerste overschrijft (de property "functienaam" in het object, zeg maar). <br/><br/>
Het is wel mogelijk om één functie te maken die delegeert, zie http://ejohn.org/blog/javascript-method-overloading/
@ -354,11 +354,11 @@ function count(one, two, three) {
!! `undefined` is een window-scope variabele die initiëel de value `undefined` heeft, dit is dus géén keyword, pas op!
# Async coding in JS
# Async coding in JS
[Asynchronous programming in JS: APIs interview](http://www.infoq.com/articles/surviving-asynchronous-programming-in-javascript) (infoQ)
## Het probleem
## Het probleem
Alle events in javascript zijn asynchroon. Dat wil zeggen dat we geen idee hebben wanneer de eigenlijke code uitgevoerd is, en we een **callback closure** moeten meegeven, die verder werkt als de asynchrone code uitgevoerd is.
@ -368,7 +368,7 @@ Dit is oké voor 1-2 asynchrone calls. Maar stel u voor dat we 4+ async calls mo
* animaties (jQuery ea)
* AJAX calls (REST, naar domein logica, bewaren, opvragen, veranderen, ...)
### Een integratietest schrijven in JS
### Een integratietest schrijven in JS
In *Java* kunnen we gewoon wat methods oproepen die data persisteert, daarna de eigenlijke *asserts* schrijven en eventueel in de `@After` met JUnit data cleanup uitvoeren:
@ -405,7 +405,7 @@ $.ajax('/domain/obj/store', {
Dus een callback wrappen in een callback wrappen in een callback.
#### Async event loop hulpjes
#### Async event loop hulpjes
Zie ook [Philip Roberts: Help, I'm stuck in an event-loop](http://vimeo.com/96425312)
@ -413,7 +413,7 @@ Zie ook [Philip Roberts: Help, I'm stuck in an event-loop](http://vimeo.com/9642
Tooltje om event loop te visualiseren zodat je ziet wat er gebeurt. Breaken in chrome helpt natuurlijk ook, gewoon naar de call stack kijken...
#### Asynchroon testen in Jasmine
#### Asynchroon testen in Jasmine
Met **Jasmine** is het (beperkt) mogelijk om te wachten tot dat een stukje werk uitgevoerd is voordat de assertions afgegaan worden. <br/><br/>
Dit kan op de volgende manier:
@ -447,7 +447,7 @@ Pitfalls:
De assertion functiepointers die meegegeven worden met `runs()` worden intern opgeslaan en bijgehouden totdat de closure van `waitsFor()` `true` retourneert. Daarna wordt ook alles pas meegegeven met de Jasmine reporter (logging, output etc). Redelijk omslachtig, aangezien 3+ async calls dan `waitsFor()` moeten wrappen. Geen oplossing.
##### Asynchroon testen met QUnit #####
##### Asynchroon testen met QUnit
```javascript
asyncTest("should be green, right??", function() {
@ -468,7 +468,7 @@ Pitfalls:
* Ge moet een speciale test method gebruiken, `asyncTest()`
* Ge moet na uw assertions `start()` aanroepen (??)
##### De oplossing #####
##### De oplossing
https://github.com/willconant/flow-js e.a. (of iets zelfgemaakt in die aard).
@ -503,7 +503,7 @@ Pitfalls:
flow.js geeft het resultaat van closure1 mee als argument aan closure2 (via `arguments`) en zo maar door, dat is mega handig.
##### Synchrone code code combineren met asynchrone in flow.js #####
##### Synchrone code code combineren met asynchrone in flow.js
Enige minpunt is dat de callback `this()` moet expliciet aangeroepen worden om van closureX naar closureY over te stappen! <br/><br/>
Los dit op met een utility functie:
@ -532,11 +532,11 @@ flow.exec(
);
```
##### In een asynchrone closure parallel werken #####
##### In een asynchrone closure parallel werken
Gebruik `this.MULTI()` als callback ipv `this` (zie voorbeeld hieronder)
##### flow.js combineren met Jasmine #####
##### flow.js combineren met Jasmine
Om de smeerlapperij van `waitsFor()` weg te werken kunnen we ook `flow.exec` gebruiken.
@ -597,7 +597,7 @@ describe("plaatsen domein", function() {
Merk op dat de closure meegeven in `then()` (slechts 1 mogelijk voor assertions) als **argument** het resultaat van de laatste closure in `when()` meekrijgt!
##### jQuery 1.6: Deferred en piping #####
##### jQuery 1.6: Deferred en piping
Vanaf **jQuery 1.6** is het mogelijk om met `$.Deferred` te werken, dat het mogelijk maakt om een closure uit te voeren op het moment dat "werk" gedaan is. Met werk bedoelen we:
@ -605,7 +605,7 @@ Vanaf **jQuery 1.6** is het mogelijk om met `$.Deferred` te werken, dat het moge
2. http: `.ajax` ea
3. custom code die zelf een `$.Deferred` object retourneren
##### Promising stuff #####
##### Promising stuff
Alle async operaties worden aan een *queue* toegevoegd van het jQuery element zelf. Je kan op eender welk moment vragen aan dat queue object, dat wanneer alle items zijn verwerkt er iets speciaals uigevoerd wordt:
@ -617,7 +617,7 @@ $('#blink').fadeOut().promise().done(function() {
Dit kan dus ook met `$.ajax`.
##### Zelf Deferred code schrijven #####
##### Zelf Deferred code schrijven
Maak een deferred object aan door `$.Deferred()` aan te roepen. Op dat moment kan je `done()` hierop zoals in het vorige voorbeeld aanroepen. Bijvoorbeeld:
@ -637,7 +637,7 @@ startStuff().done(function() {
});
```
##### Multiple elements in queue: piping #####
##### Multiple elements in queue: piping
Stel dat eerst element #1 animatie triggert, dan #2, en daarna nog logica dient te gebeuren. Dit kan ook met `$.Deferred`, door `.pipe()` te gebruiken om verder te breiden aan de queue.
@ -660,11 +660,11 @@ $("button").bind( "click", function() {
:exclamation: Pas op, in de `.pipe()` functie moet een nieuw **promised object** geretourneerd worden! Dat nieuw object wordt als return value van de vorige pipe gebruikt. Op die manier wordt er dus *chaining* toegepast.
# Javascript Inheritance
# Javascript Inheritance
> JavaScript uses prototypal inheritance. This means that Javascript does not distinguish between classes/prototypes and instances and, therefore, we can add our desired behavior directly to the instance.
## "new" operator
## "new" operator
Zie http://unitstep.net/blog/2008/01/24/javascript-and-inheritance/ <br/><br/>
Gegeven de volgende functie:
@ -706,7 +706,7 @@ Eender welke functie heeft een `prototype`. Een "lege" functie bevat een dynamis
(function(){}).prototype
```
##### Gewenst gedrag - wat waar plaatsen #####
##### Gewenst gedrag - wat waar plaatsen
* Indien ik een functie of een variabele heb die anders kan zijn naargelang de implementatie (definiëer de "naamgeving"), plaats deze dan in de **constructor** functie.
* Indien ik een functie of een variabele heb die specifiek voor die functie is en niet gaat veranderen, plaats deze dan **in het concreet object** via `this.`.
@ -714,7 +714,7 @@ Eender welke functie heeft een `prototype`. Een "lege" functie bevat een dynamis
Typisch bevatten constructor functies ook *geen* return waarden ((dit retourneert dus impliciet `undefined`)) - we gebruiken deze functies toch altijd in combinatie met de `new` operator, dus kennen de nieuwe instantie van het object direct toe aan een variabele.
##### prototype gebruiken als inheritance #####
##### prototype gebruiken als inheritance
-> Meer informatie inclusief grafen met uitgebreide uitleg hoe prototype en constructors werken: zie http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
@ -773,7 +773,7 @@ dier.aantalPoten = 2;
new Ezel().aantalPoten ###### 4; // false
```
##### Properties overriden #####
##### Properties overriden
Prototypal inheritance werkt omdat JS bij elke property lookup kijkt in welk object die referentie gedefiniëerd is. Is dat het huidig object, neem dan die waarde. Indien neen, kijk in het `prototype` object. Indien neen, kijk in het `prototype` object van dat object, en zo maar door tot op `Object` niveau. We kunnen zo ook een property van een prototype zelf overriden, door ander gedrag te definiëren, of zelfs de super aan te roepen:
@ -787,7 +787,7 @@ Ezel.prototype.eetIets = function() {
}
```
##### Built-in JS types extenden #####
##### Built-in JS types extenden
:exclamation: Extend **nooit** `Object.prototype`! Waarom? Omdat Eender welk object een instantie van `Object` is, dus zijn prototype heeft, en met een `for(x in prop)` deze property nu ineens toegankelijk is voor elk object. Een leeg object `{ }` wordt verwacht géén properties te hebben!
@ -798,7 +798,7 @@ for(x in {}) {
}
```
##### Checken op inheritance #####
##### Checken op inheritance
Met Javascript kan men door middel van `typeof` controleren van welk type een variabele is. Dat komt neer op:
@ -815,9 +815,9 @@ ezeltje instanceof Ezel == true
new Vierpotige() instanceof Ezel == false
```
##### Zelf inheritance afchecken met prototype #####
##### Zelf inheritance afchecken met prototype
###### met constructors ######
###### met constructors
Dit is een zeer beperkte manier dat geen rekening houdt met "inheritance":
@ -831,7 +831,7 @@ instanceOf(Ezel, Vierpotige) // true
Aangezien elk object een `.constructor` property heeft die afgeleid werd vanuit de constructor functie die aangeroepen werd, kan men op deze manier een simpele check afwegen. Een praktischer voorbeeld is `(typeof (new Date()) ###### object) && (new Date().constructor ###### Date)`.
###### met __proto__ ######
###### met __proto__
Het `instanceof` keyword kijkt natuurlijk naar de `prototype` properties van beide objecten om te controleren of object a van object b komt. Dit kan men ook zelf doen:
@ -854,11 +854,11 @@ De betere oplossing: **`isPrototypeOf()`**! Zie magic properties.
:exclamation: **`_ _proto_ _` is een __instance__ property, `.prototype` een constructor function property**
###### met properties ######
###### met properties
Door `hasOwnProperty()` te gebruiken kan je nagaan of een property overgenomen is of niet. Vanaf JS 1.5.
##### call als inheritance #####
##### call als inheritance
De klassieke inheritance structuur zoals in Java en C++ kan beter benaderd worden door `call` te gebruiken. Herbekijk onze ezels:
@ -883,7 +883,7 @@ ezeltje.eetIets(); // aha! outputs omnom
Door als eerste statement in de constructor functie van `Ezel` een `call` te plaatsen naar onze "parent", *kopiëren* we alle keys en values die daarin gedefiniëerd staan. In tegenstelling tot prototypal inheritance kost dit dus veel meer geheugengebruik, en is dit beperkter om uit te breiden. We linken eigenlijk impliciet twee functies aan elkaar door waarden over te nemen, maar iets aanpassen aan `Vierpotige` gaat de `Ezel` op geen ekele manier doen veranderen.
##### prototypal inheritance toepassen #####
##### prototypal inheritance toepassen
In plaats van `new` overal te gebruiken zonder te weten wat hierachter ligt, kan men `create` ook gebruiken:
@ -900,7 +900,7 @@ newObject = Object.create(oldObject);
Zie http://javascript.crockford.com/prototypal.html
##### Een minder verbose manier om extra properties te definiëren #####
##### Een minder verbose manier om extra properties te definiëren
Zie http://howtonode.org/prototypical-inheritance -
@ -918,7 +918,7 @@ Object.defineProperty(Object.prototype, "spawn", {value: function (props) {
Op die manier kan je `BaseObj.spawn({'extraProp': 'extraValue'});` gebruiken, zonder de relatieve verbose manier van extra properties te moeten gebuiken die `Object.create` [handhaaft](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create#Classical_inheritance_with_Object.create).
##### Prototype JS en Class.create #####
##### Prototype JS en Class.create
Javascript frameworks proberen altijd inheritance makkelijker te maken voor klassieke OO developers door functies te modelleren als klassen. In [Prototype JS](http://www.prototypejs.org/api/class) kan men zoiets doen:
@ -1020,9 +1020,9 @@ Als dit echt nodig is kan men zoiets zelf implementeren door weer te loopen via
Zie Mozilla Dev center: [Details of the Object Model](https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model#No_Multiple_Inheritance)
# Javascript Scoping
# Javascript Scoping
### Toplevel Scope
### Toplevel Scope
Een stuk Javascript in een HTML pagina, zonder eender welke functie te definiëren, werkt altijd op **top-level scope**. Dat stelt het `window` object voor, waar we ook resolutie gegevens en dergelijke kunnen uithalen. Dus simpele variabelen declareren om in HTML te kunnen gebruiken werkt altijd op de globale scope:
@ -1033,7 +1033,7 @@ window.customerEmail // what did I do?? (null@null.com if unknown IDs)
Om te vermijden dat we alles op het `window` object "dumpen", schrijven we nette functies die zaken zoals tijdelijke variabelen en private stukken code *encapsuleren*.
#### Variabele declaratie
#### Variabele declaratie
Variabelen definiëren gaat met `var` (zoals hierboven), máár *globale* (window-scope) variabelen kunnen gedeclareerd worden zonder dit. Pas hiermee op:
@ -1124,13 +1124,13 @@ function foo() {
}
```
##### Scope chain #####
##### Scope chain
Elke JS Executie context heeft een **scope chain** toegekend. Dit is een lijst van objecten waar de interpreter door gaat om een variabele x op te kunnen zoeken (Dit proces heet *variable name resolution*). Men begint met de huidige context van de functie die opgeroepen wordt. Indien variabele x daar niet gedefiniëerd is, ga een scope hoger, en zo voort.
In *top-level* JS (op window scope) bevat de scope chain slechts één object, het "globaal" object. (`window`)
##### Event handler scope chain #####
##### Event handler scope chain
Bij het uitvoeren van events in de DOM Tree zitten er buiten `window` nog enkele andere objecten op de scope chain: het object dat het event zelf triggerde. Het is dus mogelijk om rechtstreeks vanuit een `onclick` event van een `input` tag, een ander `form` element aan te spreken zonder dit eerst te resolven via de klassieke `getElementById()`:
@ -1187,7 +1187,7 @@ function Iets(e) {
```
##### Scope tijdelijk aanpassen #####
##### Scope tijdelijk aanpassen
```javascript
with(window.screen) {
@ -1227,7 +1227,7 @@ Zodra we `this` gebruiken om members in een constructor functie te steken wordt
Merk op dat we aan `privateMember` kunnen zonder `this` te gebruiken om naar iets te refereren. Dit komt omdat die members in de context van het object zitten.<br/><br/>
Een probleem dat zich voordoet is dat de `this` pointer binnen private functions natuurlijk weer gereset wordt tot op `window` scope. Om dit op te lossen kunnen we een private variabele voorzien die refereert naar `this`, daarvoor dient `me`.
###### Private, Public en prototype functies ######
###### Private, Public en prototype functies
Een **private** functie is een functie die in de constructor functie gedefiniëerd is als *member variabele*, en dus geldig is binnen de context van die functie. <br/><br/>
Een **privileged** functie is een functie die in de constructor functie gedefiniëerd is met de *this accessor*. Deze functies kunnen private functies aanroepen omdat ze binnen de context van de constructor functie leven, en zijn ook aanroepbaar van buitenaf.<br/><br/>
@ -1324,7 +1324,7 @@ new Ezel().balk.call(); // iaia met mijn 100 poten
Hoezo 100? `this` wordt dan `window`, de hoogst mogelijke scope, en daar is net toevallig ook een poten variabele op gedefiniëerd. Als dat niet zo was gaf dit als output "iaia met mijn undefined poten".
##### Impliciete unbound objecten #####
##### Impliciete unbound objecten
Het vorige voorbeeld toont aan hoe je expliciet `this` kan "unbinden". Dit gebeurt ook regelmatig intern impliciet, bijvoorbeeld met `setTimeout` of met events zoals `blabla.onclick`. <br/><br/>
De oplossing hiervoor is **closures** gebruiken. Bekijk dit voorbeeld:
@ -1369,7 +1369,7 @@ function SomeClass() {
new SomeClass().startLooping();
```
##### loop closures #####
##### loop closures
Een ander voorbeeld waar het mis kan gaan (ref. http://trephine.org/t/index.php?title=JavaScript_loop_closures !):
@ -1457,11 +1457,11 @@ VS
```
# Testing JS Code
# Testing JS Code
## Testen schrijven
## Testen schrijven
### Klassieke Unit testen
### Klassieke Unit testen
Frameworks gebruiken zoals jQuery's [QUnit](http://docs.jquery.com/Qunit) die het makkelijk maken modulair te testen:
@ -1481,7 +1481,7 @@ assertEqual('out', f('in'));
:exclamation: Vereist `Prototype JS`, en `JsUnit` om de `assert` functions te kunnen gebruiken
### Gedrag testen met Jasmine
### Gedrag testen met Jasmine
Inspiratie van de *Ruby* community gehaald, met name **RSpec**-based.<br/><br/>
Frameworks gebruiken zoals [Jasmine](http://pivotal.github.com/jasmine/) ((Niet afhankelijk van andere JS Frameworks, vereist geen DOM dus geen Envjs nodig serverside!)):
@ -1511,11 +1511,11 @@ Zwakheden:
Betere matchers speciaal voor jQuery ea zijn beschikbaar: https://github.com/velesin/jasmine-jquery
##### Aynschrone code testen
##### Aynschrone code testen
Zie async stuff
##### Jasmine integreren met jsTestDriver
##### Jasmine integreren met jsTestDriver
Zie http://skaug.no/ingvald/2010/10/javascript-unit-testing.html
@ -1525,7 +1525,7 @@ Het kan ook handig zijn om een **Junit XML Reporter** te gebruiken om bijvoorbee
:exclamation: Integratie met Hudson, EnvJS en Rhino ea: zie eigen junit test runner: https://github.com/wgroeneveld/jasmine-junit-runner
### Andere JS Test frameworks
### Andere JS Test frameworks
Interessante links:
@ -1533,11 +1533,11 @@ Interessante links:
2. [Stack overflow: Looking for a better Javascript unit test tool](http://stackoverflow.com/questions/300855/looking-for-a-better-javascript-unit-test-tool)
3.
## Testen automatiseren
## Testen automatiseren
### Distributed testing in-browser
### Distributed testing in-browser
#### jsTestDriver
#### jsTestDriver
http://code.google.com/p/js-test-driver/
@ -1563,7 +1563,7 @@ java -jar test/JsTestDriver-1.2.2.jar <br/>
Dit neemt aan dat de server reeds gestart is, kan met een shell script op de Hudson server bak: `java -jar test/JsTestDriver-1.2.2.jar --port 4223`.
#### JsUnit Server
#### JsUnit Server
http://www.jsunit.net/documentation/index.html
@ -1572,13 +1572,13 @@ Wat doet dit?
* Afhankelijk van `Prototype JS` om asserts uit te voeren
* Integratie met ant zeer eenvoudig
#### TestSwarm
#### TestSwarm
Zie http:*swarm.jquery.org/ en https:*github.com/jquery/testswarm/wiki
### Headless testen
### Headless testen
#### Mogelijkheid 1: EnvJS
#### Mogelijkheid 1: EnvJS
*EnvJS* is een *gesimuleerde* browser omgeving geschreven in JS. Zie http://www.envjs.com/
@ -1596,7 +1596,7 @@ java -cp lib/envjs/js.jar:lib/envjs/jline.jar org.mozilla.javascript.tools.shell
`test.js` heeft dan maar 1 regel die naar de juiste specRunner.html gaat met `window.location`.
#### Mogelijkheid 2: Qt Webkit widget
#### Mogelijkheid 2: Qt Webkit widget
*Webkit* is een opensource web renderer, en er is een implementatie in `Qt` beschikbaar (vereist libs geïnstalleerd te hebben). Zie http://trac.webkit.org/wiki/QtWebKit
@ -1608,7 +1608,7 @@ Zie http://johnbintz.github.com/jasmine-headless-webkit/ (Implementatie in Ruby
[Phantom JS](http://www.phantomjs.org/) is een full stack headless browser implementatie gebaseerd op WebKit (C++/Python implementatie).
# Pitfalls
# Pitfalls
:exclamation: Gebruik aub **[JSLint](http://www.jslint.com)** om onderstaande "probleempjes" makkelijker te kunnen tracen en aanpassen.
@ -1616,7 +1616,7 @@ Zie http://johnbintz.github.com/jasmine-headless-webkit/ (Implementatie in Ruby
-> Meer (al dan niet grappige) pitfalls/weetjes: http://www.wtfjs.com/
### Objecten
### Objecten
Javascript gebruikt intern de `toString()` functie wanneer objecten als keys worden toegekend. Dit wil zeggen dat eigenlijk de string representatie als key gebruikt wordt. Bijvoorbeeld:
@ -1633,7 +1633,7 @@ console.log(obj[key1]); // ##### yo???
#####= arguments #####=
##### arguments on-the-fly veranderen #####
##### arguments on-the-fly veranderen
Zonder `use strict` (ES5) kan je een binnenkomend argument ook toekennen aan een andere waarde. Hierdoor verandert de waarde van `arguments[0]`! De `arguments` lijst houdt dus een pointer bij naar de variabele die de value van het argument vasthoudt, en niet naar de value zelf. In strict mode wel. Voorbeeld:
@ -1645,7 +1645,7 @@ function bla(a) {
bla(1); // 5, in strict mode 1
```
##### arguments is geen array #####
##### arguments is geen array
Snel "effe" lopen over alle argumentjes:

View File

@ -10,7 +10,6 @@ categories:
tags: ['braindump', 'learning', 'baking', 'bread' ]
---
Originally posted on [Medium](https://medium.com/this-happened-to-me/learning-to-become-a-baker-99c0d2c3388a).
#### Addendum

View File

@ -11,7 +11,7 @@ date = "2013-10-01"
categories = [ "software" ]
+++
### Binaries zoeken
### Binaries zoeken
Kan met `whereis`, **maar** die zoekt blijkbaar niet in "alle" binary dirs - enkel degene die geconfigureerd zijn onder:
@ -20,7 +20,7 @@ sysctl user.cs_path
# output: user.cs_path = /usr/bin:/bin:/usr/sbin:/sbin
```
### Shell automatisation
### Shell automatisation
Command-line programs *feeden* kan met het `expect` tooltje. Bijvoorbeeld, bij het aanloggen in `ssh` moet je daarna een wachtwoord geven en op enter drukken dat niet als commandline argument meegegeven kan worden. Dit kan je dan zo forceren:
@ -58,9 +58,9 @@ send -- "<br/>r"
expect eof
```
([bron](http://nixcraft.com/shell-scripting/4489-ssh-passing-unix-login-passwords-through-shell-scripts.html)) - voor meer uitleg zie {{< wp "Expect" >}} wiki.
([bron](http://nixcraft.com/shell-scripting/4489-ssh-passing-unix-login-passwords-through-shell-scripts.html)) - voor meer uitleg zie Expect wiki.
### Synchronizing/backupping/file copying
### Synchronizing/backupping/file copying
Gebruik het `rsync` commando om incrementeel een kopie te nemen van een directory en alle subdirs van plaats1 naar plaats2. Dit kan lokaal, naar een externe HDD of zelfs via een server. `rsync` heeft ook een daemon mode die je aan kan zetten met `--daemon` - Zie [rsync man](http://www.samba.org/ftp/rsync/rsync.html). Het belangrijkste commando is zonder twijfel:
@ -80,7 +80,7 @@ Een extra optie `-z` kan ook compressie over netwerk toevoegen. Verwijder dan be
Je kan periodiek dit commando uit voeren om de destination dir up-to-date te houden. Vergeet niet dat rsync ook een `daemon` mode heeft, met nog veel meer opties!
### User rechten geven om root te worden
### User rechten geven om root te worden
Probleem bij `su` commando: *su: Sorry for normal user account.*
@ -88,7 +88,7 @@ Vergeten toe te voegen aan de `wheel` user group, zo doen:
```pw user mod vivek -G wheel```
### Shell editing mode
### Shell editing mode
Zie http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-sheet/
@ -100,7 +100,7 @@ Best opslaan in uw `.bashrc` (of whateverrc)
-> Tof om te weten: `CTRL+L` **cleart het scherm** van een **terminal** (dit werkt ook voor Cygwin!)
### Command History
### Command History
voorbeeld:
@ -115,7 +115,7 @@ dir $ !2
waarbij ![getal] laatste x commando uitvoert en !! het laatste. Zie `man history` voor geavanceerde voorbeelden.
### Copy and auto-create dir structure
### Copy and auto-create dir structure
Bewaar dit shell script naar cpi.sh:
@ -129,7 +129,7 @@ cp -R "$1" "$2"
`chmod +x cpi.sh` en dan in uw `.bashrc` een link leggen om `cpi` te gebruiken.
### xargs
### xargs
Het bovenstaande kan ook uitgevoerd worden met `xargs` en piping. Bijvoorbeeld bepaalde bestanden (niet-recursief) kopiëren naar "tmp":
@ -146,7 +146,7 @@ Andere interessante opties van xargs:
* `-nx`: gebruik maximum x argumenten per command line.
* `-t`: verbose mode (`--verbose` werkt ook)
### sed
### sed
Gebruik `sed` om snel replaces te doen door middel van regex, of door lines te nummeren, ... <br/><br/>
Het is ook mogelijk om regex partities te *groeperen*, vergeet niet de haakjes zelf te escapen! Om de gegroepeerde waarde in het "replace" geteelde te gebruiken, moeten we niet `$1` maar `<br/>1` gebruiken. Bijvoorbeeld:
@ -166,7 +166,7 @@ Dus prepend elke regel met 'regel:'.
-> Groeperen in sed vereist escaped parentheses, anders matchen we exact `(` in de zoekstring zelf!
##### chainen
##### chainen
Een keer sed aanroepen en in een sequentie meerdere replaces doen gaat met het `-e` argument (script mode):
@ -174,7 +174,7 @@ Een keer sed aanroepen en in een sequentie meerdere replaces doen gaat met het `
cat file | sed -e 's/replace/by/g' -e 's/other/new/g'
```
##### Aan begin van lijnen prependen
##### Aan begin van lijnen prependen
Gebruik het symbool '^' om het begin van een lijn te matchen, en '$' om het einde van een lijn te matchen:
@ -186,12 +186,12 @@ Hier wordt in het begin van elke lijn spatie spatie ster toegevoegd behalve als
-> Zoals in eclipse een getal matchen met `<br/>d` werkt niet, daarvoor moet je `[0-9]` gebruiken.
### uniq
### uniq
Vergelijkt een lijn met de volgende en gooit dubbels eruit. Instelbaar met een beperkt aantal parameters. <br/><br/>
**adjacent matching lines**, meer kan dit ding niet!
##### sed gebruiken om uniq te emuleren
##### sed gebruiken om uniq te emuleren
Zie http://www.catonmat.net/blog/sed-one-liners-explained-part-three/ voor volledige uitleg
@ -199,13 +199,13 @@ Zie http://www.catonmat.net/blog/sed-one-liners-explained-part-three/ voor volle
sed '$!N; /^<br/>(.*<br/>)<br/>n<br/>1$/!P; D'
```
##### sed gebruiken om álle dubbels eruit te smijten: buffering
##### sed gebruiken om álle dubbels eruit te smijten: buffering
```
sed -n 'G; s/<br/>n/&&/; /^<br/>([ -~]*<br/>n<br/>).*<br/>n<br/>1/d; s/<br/>n//; h; P'
```
### cut
### cut
Een utility command dat meestal gebruikt wordt om lijnen op te splitsen afhankelijk van een __delimiter__. Bijvoorbeeld:
@ -218,7 +218,7 @@ meest gebruikte opties:
* `-d` verplicht, geef delimiter op
* `-f` selecteer enkel deze kolommen
### Combinatievoorbeeld
### Combinatievoorbeeld
Onderstaand script zoekt in de svn log entries met 'jira' of 'hel' (case insensitive, `-i` grep operator) behalve 'gcl' of 'lvm', print context 1 lijn above en 2 lijnen below, filtert dubbels, haalt de derde kolom eruit gesplitst door '|' (datum), vervangt eender welke hoeveelheid '-' door niets en wrap datums beginnende met 2011 met twee = tekens.
@ -322,7 +322,7 @@ echo DIRS = ${DIR}
Makkelijker dan `getopts()`?
#### Pipen en multiple lines in shell scripts
#### Pipen en multiple lines in shell scripts
Dit is legale shell code:
@ -336,7 +336,7 @@ cat dinges.log |
De pipe aan het begin van een nieuwe lijn alleszins niet. Ook `>>` of `>` kan niet het begin zijn van een nieuwe lijn, dan wordt een spatie gepiped naar de outputstream.
#### array loops
#### array loops
```bash
names=( Jennifer Tonya Anna Sadie )
@ -351,7 +351,7 @@ Ook mogelijk om bvb een counter bij te houden met `for (( i = 0 ; i < ${#names[@
Inline arrays "maken" en over lopen gaat met `for VAR in 'a' 'b' 'c' do ... done`.
##### argumenten samen rapen in een variabele
##### argumenten samen rapen in een variabele
```bash
DIR_EXCLUDES=(eclipsecompiled test bin target)
@ -371,11 +371,11 @@ done
:exclamation: dit werkt **niet** als er een dubbele quote bij komt kijken in de vorm van `<br/>"` - vreemd? uit te zoeken...
#### Controleren of een string in een variabele steekt
#### Controleren of een string in een variabele steekt
Zie http://stackoverflow.com/questions/229551/string-contains-in-bash - makkelijkste manieren zijn
##### met grep
##### met grep
```bash
if grep -q '|' <<<$line; then
@ -383,7 +383,7 @@ if grep -q '|' <<<$line; then
fi
```
##### met regexp
##### met regexp
```bash
if [[ "$line" =~ "|" ]]; then
@ -391,7 +391,7 @@ if [[ "$line" =~ "|" ]]; then
fi
```
#### Loopen over alle lijnen van bepaalde output voor verdere processing
#### Loopen over alle lijnen van bepaalde output voor verdere processing
```bash
`cat somefile` | while read line
@ -412,11 +412,11 @@ done
:exclamation: By default splitst for **op spaties**
# Find command
# Find command
-> Zie http://northredoubt.com/n/2009/12/30/linuxunixcygwin-find-command/ voor enorm veel uitleg over basics van `find`.
### Finding stuff
### Finding stuff
```
find / -name "*.ext" -type f -exec [command with args] {} <br/>;
@ -428,7 +428,7 @@ Bovenstaande lijn zoekt in root directory voor alle .ext bestanden (-type f is s
> find: missing argument to '-exec'
### Includen en excluden: filters
### Includen en excluden: filters
Ik zoek *.properties behalve die en die file en overal behalve in die en die directory:
@ -438,9 +438,9 @@ find . -name "*.properties" -not -path "*dir*" -not -name "ugly.properties"
`-not` is te combineren met eender wat én te chainen, bijvoorbeeld met `-size` enzo.
# Greppin' away
# Greppin' away
#### Surrounding lines while greppin'
#### Surrounding lines while greppin'
Dit heet **lines in context** in *man grep*.
@ -451,9 +451,9 @@ grep -B 3 -A 2 foo README.txt
Verklaring: Zoek foo in readme.txt met 3 lijnen boven en 2 lijnen onderaan. <br/><br/>
Indien aantal lijnen gelijk, gebruik simpelweg `-C [x]`.
#### Inverse grepping
#### Inverse grepping
##### In file contents
##### In file contents
Om te zoeken naar bijvoorbeeld 'hond', maar niet 'kat', moet je inverse zoeken voor kat:
@ -461,7 +461,7 @@ Om te zoeken naar bijvoorbeeld 'hond', maar niet 'kat', moet je inverse zoeken v
cat file | grep 'hond' | grep -v 'kat'
```
#### Finding pattern a OR b
#### Finding pattern a OR b
Combineren gaat met het pipe character (escaped) `<br/>|` - voorbeeld zoekt naar hond of kat:
@ -471,7 +471,7 @@ cat file | grep 'hond<br/>|kat'
:exclamation: Normale manier is `egrep pattern1|pattern2` gebruiken of `grep -E pattern1|pattern2`.
#### Toon meer info bij context
#### Toon meer info bij context
```
grep 'zoekstring' file.bla -n -H

View File

@ -0,0 +1,49 @@
---
title: Are Digital Gardens Blogs?
date: 2021-10-06T10:00:00+02:00
categories:
- journaling
---
I've missed the latest IndieWeb popup gathering on [digital gardens and streams](https://indieweb.org/2021/Pop-ups/Gardens_and_Streams_II) (thanks [Frank](https://diggingthedigital.com/17204-2/) for bringing that up). Thankfully, they are intricate note-takers, and it always pays off to poke around in those. As avid journaler, the subject naturally appeals to me. In fact, you could say that _Brain Baking_ is my _digital garden_. Or is it?
First, what's a digital garden? Simply put, it is your (1) personal (2) online space to (3) write down notes and (4) connect them---as [Dennis Seidel](http://dennisseidel.de/digital-garden) defined it in his garden. Those four things are important:
1. _Personal_: These are your own private thoughts. But are they private? Once the community starts discussing digital gardens, they tend to want to share them. The rise of Roam and Obsidian made it easy to (self-)publish these, but even before that, people have been setting up wikis and blogs for the very same reason.
2. _Online_: It's called a _digital_ garden for a reason.
3. _Write down notes_: the collecting part.
4. _Connect notes_: the value-creating part.
Collecting thoughts isn't exactly new. Cicero did it, Michelangelo did it, John Locke did it, Charles Darwin did it. Their methods do not differ much from modern digital gardeners. Or do they? Which of the above four things is essential? Only the last two are: find a way to write down your thoughts and go through them and manage to create novel insights.
### Why digital is overrated
Whether they are [codexes, memexes, or genexes](http://www.cs.umd.edu/hcil/trs/97-21/97-21.html): it all boils down to store knowledge outside of your brain and (regularly) reprocess them. I dare to say that technology, such as the World Wide Web that features linked documents, aren't all that compelling. I just as easily reference to other pages and books on the analog notes I write down. Sure, refactor and move tools greatly simplify structure, and digital text is easily searchable. But for every `[[linked]]` article you produce, clutter is introduced that is called syntax. Furthermore, a lot of people struggle with actually _tending_ to the garden: cutting branches, moving plants. The end result is usually a mess.
One of the biggest disadvantages of digital gardens, to me, is exactly the fact that it's structured. That is, articles---whether they are blog posts or wiki pages do not matter---are still mainly text-based. You can't quickly draw rectangles or arrows next to your notes. You can't draw an eukaryote and point to its nucleus to explain that that's where the DNA chromosome strings are coiled up (sorry, I've been doing some yeast cell research). You can't print photos or cut out parts from newspapers to paste it besides a schematic. You can't grab your watercolor paint and brighten up a page. You can't paste your cat's whisker in your notebook (for research purposes, of course!). You can't smear out a blueberry or wet tea leaf to try and capture its smell and color.
Another advantage that tends to be dismissed is (s)low tech: off-screen time. I already spend way too much time clutched behind a PC. I prefer to go through my notes on a bench in the park without the artificial light of an LCD screen. Speaking about benches: capturing fleeting thoughts only works if you hold on to your writing tools at all times. I hope you leave your technological trinkets outside the bedroom, but I suspect few of us do.
I've been using a combination of Sublime Text and Obsidian extensively for my PhD research, so don't get me wrong, I love digital editors and connectors. But compared to my fountain pen and my notebook, they severely hamper my thoughts. Of course, to get anything published, whether it is an academic paper or a blog article, you'll need to convert your thoughts to ASCII.
I do not refactor my analog notes. That's impossible unless you bring out the scissors. Instead, I rewrite things, cross things through, and reference to both previous pages and previous books a lot. To do that, I [digitize and annotate my journal pages](/post/2021/01/digitizing-journals-using-devonthink/). So _digital_ does help to _archive_, but it is far from the best way to assist my thinking.
### Why public is overrated
Public digital gardens are overrated. They are very hard to navigate. Time and time again, I get lost in the jungle of mystical links, in the _check-ins_ drowned in the _bookmarks_ and the _quotes_. Fancy IndieWeb sites that boast 5 separate RSS feeds to "help" navigate the labyrinth do not make it better. I've tried following multiple interesting people that pump loads and loads of seemingly cool looking stuff into their site. It always ends in confusion. Yes, sometimes I discover a link to another published article (external to the garden, by the way!) that is interesting. As admiring as the garden is, the things they grow there are almost always puzzling.
But the most important reason why I think they're not that useful to others, is exactly that: they're _personal_. That is, you'll have to make the translation between _their_ context and _your_ context. And that always and inevitably means important messages get lost in translation. It's fun to fool around in someone's garden, but if you have no clue what to do with tropical seeds in your own temperate climate powered garden, then don't bother.
Many famous journals were never meant to be published and have to be heavily edited to produce an interesting coherent text. Hilarious letters from [Madame de Sévigné](https://fr.wikipedia.org/wiki/Madame_de_S%C3%A9vign%C3%A9) or depressing ones from Vincent van Gogh are the exception, since they were written to be read by others, although not the general public.
### Digital Gardens or Blogs?
That is why I think that most digital gardens are not blogs. Again, there are exceptions, like some articles in [Tracy Durnell's](https://tracydurnell.com/2021/09/26/gardens-and-streams-ii/), but on average, digital gardens contain slices of context-heavy information processed by someone else's mind. Only after the translation into something publishable, like a blog post, they become interesting for others to read. I have little use for countless of "collected" links and likes. Published [Obisidan Vaults](https://obsidian.md/publish) look cool, but the initial excitement wears off pretty quickly.
Cory Doctorow has been calling his blog [his Outboard Brain](https://web.archive.org/web/20040616003452/http://www.oreillynet.com/pub/a/javascript/2002/01/01/cory.html) since 2002. _Outboard brain_, not _Second brain_. He must have had notes---either in his head, on paper, or digitally---before being able to put the message _out_ there. Quite a few people reach for Wordpress to build their digital garden nowadays, and although Wordpress is the de facto blogging tool, the result is all but a blog.
I much prefer others' blogs, in the classic sense of the word (let's ignore parasitic corporate blogs). These are interesting because they are coherent---or at least, should be. They are about others' passion for whatever that drives them. Which might spike my own interest. And then, perhaps, maybe, could end up in my own notebook.
With the help of a pen, of course.

View File

@ -0,0 +1 @@
{{ .Site.Params.level }}

View File

@ -1 +0,0 @@
<a href="https://en.wikipedia.org/wiki/{{ index .Params 0 }}" target="_blank">{{ index .Params 0 }}</a>