[RegEx] JSON filteren [en unit-testing]*

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10-09 18:14

alienfruit

the alien you never expected

Topicstarter
Ik probeer een bestaande json bestand aan te passen zodat het gebruikt kan worden door een vertaaltool. Alleen nu heb ik een probleem dat als een json-property begint met uittip_ deze regelt niet hoeft worden aangepast. Weet iemand hoe zoiets moet? Ik krijg het namelijk niet voor elkaar.

Als voorbeeld:
code:
1
2
3
4
5
6
7
8
9
{
    "uitip_buttons": "General buttons used throughout the application",
    "buttons": {
        "uitip_resetfilters": "Reset filters on panels",
        "resetfilters": "Reset filters",
        "uitip_clearFilters": "Clear all filters",
        "clearFilters": "Clear filters",
    }
}


Nu wil ik graag alles met uitip_ niet selecteren. Ik wil namelijk de waarde van property leegmaken. Dus van
code:
1
 "resetfilters": "Reset filters on panels"
naar
code:
1
 "resetfilters": ""


Ik gebruik nu de regex
code:
1
/\:(\s+)\"(.+)\"/g)
wat alleen niet werkt omdat het dan ook de uitip_ meepakt. Ik heb vervolgens
code:
1
((?!uitip_\W)\S+)":(\s+)"(.+)"
geprobeerd maar dat wil ook niet lukken. Iemand enig idee? Of moet ik toch maar voor een recursieve functie gaan in Javascript?

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
In javascript kun je geen lookbehind doen. Als het formaat steeds hetzelfde is, dan kun je natuurlijk wel een hack toepassen, waarbij je gewoon de tekst terugplaatst:
JavaScript:
1
result=jsonstring.replace(/        "resetfilters": "[^"]+",/g,'        "resetfilters": "",');

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Zoiets?
JavaScript:
1
/^((?!uitip_).)*: "[^"]+"$/g

De uitleg staat op http://stackoverflow.com/...ing-not-containing-a-word

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Welke taal ga je gebruiken om je regex toe te passen (neem aan JS)?

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Oh, ik zie dat ik denk ik de vraag verkeerd begrepen heb. :p Bedoel je dat je alle properties behalve "uitip_*" wilt wissen op dat niveau? Dan is de truc om (?!) op de juiste plaats te gebruiken, dat betekend niet "niet in die regel", maar "niet op exact die plek". Ook dan zul je een deel moeten terugplaatsen in js, vanwege gebrek aan lookbehind. Dus zoiets:
JavaScript:
1
result=jsonstring.replace(/(        "(?!uitip_)[^\"]+": ")[^"]+",/g, '$1",');

Maar dit soort hacks hangen een beetje samen met hoe het is gegenereerd.

De methode van GlowMouse kan met wat aanpassingen ook wel werken (iig /m), maar lijkt me wat inefficiënt, je weet tenslotte precies waar je uitip kan verwachten.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Ik zou liever eerst door alle regels heen lopen, dan matchen met die lookahead en daarna pas replacen als die match er niet is. Dan hoef je niet ingewikkeld te doen en valt het hackniveau mee. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Maar als je er doorheen loopt dan is een needle - haystack een stuk simpeler te fixen :)

Dat kan je simpelweg zelf of met een geoptimaliseerd stukje proza zoals https://github.com/Baggz/Pinch

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Voor iets dat met een paar regels code ook is opgelost zou ik geen library installeren. :) Ik zou een voorbeeldje kunnen schrijven maar dat gaat wat eenvoudiger als ik weet over welke taal we het hebben. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Dat zeg ik toch ook ;)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom zou je dit überhaupt met een regex op willen lossen?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Omdat het dan tenminste opeens fout kan gaan met bijvoorbeeld escaping (ipv [^"]+ zou je overigens (?:[^"\\]|\\.)+ kunnen/moeten gebruiken).

De reden is natuurlijk dat het zo lekker snel in elkaar hackt en dan lijkt te werken. ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Van creepy:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. — Jamie Zawinski

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Ik begrijp dat je voor iets als dit als eerst naar regex grijpt, en vaak zat is dat een prima oplossing.

Echter heb ik hier een ander probleem, en dat is een architectuur probleem.

Wees eerlijk. Als ik op basis van een naam van een key in keyvaluepair (lees: variable naam) ga filteren dan doe je iets fout.

Wees zo eerlijk om toe te geven dat je eigenlijk een property 'dezewilikniethebben' wilt hebben.

Dus in mijn ogen zou je 'data' (json) er zo uit moeten zien (geparsed, dus zonder die quotes):
JavaScript:
1
2
3
4
5
6
7
8
9
{
    uitip_buttons: "General buttons used throughout the application",
    buttons: [  //ja dit is een array, je hebt namelijk een lijst van gelijkgetypeerde items
        { id: "uitip_resetfilters", wilikdeze: false, title: "Reset filters on panels" },
        { id: "resetfilters", wilikdeze: true, title: "Reset filters" },
        { id: "uitip_clearFilters", wilikdeze: false, title: "Clear all filters" },
        { id: "clearFilters", wilikdeze: true, title: "Clear filters" },
    ]
}


je kunt dan met $.grep bijv. door de array lopen en de gevonden items 'resetten'
JavaScript:
1
$.grep(json.buttons, function(e) { return e.wilikdeze; } ).title = '';

[ Voor 31% gewijzigd door BasieP op 15-10-2013 21:46 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Je weet toch niet vantevoren waar je op wilt filteren ;)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
BtM909 schreef op dinsdag 15 oktober 2013 @ 21:47:
Je weet toch niet vantevoren waar je op wilt filteren ;)
dan heeft ie achteraf gezien toch goede variablenamen gekozen ;)

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op dinsdag 15 oktober 2013 @ 15:11:
Waarom zou je dit überhaupt met een regex op willen lossen?
De voornaamste reden om regexen te gebruiken is zodat ze niet ineens iemand anders kunnen inhuren, zodat je volledig onmisbaar bent om de code te onderhouden tot het einde der tijden.

Want als je als nieuwe werknemer gevraagd wordt de code even aan te passen aan het nieuwe protocol, en je ziet zoiets "/^((?!uitip_).)*: "[^"]+"$/g" staan, dan denk je wel twee keer na om deze taak op je te nemen.

[ Voor 23% gewijzigd door Zoijar op 15-10-2013 22:03 ]


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Zoijar schreef op dinsdag 15 oktober 2013 @ 22:01:
[...]

De voornaamste reden om regexen te gebruiken is zodat ze niet ineens iemand anders kunnen inhuren, zodat je volledig onmisbaar bent om de code te onderhouden tot het einde der tijden.

Want als je als nieuwe werknemer gevraagd wordt de code even aan te passen aan het nieuwe protocol, en je ziet zoiets "/^((?!uitip_).)*: "[^"]+"$/g" staan, dan denk je wel twee keer na om deze taak op je te nemen.
Sorry, dat vind ik een slecht verhaal.

Als ik java zie staan als cobol programeur zou ik net zo goed schrikken. Je hebt gewoon de verkeerde persoon aangenomen.
Kennis van Regex is gewoon een vereiste. Ik zal nooit een ontwikkelaar aannemen die geen regex kent of op korte termijn wil leren. Dat is gewoon zonde van je geld. Dat is zoiets als een tester aannemen die geen testautomatisering wil doen, of een informatieanalist inhuren die geen specs wil schrijven.

Ga je hetzelfde zeggen over SQL? mag een java ontwikkelaar geen SQL meer schrijven omdat het geen java is?
En jquery als frontend ontwikkelaar.. Ik kan hele 'onleesbare' jquery verzinnen, maar als dat precies is wat je nodig heb ga je het gebruiken. (daar gelaten dat je het wel even wilt verduidelijken dmv wat inline comment of een stukje documentatie)

[ Voor 15% gewijzigd door BasieP op 15-10-2013 22:11 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Dude, sarcasm.... Can you read it? ;)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
BtM909 schreef op dinsdag 15 oktober 2013 @ 22:17:
Dude, sarcasm.... Can you read it? ;)
heb je het tegen mij? (quote helpt)
dan "ja tuurlijk, ik doe er een schepje bovenop can YOU read it?"

(lekker dat emotieloos communiceren (text) en dan over sarcasme gaan hebben)

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

haha, nou, ik was eigenlijk nog best serieus. Wel een beetje tongue-in-cheek natuurlijk.

Je kan een onleesbare jquery verzinnen: wat een ge-wel-dige developer skill ;) En een SQL query schrijf je ook zo natuurlijk: "s$1f["./t@$1].o+&x" daar staat gewoon select field1 van local table t oplopend gesorteerd op veld x bij reference ;)

Eigenlijk zou ik nooit iemand aannemen die niet vloeiend brainfuck schrijft; dat is toch wel een vereiste -- in ieder geval als je ze later wilt laten promoveren tot regexen :+

[ Voor 21% gewijzigd door Zoijar op 15-10-2013 22:30 ]


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Zoijar schreef op dinsdag 15 oktober 2013 @ 22:25:
haha, nou, ik was eigenlijk nog best serieus. Wel een beetje tongue-in-cheek natuurlijk.

Je kan een onleesbare jquery verzinnen: wat een ge-wel-dige developer skill ;) En een SQL query schrijf je ook zo natuurlijk: "s$1f["./t@$1].o+&x" daar staat gewoon select field1 van local table t oplopend gesorteerd op veld x bij reference ;)

Eigenlijk zou ik nooit iemand aannemen die niet vloeiend brainfuck schrijft; dat is toch wel een vereiste -- in ieder geval als je ze later wilt laten promoveren tot regexen :+
nou ik ben ook nog serieus, en ik blijf bij het standpunt.

ingewikkelde code is niet fout. Tuurlijk is leesbaarheid een argument om bepaalde code anders te schrijven, maar als je geen regex snapt dan denk ik dat je gewoon een cursus nodig hebt of een andere baan moet zoeken.

nee onleesbare jquery schrijven is niet een skill, maar goed werkende en efficient code schrijven wel. En ja die wil wel eens onleesbaar zijn.

Ik weet niet of je wel eens lambda expressions hebt gezien? nog zo'n mooi voorbeeld van 'onleesbare, maar nuttige' code.

En jij denkt dat je met sql alleen maar select * from table doet vind ik vrij naief.
Wel eens met xmlagg een kolom naar een rij gekantelt binnen je select? daar komt echt niet iets heel leesbaars uit hoor.

punt is gewoon simpel:
je hebt skills nodig om het werk te doen, als jij denkt dat je iemand aan kan nemen die alleen 'de basics' snapt is dat leuk als junior developer, maar daarmee houd het op.
Ik stel een iets hogere eis aan mijn ontwikkelaars.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik vind het een vorm van, hoe noem je dat, 'fancy code syndrome'. Een mooie uitspraak is dat je collega's en opvolgers niet zo slim zijn als jij denkt. Ingewikkelde, moeilijk leesbare code is niet fout... als het niet twee, drie of vijf jaar later door iemand anders onderhouden moet worden. Wat er dan gebeurt met die prachtige, efficiente doch moeilijk leesbare en aanpasbare code is zeerwaarschijnlijk een enkeltje recycle bin, en men schrijft het opnieuw.

Het heeft overigens niks met skill of kennis te maken: ik snap het wel, maar het is lastiger. Code moet zo simpel mogelijk zijn. Als het dan noodzakelijk ingewikkelder moet zijn, bijvoorbeeld sterk performance-kritieke code, dan moet het maar, met twee keer zoveel commentaar. Maar als je heel simpel een ander alternatief kan gebruiken dat wel leesbaar en onderhoudbaar is, zonder nadelen, gebruik dat dan.

Goede code is niet ingewikkeld of complex; goede code is simpel. Code die een kind van 12 zonder enige skills kan begrijpen: dat is het hoogst haalbare.

[ Voor 4% gewijzigd door Zoijar op 15-10-2013 23:01 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Een regex is gewoon onleesbaar, punt. Doet er niet toe hoe goed je erin bent. En daarom verschilt het echt enorm van iets als SQL en Java. Sure, je hebt er verstand van nodig om precies te weten wat er gebeurt, maar ook zonder verstand laat het zich wel enigszins raden. Dat is bij een regex totaal niet het geval, en dat feit alleen al betekent dat je het beter kan mijden dan gebruiken, zeker voor de wat complexere zaken (en deze topic is er een van). Daarnaast gaat een regex je hier niet helpen om alle cases te coveren. "uitip_clearFilters" is bijvoorbeeld ook te schrijven als "\u0075itip_clearFilters". Beter pak je gewoon een json parser en loop je gewoon door de object tree heen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

.oisyn schreef op woensdag 16 oktober 2013 @ 11:56:
Een regex is gewoon onleesbaar, punt. Doet er niet toe hoe goed je erin bent. En daarom verschilt het echt enorm van iets als SQL en Java. Sure, je hebt er verstand van nodig om precies te weten wat er gebeurt, maar ook zonder verstand laat het zich wel enigszins raden. Dat is bij een regex totaal niet het geval, en dat feit alleen al betekent dat je het beter kan mijden dan gebruiken, zeker voor de wat complexere zaken (en deze topic is er een van). Daarnaast gaat een regex je hier niet helpen om alle cases te coveren. "uitip_clearFilters" is bijvoorbeeld ook te schrijven als "\u0075itip_clearFilters". Beter pak je gewoon een json parser en loop je gewoon door de object tree heen.
Niet om dat laatste tegen te spreken aangezien dat een betere oplossing is...maar als je het probleem in dit topic opdeelt in het eerst zoeken of losse regels matchen en dan pas replacet dan zijn de resulterende regexen verre van complex. Sterker nog, veel simpeler worden ze dan niet. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Losse regels? Alsof json notie heeft van regels :). Da's natuurlijk vragen om moeilijkheden. Vroeg of laat produceert iemand een stukje json waarbij het niet meer zo is dat elke variabele zijn eigen regel heeft en dan heb je de poppen aan het dansen.

[ Voor 66% gewijzigd door .oisyn op 16-10-2013 12:19 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Klopt, maar dat hangt natuurlijk van het probleemdomein af. Als je zelf enige controle hebt over de uitvoer loopt dat wel los. Begrijp me niet verkeerd, je hebt honderd procent gelijk dat een JSON-parser veel slimmer is, maar met de claim dat een regexp per definitie onleesbaar is ben ik het niet eens. Expressies voor veel beperkte probleemdomeinen zijn prima te overzien, ook voor beginners. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Zoals ik hier aangeef is voor dit topic het probleem niet zozeer die regex, maar het feit dat je hem uberhaupt wilt gebruiken.

je probleem zit hem in dat je op basis van een eigenschap iets wilt beslissen, maar daarvoor een eigenschap misbruikt.
Die variabelenaam is niet bedoelt om de beslissing op te maken of je .... (vul maar in)
Een variabelenaam is een variabelenaam.

tot zover dat.


Wat betreft regex (en andere 'ingewikkelde' constructies)

Ik werk in een professioneel bedrijf (hou ik mezelf voor) en daarin werken proffesionele mensen (hou ik mezelf ook voor)
Buiten de inhoudelijke kwaliteiten van mijn collega's om (of ze regex snappen of niet) ga ik er vanuit dat ze wel de hersens hebben om te weten dat je niet aan bestaande code gaat zitten als je het niet snapt.

Voor de meeste functies, en zeker de complexere (zoals functies die iets met ingewikkelde regex doen) bouw ik unit testen.
Zolang de unittest goed is hoeft er dus niemand met z'n tengels aan die functie te zitten.

Wanneer de functionaliteit veranderd zal je misschien een keer de code raken, en dan (en alleen dan) is het een valide argument om de regex te heroverwegen.
Het vervangen van regex omdat het regex is is gewoon NOT DONE.
if it ain't broke, don't fix it!

Verder heb ik al herhaaldelijk gezegt dat complexe code natuurlijk documentatie vereist. Een (elke) regex zou in mijn opinie vergezeld moeten gaan van een functionele beschrijving in de vorm van
a. inline commentaar
b. een unittest met alle scenario's

Waarom uberhaupt een regex gebruiken?
nou dat is een simpele. Regex is er niet voor niets. Het is de meest efficiente generieke manier om enkelvoudig door een string te lopen.
Je kunt specifieke code bouwen die hetzelfde doet, maar wanneer ik wil kijken of een stuk tekst een url bevat, en daar dan een ancher van maken (bijvoorbeeld) is een regex VEEL simpeler (en leesbaarder) dan een stuk code van 20 regels die hetzelfde doet.
En, minder foutgevoelig.
Je complete regex is namelijk de definitie van je probleem. Je bent niet bezig non-functional code te schrijven. Dit doe je wel als je geen regex gebruikt. Je gaat dan de non-functional code schrijven om door een string te lopen, je gaat de non-functional code schrijven om case-insensitive te matchen, je gaat de non-functional code schrijven die zorgt dat ... (vul maar in).
Meer code is grotere kans op menselijke fouten.

Ja ik ben het met jullie eens dat sommige regex slecht leesbaar is, en als je vaak aan die code komt is het een valide reden om geen regex te gebruiken.
Maar regex kan heel leesbaar zijn.

En nogmaals:
Er zijn vele vergelijkbare dingen waarvan ook niet wordt gezegt 'dan gebruiken we ze maar niet'
Ik noemde eerder al:
- onleesbare jquery dingen
- onleesbare xmlagg functies in sql
- onleesbare lambda expressions

Moeten we dan geen jquery, sql en lambda gebruiken?
volgens mij is 'ik snap het niet dus we gebruiken het niet' een erg slechte instelling.

ow en met een knipoog:
If it was hard to write, it should be hard to understand.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10-09 18:14

alienfruit

the alien you never expected

Topicstarter
Bedankt allemaal! De code wordt gebruikt voor het genereren van een skeleton bestand voor een vertaalapplicatie die we hier gebruiken. Dus hebben veel invloed op de JSON input omdat we het alleen zelf intern gebruiken. Onderstaande code vind ik zelf lekkerder weg lezen. Meer regels ;)

Ik heb het inmiddels maar anders opgelost:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var generateSkeleton = function(source, json) {
    var source = JSON.parse(source),
        json = json || true,
        skeleton = {},
        checkProperty = function(property, value) {
            if (typeof value === 'object') {
                return Object.map(value, checkProperty);
            }

            if (property.indexOf('uitip_') === 0 ) {
                return value;
            }

            return '';
        },
        recursive = function(property, value) {
            return checkProperty(property, value);
        };

    skeleton = Object.map(source, recursive);
    if (json) {
        skeleton = JSON.stringify(skeleton, null, 4);
    }

    return skeleton;
};

[ Voor 15% gewijzigd door BtM909 op 16-10-2013 20:21 ]


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
JavaScript:
1
2
3
recursive = function(property, value) {
            return checkProperty(property, value);
        };


die snap ik niet...

je hebt een doorgeefluikje gecreerd... waarom?

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10-09 18:14

alienfruit

the alien you never expected

Topicstarter
Hah, brainfart :D

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
en je herdefineerd source...

var source = ..(source)...

je wil die buiten je var declaratie..

zelfde geld voor de variable 'json'

[ Voor 16% gewijzigd door BasieP op 16-10-2013 18:19 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:32
Als je het toch met een regex zou willen doen:
JavaScript:
1
json.replace(/([\ ]{1,})("((?!uitip_).)*[a-zA-Z]{1,}":[\ ]){1,}"(.*)"/g, "$1$2\"\"");


http://jsfiddle.net/zD7nR/3/

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

BasieP schreef op woensdag 16 oktober 2013 @ 17:51:
Ik werk in een professioneel bedrijf (hou ik mezelf voor) en daarin werken proffesionele mensen (hou ik mezelf ook voor)
Buiten de inhoudelijke kwaliteiten van mijn collega's om (of ze regex snappen of niet) ga ik er vanuit dat ze wel de hersens hebben om te weten dat je niet aan bestaande code gaat zitten als je het niet snapt.
Alsof je altijd die keuze hebt. Dan creer je dus een situatie met een single point of failure: degene die de code geschreven heeft is de enige die het kan onderhouden/aanpassen. En als die nou ziek is of naar een ander bedrijf over?
Voor de meeste functies, en zeker de complexere (zoals functies die iets met ingewikkelde regex doen) bouw ik unit testen.
Zolang de unittest goed is hoeft er dus niemand met z'n tengels aan die functie te zitten.
En als die unit test nou ineens breekt als je een ander stuk code verandert?
Wanneer de functionaliteit veranderd zal je misschien een keer de code raken, en dan (en alleen dan) is het een valide argument om de regex te heroverwegen.
Het vervangen van regex omdat het regex is is gewoon NOT DONE.
if it ain't broke, don't fix it!
Maar breken is wat code doet. Een situatie die veelvuldig voorkomt is dat een heel ander team iets verandert, bijvoorbeeld hier het exacte formaat van de json. Die merken dan dat de productie breekt. Die sturen het door naar jouw team. Helaas voor jouw team is degene die deze code 5 jaar geleden geschreven heeft nu verhuisd naar het buitenland en niet meer bereikbaar. Nu mag iemand zich in gaan lezen over hoe die regex precies werkt...
volgens mij is 'ik snap het niet dus we gebruiken het niet' een erg slechte instelling.

ow en met een knipoog:
Je zegt het met een knipoog, maar dat is wel wat ik tussen de regels door lees bij jou. Ik ben heel slim; ik snap het; mijn collega's moeten ook heel slim zijn en het snappen, dus is er geen probleem. Maar juist als je heel slim bent schrijf je code die iemand die niet heel slim is ook kan begrijpen :)

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
CurlyMo schreef op woensdag 16 oktober 2013 @ 18:24:
Als je het toch met een regex zou willen doen:
JavaScript:
1
json.replace(/([\ ]{1,})("((?!uitip_).)*[a-zA-Z]{1,}":[\ ]){1,}\"(.*)"/g, "$1$2\"\"");


http://jsfiddle.net/zD7nR/2/
Als ik dat niet al lang was heb je mij nu in ieder geval overtuigd dat je het NIET met regex wilt doen ;)
Zoijar schreef op woensdag 16 oktober 2013 @ 18:26:
*knip*

Je zegt het met een knipoog, maar dat is wel wat ik tussen de regels door lees bij jou. Ik ben heel slim; ik snap het; mijn collega's moeten ook heel slim zijn en het snappen, dus is er geen probleem. Maar juist als je heel slim bent schrijf je code die iemand die niet heel slim is ook kan begrijpen :)
Dan schat je me toch verkeerd in.
Ik reageer op jou reactie waaruit ik heel erg proefde 'thay shall not use regex'
En dat vind ik gewoon te ver gaan.
Er zijn legio legitime redenen om regex te gebruiken. Jouw hele verhaal berust op de aanname dat men de regex niet snapt.

Ik probeer op veel manieren aan te geven dat het doel van een regex niet is om code onleesbaar te maken, maar om te zorgen dat het juist beter wordt (performance, minder eigen code etc.)

Natuurlijk maak ik de afweging of ik op een bepaalde plek regex moet gebruiken. Zeker wanneer de regex complexer wordt.
Maar ik verzet mij hevig tegen de stelligheid in je opmerking dat 'alle regex ten alle tijde' fout is.

Dat is gewoon niet waar.

Daarbij vind ik dit een boeiend stukje proza:
Nu mag iemand zich in gaan lezen over hoe die regex precies werkt...
nee, dat heb je gedocumenteerd (lees inline code, een unittest etc.)

Ik blijf het zeggen, maar het lijkt niet aan te komen.
Het laatste wat ik wil is niet-onderhoudbare code. Ik doe er juist veel voor om te zorgen dat de code onderhoudbaar is.

Echter vind ik de stelling:
Dan creer je dus een situatie met een single point of failure: degene die de code geschreven heeft is de enige die het kan onderhouden/aanpassen.
nergens op slaan.
Regex is geen rocket science, er zijn legio mensen die het in meer of mindere mate snappen, en met een uurtje inlezen heb je de 90% normale regex dingen gewoon in de gaten.
Tuurlijk zal je geen negative lookbehinds enzo snappen in een uur, maar dat zijn ook niet dingen die je doorgaans in mijn code vind.

En het argument dat mijn vervanger misschien geen regex snapt blijf ik vaag vinden.
Als ik een java project bouw, en mijn vervanger snapt geen java dan gaat het ook niet werken..
Ja het is gechargeerd, maar dit is wel wat je zegt..
BCC schreef op woensdag 16 oktober 2013 @ 18:30:
Waarom je geen regexp wil gebruiken:
http://www.codinghorror.c...html-the-cthulhu-way.html
(Vervang overal HTML door JSON).
Nee dat is bullshit, je zou aan de hand van die link kunnen zeggen
'dit is waarom je geen html wilt'
Het probleem in die link is dat men poogt om met regex html te parsen.
voor parsen heb je parsers. Tokenizer, jak lexx etc.

Regex is geen parser.

[ Voor 77% gewijzigd door BasieP op 16-10-2013 18:38 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 11-09 21:08

BCC

Waarom je geen regexp wil gebruiken:
http://www.codinghorror.c...html-the-cthulhu-way.html
(Vervang overal HTML door JSON).

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
BasieP schreef op woensdag 16 oktober 2013 @ 18:27:
[...]

Als ik dat niet al lang was heb je mij nu in ieder geval overtuigd dat je het NIET met regex wilt doen ;)
Die regex is dan ook minder handig dan de regex in post 4 ofzo. Beetje een stroman. Het was vast een leuke oefening, maar ik zie mogelijkheden tot verbetering:
  • waarom {1,} ipv +?
  • waarom minimaal 1 spatie op het begin matchen?
  • \[\ ] ipv gewoon een spatie?!
  • waarom mag "zooi": herhaalt worden ({1,})?
  • waarom 2 groepen?
  • waarom [a-zA-Z]{1,} wat nooit zal matchen?
  • gaat mis bij bijv. muitip_*
  • zie hints over escaping
BasieP schreef op woensdag 16 oktober 2013 @ 17:51:
Voor de meeste functies, en zeker de complexere (zoals functies die iets met ingewikkelde regex doen) bouw ik unit testen.
Zolang de unittest goed is hoeft er dus niemand met z'n tengels aan die functie te zitten.
En dan blijk je een case zoals escaping of meerdere attributen op 1 regel gemist te hebben, en moet de unittest aangepast en de code ook. Beter zou je die tijd van de unittest investeren in code die gewoon begrijpbaar is en in generieke gevallen werkt. :p

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Een regex is een definitie van een reguliere taal, die vervolgens gevoed wordt aan een of andere regex engine die een parser voor die taal maakt en uitvoert (al dan niet in een stap). Dus het is niet gek om het een parser te noemen.

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Zoijar schreef op woensdag 16 oktober 2013 @ 18:58:
[...]

Een regex is een definitie van een reguliere taal, die vervolgens gevoed wordt aan een of andere regex engine die een parser voor die taal maakt en uitvoert (al dan niet in een stap). Dus het is niet gek om het een parser te noemen.
Taaltechnisch heb je soort van gelijk, maar jij en ik zijn het volgens mij eens over dat regex niet bedoeld is om (zoals in het voorbeeld) html te parsen met regex
a regular expression (abbreviated regex or regexp) is a sequence of characters that forms a search pattern, mainly for use in pattern matching with strings, or string matching, i.e. "find and replace"-like operations
dus matching en replacing
Parsing is wel echt wat meer dan dat.
pedorus schreef op woensdag 16 oktober 2013 @ 18:57:

En dan blijk je een case zoals escaping of meerdere attributen op 1 regel gemist te hebben, en moet de unittest aangepast en de code ook. Beter zou je die tijd van de unittest investeren in code die gewoon begrijpbaar is en in generieke gevallen werkt. :p
Jij slaat je unittest over? hoe ga je er dan achter komen wanneer je stukje code omgevallen is. Als het in productie fout gaat en je klanten gaan klagen?

Die unittest moet er sowieso komen, en ik weet niet hoe jij unittests bouwt, maar er bestaat zoiets als test-driven development.

Je komt er dus niet na het bouwen van je unittest achter dat je een scenario vergeten bent, je komt er tijdens het bouwen van je functie achter dat je een scenario vergeten bent, en dit komt omdat je unittest het aangeeft.

[ Voor 38% gewijzigd door BasieP op 16-10-2013 21:38 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:32
pedorus schreef op woensdag 16 oktober 2013 @ 18:57:
[...]

Die regex is dan ook minder handig dan de regex in post 4 ofzo. Beetje een stroman. Het was vast een leuke oefening, maar ik zie mogelijkheden tot verbetering:
  • waarom {1,} ipv +?
  • waarom minimaal 1 spatie op het begin matchen?
  • \[\ ] ipv gewoon een spatie?!
  • waarom mag "zooi": herhaalt worden ({1,})?
  • waarom 2 groepen?
  • waarom [a-zA-Z]{1,} wat nooit zal matchen?
  • gaat mis bij bijv. muitip_*
  • zie hints over escaping
Je hebt helemaal gelijk. Mijn vorige regex was een beetje lui geschreven :P
JavaScript:
1
json.replace(/( *"(?!\w+_)\w+": *)"[\w ]*"/g, '$1""');

http://jsfiddle.net/zD7nR/5/

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Die \w's zijn nogal sterke aannames.
BasieP schreef op woensdag 16 oktober 2013 @ 21:34:
Jij slaat je unittest over? hoe ga je er dan achter komen wanneer je stukje code omgevallen is. Als het in productie fout gaat en je klanten gaan klagen?

Die unittest moet er sowieso komen, en ik weet niet hoe jij unittests bouwt, maar er bestaat zoiets als test-driven development.

Je komt er dus niet na het bouwen van je unittest achter dat je een scenario vergeten bent, je komt er tijdens het bouwen van je functie achter dat je een scenario vergeten bent, en dit komt omdat je unittest het aangeeft.
Ik doe inderdaad niet aan unit tests, net zoals zeer veel succesvolle IT-bedrijven trouwens. Die tijd kun je dan aan nuttigere dingen besteden. Toevallig is een project waar wel met unit tests wordt gewerkt nu net het beroerdste project qua code dat ik heb gezien.

Wat we bijvoorbeeld wel doen is gewoon anderen naar de code laten kijken (code reviews als je het een naampje wil geven), tests op een hoger niveau dan een unit, en simpelweg rondklikken in geval van bepaalde UI applicaties. Oh, en ja, bij uitzondering wat unit tests waar dat zinnig is, waarbij de unit dan bijvoorbeeld een bepaald bijzonder algoritme is.

Maar in dit voorbeeld is het echt nuttiger om iemand anders ernaar te laten kijken en/of het gewoon direct uit te proberen, want jij gaat geen unit test maken voor iets dat je niet verwacht, en de hoeveelheid te verwachten wijzigingen is nihil. Zoals je zelf zegt, iets dat werkt valt niet zomaar om. En als het niet werkt, moet je de unit test anders ook up to date houden, kost het weer extra werk.

Nu stel je min/meer voor om dit met een regex te doen en een unit test te maken, en dat dan bewijs is dat het goed werkt. In werkelijkheid valt het om als de json er net iets anders uit ziet, en moet je dan zowel de unit tests bijwerken als de code. Je kunt dus beter gewoon een json-parser gebruiken bij het implementeren. Dan kun je de unit test achterwege laten, omdat die json-parser genoeg getest is en de eigen implementatie zeer overzichtelijk is. Zeker als je dan het nog even uitprobeert en iemand anders even laat kijken is de kans op bugs veel kleiner, en de bestede tijd ook. :p

offtopic:
Dijkstra, 1988:
It is now two decades since it was pointed out that program testing may convincingly demonstrate the presence of bugs, but can never demonstrate their absence. After quoting this well-publicized remark devoutly, the software engineer returns to the order of the day and continues to refine his testing strategies, just like the alchemist of yore, who continued to refine his chrysocosmic purifications.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Nu stel je min/meer voor om dit met een regex te doen en een unit test te maken, en dat dan bewijs is dat het goed werkt. .........
ik zou de rest van het topic even lezen. Ik ben FEL tegen het oplossen van DIT probleem met regex.
Maar hoe je het probleem ook oplost. Dit is een typisch gevalletje van "we hebben iets, en we gaan het omvormen tot iets anders"

Voor zulke situaties is het gezond om eerst te kijken naar wat je eigenlijk wilt.
Welke eisen stelt jou functie (of setje functies) en wat is de gewenste uitkomst.
Wat is de verwachte foute uitkomst etc.
Voor die scenario's die je dan maakt bouw je een testje op een functie die er nog niet is.

Dan vervolgens ga je die functie maken, en je bent klaar als alle unittesten op groen staan. (en ja, natuurlijk mag je later scenario's toevoegen als test. Je hebt het niet in 1x goed, dat hoeft niet)
Dit proces heet test-driven development. Het werkt om deze redenen
1. je denkt na voordat je gaat bouwen
2. je hebt nu een geautomatiseerde test voor elk (complex) stukje werk, dus je code coverage schiet omhoog, waardoor je code aanpassingen in de toekomst veel minder risicovol zijn.
3 doordat de bouwer zelf test komt hij achter de valkuilen van zijn eigen code. Hij wordt gebruiker van zijn code

Let op:
Tuurlijk ga je geen getters en setters testen. Ik ben het 100% met je eens dat je alleen de wat ingewikkeldere dingen moet gaan testen. De rest is absoluut nutteloos.
Toevallig is een project waar wel met unit tests wordt gewerkt nu net het beroerdste project qua code dat ik heb gezien
Ik ga je een 101% garantie geven dat het maken van unittests niet 1 letter code slechter heeft gemaakt.
Echter zijn ZELFS unittests geen heilige graal.
Dat dacht je misschien, maar nee echt... dat is niet zo. Een slechte ontwikkelaar is een slechte ontwikkelaar. Laat die ontwikkelaar unittests schrijven en zijn code is niet opeens beter.

Ow en btw:
Ik denk dat jullie het goed doen als je uberhaupt code reviews doet.
Ik heb heel wat ontwikkelaars gezien die niet eens willen dat er iemand anders naar hun code kijkt. En waarvan de leidinggevende het nut er ook niet van ziet. "het werkt toch?" ;)

Ow en die mooie Dijkstra quote.
Je laat toevallig de voorgaande zin weg uit de quote (halve waarheid.. leugen *kuch*)
Besides the notion of productivity, also that of quality control continues to be distorted by the reassuring illusion that what works with other devices works with programs as well. ......... en dan jou quote
Hij had het hier dus over het toepassen van testmethodieken uit bestaande (niet software) omgevingen op software.
Test driven development bestond toen nog niet, en is juist gemaakt omdat men door had dat 'ouderwetse technieken' niet werkten

[ Voor 24% gewijzigd door BasieP op 16-10-2013 23:07 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

BasieP schreef op woensdag 16 oktober 2013 @ 21:34:
Taaltechnisch heb je soort van gelijk, maar jij en ik zijn het volgens mij eens over dat regex niet bedoeld is om (zoals in het voorbeeld) html te parsen met regex
Omdat HTML geen reguliere taal is, dus dan gebruik je geen reguliere parser generator. Dat kan nooit werken.
dus matching en replacing
Parsing is wel echt wat meer dan dat.
"Parsing or syntactic analysis is the process of analysing a string of symbols, either in natural language or in computer languages, according to the rules of a formal grammar." Dat is precies wat er gebeurt bij een regex: de regex is een formele (reguliere) grammatica, het stukje code erachter analyseert je input aan de hand van die regels; i.e., parsing.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
BasieP schreef op woensdag 16 oktober 2013 @ 22:52:
Test driven development bestond toen nog niet, en is juist gemaakt omdat men door had dat 'ouderwetse technieken' niet werkten
Dus een nieuwe teststrategie ;)
Ik ga je een 101% garantie geven dat het maken van unittests niet 1 letter code slechter heeft gemaakt.
Oneens, als in dit voorbeeld:
For example let’s take a hypothetical non-testable class library called ChartLib. There’s one class exposed, “Chart” with a constructor that takes care of whatever is necessary in the background to create itself. What goes on inside may be dirty, but it’s quick and easy!

By contrast, the testable version exposes Chart, ChartData, ChartFactory, ChartAssembler, ChartExtensions, ChartLogger, ChartMessenger, ChartReporter, ChartConfig, ChartPipeline, ChartUtils, IChartRepository …. and endless other classes and interfaces, each of which contain just as many vaguely-named methods of equally trivial relevance to anyone who only cares what a ‘Chart’ is.

Even once you’ve recognized the factory pattern in there, you realize that you have to also figure out how to construct and inject the configuration, the logger, the messenger (whatever that is) and all the other dependencies.

Statistically, the more code there is, the higher the chance of a problem occurring. Secondly, it’s less obvious how to consume the library by exploring it. With all those extra entities and exposed internals, it loses a lot of its self-description and it’s a lot easier for a developer to reference the wrong class or method by accident.

So I hereby present my theory: The Testability / Fallability Paradox.

The paradox is that unit-testable code is more likely to need testing than non-testable code.
Het probleem van TDD is dat het enige aantoonbare verschil de grotere initiële developmenttijd is, voor kwaliteit daarna is de situatie wellicht een beetje positief, en voor productiviteit is de situatie onbekend. De adoptie valt (daarom?) ook tegen. Bronnen: mijn ervaring, deze review uit 2010, en ik zie nu een nieuwe uit 2013, maar de situatie is niet veranderd: http://doi.ieeecomputersociety.org/10.1109/TSE.2012.28

offtopic:
Ik misbruik dit opgeloste draadje even voor deze offtopic-discussie, mochten er nog meer posts over TDD komen, dan wordt het wellicht tijd om te vragen om dit af te splitsen... Er hebben vast meer mensen een mening :p

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik vind unit tests wel handig; het geeft je wat meer zekerheid dat je wijzigingen toch niet ergens anders iets breken. Dat is vrijwel niet te doen om elke keer allemaal handmatig te gaan testen. Dat "een beetje rondklikken in de GUI" is dan iets dat automatisch gebeurt. Eigenlijk wat iedereen doet: wat test code om te kijken of je implementatie werkt. Waarom zou je dat er niet in laten zitten als unit test?

Ik vind die self-fulfilling prophecy trouwens nergens op slaan. Ja, quick and easy als blackbox: tot iemand de chart config aanpast en daardoor de chart messenger breekt waardoor je chart het niet meer doet. Veel succes weer met debuggen... en die encapsulatie kan je bv met friends regelen, dat normale code er niet bij kan. In goede code heeft sowieso alles een enkele, wel-gedefineerde verantwoordelijkheid.

Ik heb in de laatste maanden toch al een aantal keren gehad dat ik code in wou checken voor productie waarbij er een unit test faalde, en ik toen dacht "ohja, shit, dat kan ook nog". Overigens code die ook in code reviews niet werd opgemerkt als fout, omdat er geen een programmeur is die alle dependencies of mogelijke fouten ziet.

Overigens zeg ik niet dat je nu meteen puur TDD moet doen, maar belangrijke tests als automatische unit tests achter laten is weldegelijk nuttig. En die test code is vaak toch al geschreven.

[ Voor 7% gewijzigd door Zoijar op 17-10-2013 00:42 ]


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 10-09 18:14

alienfruit

the alien you never expected

Topicstarter
BasieP schreef op woensdag 16 oktober 2013 @ 18:18:
en je herdefineerd source...

var source = ..(source)...

je wil die buiten je var declaratie..

zelfde geld voor de variable 'json'
Klopt dat is expres...

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
En mag ik vragen waar jij denkt dat dit goed voor is?

Imho is het namelijk niet alleen nutteloos, maar zelfs fout. (in strict mode iig)

This message was sent on 100% recyclable electrons.

Pagina: 1