[alg] Slechtste programmeervoorbeelden deel 4 Vorige deel Overzicht Laatste deel

Dit topic is onderdeel van een reeks. Ga naar het meest recente topic in deze reeks.

Pagina: 1 ... 96 ... 103 Laatste
Acties:
  • 993.599 views

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

Lengte van een functie vind ik persoonlijk dan ook niet echt een hadnige metric (alhoewel ik 2 schermen belachelijk lang vind!). Cyclomatic complexity daarentegen is een veel betere. Door dat als metric te nemen krijgt een lange functie met alleen mapping code helemaal geen hoge score, terwijl een erg korte functie met belachelijk veel nesting een veel te hoge score krijgt. Streefdoel zou een waarde tussen de 2 a 3 gemiddeld per methode moeten zijn. Mensen die denken dat dat onhaalbaar is moeten eens een boek van Uncle Bob gaan lezen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Ik heb toevallig 2 afstudeerscripties over analyse van code geschreven (eerste op het HBO over analyse van een bestaande code-base, 2e op de TU over hoe je embedded sql kan analyseren). Ik heb daarbij nooit een voorbeeld kunnen vinden van Java of C/C++ code die een hoge cyclomatic complexity heeft, maar niet te lang is. Dus wat mij betreft is die discussie een non-issue: zolang je je functies fatsoenlijk opdeelt, zal je cyclomatic complexity ook beperkt zijn.

Als er al iets anders moet worden gemeten dan lengte, dan is het unstructured cyclomatic complexity: die is afgeleid van het gebruik van goto's en andere ongestructureerde manieren van programmeren.
Grijze Vos schreef op dinsdag 16 oktober 2012 @ 20:19:
2 schermen? wat mij betreft mag dat enkel en alleen als het gaat om heel simpele maar verbose code, zoals mapping code van datamodel naar viewmodel oid. Normaliter ligt de grens toch wel bij 1 scherm voor 1 functie.
Vandaar de grens op 2x op het scherm, "maar liever niet natuurlijk".
sig69 schreef op dinsdag 16 oktober 2012 @ 21:05:
[...]

2 schermen zegt ook niks natuurlijk. Welke resolutie? Welk font size? Op mijn scherm wordt dat een flinke functie namelijk
Dat is niet echt het punt, je mag er ook een getalletje aan hangen. Het idee is dat je iets wat niet in z'n geheel op je scherm past sowieso niet in 1x kan overzien. Dus als jij en jouw collega's allemaal de functie in 2x op het scherm kunnen zien, is het goed. En als je erover twijfelt of de functie te lang is: opsplitsen :+

Ach, bij mijn vorige opdracht zat ik regelmatig te wroeten in dispatcher-code van meer dan 1000 regels, waarbij de 'simpele' afhandeling direct in de dispatcher-functie stond. Allemaal handgeschreven, meeste cases voorzien van een break..., en elk (bijna) event stond in 3 functies :'( Het bestand was 15000 regels lang.

Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
.oisyn schreef op dinsdag 16 oktober 2012 @ 19:34:
[...]

Dan nog steeds niet. Uiteraard is het tweede tellertje dan j. Of x en y.
Maar als je bij de 'l' bent, moet je oppassen.
Dan weet je niet of het I of l is. :)

Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

i l I

;)

[ Voor 5% gewijzigd door kenneth op 17-10-2012 08:53 ]

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Keke.

Toch gek dat 'i' algemeen geaccepteerd is als index-variabele en dat er voor de rest dan gezeurd wordt over te korte variabelenamen die je niet kunt begrijpen.

Is er iemand die in zijn for-loopjes bewust een variabelenaam als "index" of "counter" gebruikt oid?

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Geen idee, ik gebruik altijd foreach (item in items) { ... } ;)

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 10:24
Davio schreef op woensdag 17 oktober 2012 @ 08:56:
Keke.

Toch gek dat 'i' algemeen geaccepteerd is als index-variabele en dat er voor de rest dan gezeurd wordt over te korte variabelenamen die je niet kunt begrijpen.

Is er iemand die in zijn for-loopjes bewust een variabelenaam als "index" of "counter" gebruikt oid?
Als ik niet voor mezelf programmeer? Zeker wel. Over het algemeen gaan for-loopjes en whathaveyou wel met variabelen die ik specifiek benoem én documenteer om zodoende ook voor de andere geeks (ja het zijn allemaal geeks in het bedrijf waar ik werk :P ) duidelijkheid te scheppen.

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 13:10

Matis

Rubber Rocket

Davio schreef op woensdag 17 oktober 2012 @ 08:56:
Keke.

Toch gek dat 'i' algemeen geaccepteerd is als index-variabele en dat er voor de rest dan gezeurd wordt over te korte variabelenamen die je niet kunt begrijpen.
Er zijn diverse static code analysers die daar over vallen inderdaad en ik ben het daar wel mee eens.
Is er iemand die in zijn for-loopjes bewust een variabelenaam als "index" of "counter" gebruikt oid?
In for loopjes kun je binnen C99 in ieder geval beter geen gebruik maken van het woord index als variabele, omdat het mogelijk verwarring kan scheppen met de functie index.
Zelf gebruik ik altijd idx als index-counter bij enkelvoudige for-loopjes.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • Struikrover
  • Registratie: Juni 2005
  • Laatst online: 14-09 13:09
Davio schreef op woensdag 17 oktober 2012 @ 08:56:
Keke.

Toch gek dat 'i' algemeen geaccepteerd is als index-variabele en dat er voor de rest dan gezeurd wordt over te korte variabelenamen die je niet kunt begrijpen.

Is er iemand die in zijn for-loopjes bewust een variabelenaam als "index" of "counter" gebruikt oid?
Zoals hierboven ook al genoemd wordt inderdaad, gebruik vaak 'idx' in enkele for loops. Vaker gebruik ik foreach, en dan is het zinvol om een enkelvoud de nemen van de naam waarover je loopt. Bijvoorbeeld:

PHP:
1
2
3
4
foreach($values as $value)
{
//code
}

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

MBV schreef op dinsdag 16 oktober 2012 @ 23:44:
Ik heb toevallig 2 afstudeerscripties over analyse van code geschreven (eerste op het HBO over analyse van een bestaande code-base, 2e op de TU over hoe je embedded sql kan analyseren). Ik heb daarbij nooit een voorbeeld kunnen vinden van Java of C/C++ code die een hoge cyclomatic complexity heeft, maar niet te lang is. Dus wat mij betreft is die discussie een non-issue: zolang je je functies fatsoenlijk opdeelt, zal je cyclomatic complexity ook beperkt zijn.
Werkelijk?

Java:
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
27
28
29
public Object convert(Object destination, Object source, Class<?> destClass, Class<?> sourceClass) {
    if (source == null) return null;
    if (source instanceof JAXBElement<?>) return mapper.map(((JAXBElement<?>) source).getValue(), destClass);
    if (destClass == JAXBElement.class) {
        ObjectFactory objectFactory = new ObjectFactory();
        if (source instanceof Leveringen) {
            return objectFactory.createOpvragenLeveringResponse(mapper.map(source,
                JaxbOpvragenLeveringResponse.class));
        }
        if (source instanceof JaxbVastleggenLeveringRequest) {
            return objectFactory.createVastleggenLeveringRequest((JaxbVastleggenLeveringRequest) source);
        }
        String classSimpleName = sourceClass.getSimpleName();
        Method method = ReflectionUtils.getMethod(objectFactory, "create" + classSimpleName);
        Class destActualClass;
        try {
            if(classSimpleName.startsWith("Jaxb")){
                Class.forName(objectFactory.getClass().getPackage().getName() + "." + classSimpleName);         
                return destination;
            }else{
                destActualClass = Class.forName(objectFactory.getClass().getPackage().getName() + ".Jaxb" + classSimpleName);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return ReflectionUtils.invoke(method, objectFactory, new Object[] { mapper.map(source, destActualClass) });
    }
    return null;
}


Heb ik net even via Sonar uit een project hier gevist (Project waar mbt de code kwaliteit een berg alarmbellen af gingen ;) ). Voldoet aan de 'alles op 1 scherm', maar heeft toch een whooping complexity van 15.

Het voordeel van cyclomatic complexity is dat het daarwerkelijk de complexiteit meet. Een wat langere methode welke niet complex is, is beter leesbaar dan een korte methode met veel geneste strukturen. En dat lijkt me juist wat je zou willen bereiken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 07:55
Ik gebruik 'i' in plaats van 'idx' omdat die extra letters niets toevoegen. Vrijwel alle programmeurs zijn er wel mee bekend, het is duidelijk wat het is en buiten de loop dient het ook geen enkel belang meer, dus waarom zou je dat uitgebreid documenteren? In code weliswaar. Oké, dan praat ik niet over i vs. idx, maar over een nog langere, beter beschrijvende naam.

[ Voor 14% gewijzigd door Jaap-Jan op 17-10-2012 09:28 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 10:24
Jaap-Jan schreef op woensdag 17 oktober 2012 @ 09:27:
Ik gebruik 'i' in plaats van 'idx' omdat die extra letters niets toevoegen. Vrijwel alle programmeurs zijn er wel mee bekend, het is duidelijk wat het is en buiten de loop dient het ook geen enkel belang meer, dus waarom zou je dat uitgebreid documenteren? In code weliswaar. Oké, dan praat ik niet over i vs. idx, maar over een nog langere, beter beschrijvende naam.
Ik vind het juist altijd wel fijn als je aangeeft WAT je precies aan't tellen bent. Maar ik snap je punt en op zich is het geen ramp om het één of het ander te doen.
Korte namen hebben wel een voordeel: De code neemt minder sch(r)ijfruimte in! :+ :P

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Janoz schreef op woensdag 17 oktober 2012 @ 09:24:
[...]

Werkelijk?

Java:
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
27
28
29
public Object convert(Object destination, Object source, Class destClass, Class sourceClass) {
    if (source == null) return null;
    if (source instanceof JAXBElement) return mapper.map(((JAXBElement) source).getValue(), destClass);
    if (destClass == JAXBElement.class) {
        ObjectFactory objectFactory = new ObjectFactory();
        if (source instanceof Leveringen) {
            return objectFactory.createOpvragenLeveringResponse(mapper.map(source,
                JaxbOpvragenLeveringResponse.class));
        }
        if (source instanceof JaxbVastleggenLeveringRequest) {
            return objectFactory.createVastleggenLeveringRequest((JaxbVastleggenLeveringRequest) source);
        }
        String classSimpleName = sourceClass.getSimpleName();
        Method method = ReflectionUtils.getMethod(objectFactory, "create" + classSimpleName);
        Class destActualClass;
        try {
            if(classSimpleName.startsWith("Jaxb")){
                Class.forName(objectFactory.getClass().getPackage().getName() + "." + classSimpleName);         
                return destination;
            }else{
                destActualClass = Class.forName(objectFactory.getClass().getPackage().getName() + ".Jaxb" + classSimpleName);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return ReflectionUtils.invoke(method, objectFactory, new Object[] { mapper.map(source, destActualClass) });
    }
    return null;
}


Heb ik net even via Sonar uit een project hier gevist (Project waar mbt de code kwaliteit een berg alarmbellen af gingen ;) ). Voldoet aan de 'alles op 1 scherm', maar heeft toch een whooping complexity van 15.
Wat mij al meteen vertelt dat cyclomatic complexity dus een waardeloze metric is, want die functie wordt er echt niet leesbaarder op door 'm op te gaan zitten delen. Ik zou die derde if wel omdraaien om er zo een early-out van te maken, net als de vorige twee ifs.

Verder ben ik persoonlijk wel fan van meer witregels, maar goed, dat is zoals gezegd dus persoonlijk :)
Java:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public Object convert(Object destination, Object source, Class destClass, Class sourceClass)
{ 
    if (source == null)
        return null; 
        
    if (source instanceof JAXBElement)
        return mapper.map(((JAXBElement) source).getValue(), destClass); 
        
    if (destClass != JAXBElement.class)
        return null;
    
    ObjectFactory objectFactory = new ObjectFactory(); 
    if (source instanceof Leveringen)
        return objectFactory.createOpvragenLeveringResponse(mapper.map(source, 
            JaxbOpvragenLeveringResponse.class)); 

    if (source instanceof JaxbVastleggenLeveringRequest)
        return objectFactory.createVastleggenLeveringRequest((JaxbVastleggenLeveringRequest) source); 

    String classSimpleName = sourceClass.getSimpleName(); 
    Method method = ReflectionUtils.getMethod(objectFactory, "create" + classSimpleName); 
    Class destActualClass; 
    try
    { 
        if(classSimpleName.startsWith("Jaxb"))
        { 
            Class.forName(objectFactory.getClass().getPackage().getName() + "." + classSimpleName);             
            return destination; 
        }
        else
        { 
            destActualClass = Class.forName(objectFactory.getClass().getPackage().getName() + ".Jaxb" + classSimpleName); 
        } 
    }
    catch (ClassNotFoundException e)
    { 
        throw new RuntimeException(e); 
    } 
    
    return ReflectionUtils.invoke(method, objectFactory, new Object[] { mapper.map(source, destActualClass) }); 
}

[ Voor 29% gewijzigd door .oisyn op 17-10-2012 09:55 ]

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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

i is in mijn opinie een volledig acceptabele korte schrijfwijze voor index. Ook het gebruiken van j en k voor inner loops. Hetzelfde geldt bijvoorbeeld ook voor x,y en z. Of wat dacht je bijvoorbeeld van een implementatie van de wortelformule? In dat geval lijkt het mij ook erg logisch om a b en c als parameters te hebben.
.oisyn schreef op woensdag 17 oktober 2012 @ 09:51:
[...]

Wat mij al meteen vertelt dat cyclomatic complexity dus een waardeloze metric is, want die functie wordt er echt niet leesbaarder op door 'm op te gaan zitten delen.
De functie is sowieso ruk. Om dit werkbaarder en onderhoudbaar te krijgen zul breder aanpassingen moeten doen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom? Ik vind 'm duidelijk leesbaar, ik snap goed wat er gebeurt ookal weet ik totaal niets van het project waar het in zit of wat al die classes representeren of het feit dat er geen enkele comment in staat.

Wellicht dat het overall design van het project idd niet goed in elkaar zit, getuige de instanceof's of de check of een classnaam begint met "Jaxb", maar dat is eigenlijk irrelevant voor de discussie die we nu aan het voeren zijn.

[ Voor 35% gewijzigd door .oisyn op 17-10-2012 10:00 ]

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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

Discussie ging over de kwaliteit van code gemeten adhv de lengte van methoden, waarop ik aangeef dat CC een betere metric is, waarop MBV reageert dat hij nog nooit een korte methode met hoge CC gezien heeft, waarop ik weer reageer met een relatief korte methode met zeer hoge CC die ik uit het wild gevist heb. Lijkt me een redelijk relevante opeenvolging ;).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

En ik zeg vervolgens dat ik CC dus geen goede metric vindt want die functie is best leesbaar, waarop jij reageert dat het hele project niet deugt. Da's prima, maar dat is nog geen argument tegen mijn stelling :)

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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

Oh zo, maar mijn reactie sloeg op de
Wat mij al meteen vertelt dat cyclomatic complexity dus een waardeloze metric is, want die functie wordt er echt niet leesbaarder op door 'm op te gaan zitten delen.
, en daar reageer ik op.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Je moet gewoon zorgen dat je de enige bent die het begrijpt.

Dan zul je je baan tot in lengte van dagen kunnen houden of de volgende dag een andere baan zoeken, afhankelijk van het bedrijf en de kennis van de collega's / managers. :)

Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
Davio schreef op woensdag 17 oktober 2012 @ 10:37:
Je moet gewoon zorgen dat je de enige bent die het begrijpt.

Dan zul je je baan tot in lengte van dagen kunnen houden
Of je daar nou blij van moet worden...? Ik krijg soms nog vragen over een project waar ik anderhalf jaar terug voor het laatst aan heb gewerkt...

We are shaping the future


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Hey, 't is crisis hoor! :D

Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Sssst Davio, er lezen managers mee O-)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
kenneth schreef op woensdag 17 oktober 2012 @ 10:43:
Sssst Davio, er lezen managers mee O-)
Ja, die hebben immers tijd zat, omdat ze zelf niet programmeren. :)

Acties:
  • 0 Henk 'm!

  • Waster
  • Registratie: September 2006
  • Laatst online: 14-04 17:49
Janoz schreef op woensdag 17 oktober 2012 @ 09:24:
[...]

Werkelijk?

Java:
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
27
28
29
public Object convert(Object destination, Object source, Class<?> destClass, Class<?> sourceClass) {
    if (source == null) return null;
    if (source instanceof JAXBElement<?>) return mapper.map(((JAXBElement<?>) source).getValue(), destClass);
    if (destClass == JAXBElement.class) {
        ObjectFactory objectFactory = new ObjectFactory();
        if (source instanceof Leveringen) {
            return objectFactory.createOpvragenLeveringResponse(mapper.map(source,
                JaxbOpvragenLeveringResponse.class));
        }
        if (source instanceof JaxbVastleggenLeveringRequest) {
            return objectFactory.createVastleggenLeveringRequest((JaxbVastleggenLeveringRequest) source);
        }
        String classSimpleName = sourceClass.getSimpleName();
        Method method = ReflectionUtils.getMethod(objectFactory, "create" + classSimpleName);
        Class destActualClass;
        try {
            if(classSimpleName.startsWith("Jaxb")){
                Class.forName(objectFactory.getClass().getPackage().getName() + "." + classSimpleName);         
                return destination;
            }else{
                destActualClass = Class.forName(objectFactory.getClass().getPackage().getName() + ".Jaxb" + classSimpleName);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return ReflectionUtils.invoke(method, objectFactory, new Object[] { mapper.map(source, destActualClass) });
    }
    return null;
}


Heb ik net even via Sonar uit een project hier gevist (Project waar mbt de code kwaliteit een berg alarmbellen af gingen ;) ). Voldoet aan de 'alles op 1 scherm', maar heeft toch een whooping complexity van 15.

Het voordeel van cyclomatic complexity is dat het daarwerkelijk de complexiteit meet. Een wat langere methode welke niet complex is, is beter leesbaar dan een korte methode met veel geneste strukturen. En dat lijkt me juist wat je zou willen bereiken.
Welke verbeteringen stel je dan voor? Opdelen in nog meer functies gaat deze code niet leesbaarder maken denk ik.

Een goede functie heeft een zelfbeschrijvende naam en is doelmatig en to-the-point. Het voorbeeld dat jij gaf is gewoon heel erg slechte code en past ook perfect hier thuis. Hoe kun je een algemene convert methode schrijven die type object returned, maar toch in het model domein prikt?

createVastleggenLeveringRequest, JABX objecten en andere onzin.

Ik denk dat lange en onduidelijke routines vanzelf ontstaan door slecht class design en slechte abstractie. Dan moet je door een paar lagen abstractie heenprikken, in internals gaan wroeten en met if en for loops je informatie te pakken zien te krijgen en dan weer casten. Dat is volgens mij ook precies wat hier gebeurt. Met goede abstractie worden je functies automatisch overzichtelijker en kleiner.

Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Ik kijk in de designer naar een TabControl. Hmm, tabPage3 is een slechte naam, laat ik hem foobarTabPage noemen, de gegevens erop gaan immers over foobar. Refactor -> Rename *O*

Hmm, het werkt niet meer, even in de code behind kijken.
C#:
1
if (this.medewerkerTabControl.SelectedTab.Name == "tabPage3")


:F

Ik heb er maar dit van gemaakt:
C#:
1
if (this.medewerkerTabControl.SelectedTab == foobarTabPage)


En het control staat verder nog vol met panel1, button4, textBox3, enz ...

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Het mooiste is als ze in de layout dan ook niet meer logisch staan, omdat ze na het toevoegen heen en weer gesleept zijn.

Dan heb je van boven naar beneden bijvoorbeeld textBox2, textBox3 en textBox1. :F

Acties:
  • 0 Henk 'm!

  • Not Pingu
  • Registratie: November 2001
  • Laatst online: 05-08 09:21

Not Pingu

Dumbass ex machina

Davio schreef op woensdag 17 oktober 2012 @ 11:53:
Het mooiste is als ze in de layout dan ook niet meer logisch staan, omdat ze na het toevoegen heen en weer gesleept zijn.

Dan heb je van boven naar beneden bijvoorbeeld textBox2, textBox3 en textBox1. :F
En de tabindex die volledig door elkaar loopt, dus als je door een form heen tabt spring je van hot naar her.

Certified smart block developer op de agile darkchain stack. PM voor info.


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Variabelennaamgeving is ook een terugkerend topic blijkbaar? :+

In een foreach of lambda gebruik ik, zeker als het toch maar één regel is, stiekem lekker toch éénletterige variabelen:
C#:
1
2
3
4
5
6
7
8
foreach (var o in Objects)
{
    o.Foo();
}

// of

Objects.ForEach(o => o.Foo());


Houdt het wat mij betreft net zo leesbaar, zo mogelijk soms zelfs leesbaarder dan de naam voluit schrijven. Dan moet je weer gaan zitten turen waar je nu Object en waar je Objects aanspreekt.

Als echter gegenereerde namen niet veranderd worden, haal je het bloed onder m'n nagels vandaan. Klasse Foo in bestand Class1.cs? }:| Project1.sln? :( TextBox1? |:(

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Als Foo nu een parameter slikt met het object (wat vaak ook zal zijn).

C#:
1
Objects.ForEach(Foo);

[ Voor 33% gewijzigd door Megamind op 17-10-2012 16:55 ]


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Janoz schreef op woensdag 17 oktober 2012 @ 09:24:
[...]

Werkelijk?

Java:
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
27
28
29
public Object convert(Object destination, Object source, Class<?> destClass, Class<?> sourceClass) {
    if (source == null) return null;
    if (source instanceof JAXBElement<?>) return mapper.map(((JAXBElement<?>) source).getValue(), destClass);
    if (destClass == JAXBElement.class) {
        ObjectFactory objectFactory = new ObjectFactory();
        if (source instanceof Leveringen) {
            return objectFactory.createOpvragenLeveringResponse(mapper.map(source,
                JaxbOpvragenLeveringResponse.class));
        }
        if (source instanceof JaxbVastleggenLeveringRequest) {
            return objectFactory.createVastleggenLeveringRequest((JaxbVastleggenLeveringRequest) source);
        }
        String classSimpleName = sourceClass.getSimpleName();
        Method method = ReflectionUtils.getMethod(objectFactory, "create" + classSimpleName);
        Class destActualClass;
        try {
            if(classSimpleName.startsWith("Jaxb")){
                Class.forName(objectFactory.getClass().getPackage().getName() + "." + classSimpleName);         
                return destination;
            }else{
                destActualClass = Class.forName(objectFactory.getClass().getPackage().getName() + ".Jaxb" + classSimpleName);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return ReflectionUtils.invoke(method, objectFactory, new Object[] { mapper.map(source, destActualClass) });
    }
    return null;
}


Heb ik net even via Sonar uit een project hier gevist (Project waar mbt de code kwaliteit een berg alarmbellen af gingen ;) ). Voldoet aan de 'alles op 1 scherm', maar heeft toch een whooping complexity van 15.

Het voordeel van cyclomatic complexity is dat het daarwerkelijk de complexiteit meet. Een wat langere methode welke niet complex is, is beter leesbaar dan een korte methode met veel geneste strukturen. En dat lijkt me juist wat je zou willen bereiken.
Ja, werkelijk. Ook op code-bases waarvan alle alarmbellen afgingen. Ik geef toe dat er wel een stuk of 3 uitzonderingen waren (in de categorie waar jij een voorbeeld van geeft), maar op 5 miljoen regels code is dat niet echt significant.
Waster schreef op woensdag 17 oktober 2012 @ 11:12:
[...]

Welke verbeteringen stel je dan voor?
[knip]

Met goede abstractie worden je functies automatisch overzichtelijker en kleiner.
Je geeft zelf al het goede antwoord op je vraag. Zodra je dit soort functies gaat schrijven en vervolgens er code in gaat zetten die meer doet dan alleen converteren, dan is alle hoop verloren, ongeacht de lengte, cyclomatic complexity, etc.

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 08:57
Eigen werk :')

Voor een klant twee api's aan elkaar aan het knopen, zo goed als klaar (eindelijk) het is gewoon data heen en weer synchroniseren tussen twee webdiensten, in de ene kan je dynamisch formulieren maken zeg maar met data. En de volgorde van synchroniseren ging fout (e.g het had straat,plaats,postcode,land moeten zijn) maar het was iets anders.

Toen dacht de klant slim te zijn door velden in de dynamische formulieren aan te passen om het probleem op te lossen. En dat systeem kan enkel de beschrijvingen aanpassen als er al data in staat kan er geen veldnaam veranderd worden.. dus nu klopt het configuratiebestand niet meer met wat het doet.

En het fixen is niet echt te doen aangezien er al 5k records in sync staan... :/

Afbeeldingslocatie: http://cl.ly/KE0V/oelalala.png

Dus nu maar met commentaar opgelost.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • vpm
  • Registratie: December 2010
  • Laatst online: 18-09 19:25

vpm

Think, tinker, tank

ZpAz schreef op woensdag 17 oktober 2012 @ 21:25:
Eigen werk :')

Voor een klant twee api's aan elkaar aan het knopen, zo goed als klaar (eindelijk) het is gewoon data heen en weer synchroniseren tussen twee webdiensten, in de ene kan je dynamisch formulieren maken zeg maar met data. En de volgorde van synchroniseren ging fout (e.g het had straat,plaats,postcode,land moeten zijn) maar het was iets anders.

Toen dacht de klant slim te zijn door velden in de dynamische formulieren aan te passen om het probleem op te lossen. En dat systeem kan enkel de beschrijvingen aanpassen als er al data in staat kan er geen veldnaam veranderd worden.. dus nu klopt het configuratiebestand niet meer met wat het doet.

En het fixen is niet echt te doen aangezien er al 5k records in sync staan... :/

Dus nu maar met commentaar opgelost.
Punctuation is a bitch, huh?

OT: klinkt het als een interessant systeem. Ik zie alleen niet in hoe iets dergelijks foutief gesynct kan worden.

Acties:
  • 0 Henk 'm!

  • ZpAz
  • Registratie: September 2005
  • Laatst online: 08:57
In de ene kant zijn het losse velden in de andere kant één veld. De volgorde van de losse velden 'links (podio)' kwamen verkeerd in 'rechts (harvest)'.

En iets fout, mja het is een vrij uitgebreid systeem enkel de config file om het aan elkaar te knopen is al 400 regels code. Aangezien de applicaties dynamisch kunnen worden aangemaakt in Podio, met elk dynamische veldnamen, type velden e.d. en ik het zo wilde opzetten dat je enkel bij het aangeven via een config welke data uit welke 'podio applicatie' naar welke 'applicatie' binnen harvest moest zonder dit 'hardcoded' aan te geven.

Tweakers Time Machine Browser Extension | Chrome : Firefox


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
CodeCaster schreef op woensdag 17 oktober 2012 @ 16:33:
Objects.ForEach(o => o.Foo());
[/code]
*zucht*. iets met side effects enzo.

[ Voor 18% gewijzigd door Grijze Vos op 18-10-2012 08:51 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Jaap-Jan schreef op woensdag 17 oktober 2012 @ 09:27:
Ik gebruik 'i' in plaats van 'idx' omdat die extra letters niets toevoegen. Vrijwel alle programmeurs zijn er wel mee bekend, het is duidelijk wat het is en buiten de loop dient het ook geen enkel belang meer, dus waarom zou je dat uitgebreid documenteren? In code weliswaar. Oké, dan praat ik niet over i vs. idx, maar over een nog langere, beter beschrijvende naam.
Elke programmeur is ook bekend met for (int i = 0; i < 100; i++) { }, maar dat betekent niet dat het overmatig complex is, in vergelijking met functionele equivalenten als map() of each(). (bij for-loops werk je immers met veel side-effects; initialisatie, bijhouden, checken van een index, elementen in-order uit een array of lijst halen, etc).

Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 14:21

GrimaceODespair

eens een tettenman, altijd ...

Ik kom dus volgend commentaar tegen in de frameworkcode van .NET:
Please note that [...] is an internal static method in System.Configuration.dll. If we want to call that here, we have to use reflection and that's what we want to avoid.
Om vervolgens dit te doen:
C#:
1
2
Type typeFactory = Type.GetType(InternalConfigSettingsFactoryTypeString, true); 
s_configSettingsFactory = (IInternalConfigSettingsFactory) Activator.CreateInstance(typeFactory, true);


Lijkt mij toch een vorm van reflectie, maar goed. Het ergste is de opmerking die ze over hun eigen code maken: "which is an internal static method", zodat ze een lelijke workaround moeten implementeren. HET HELE FREAKING FRAMEWORK is opgebouwd uit internal static methodes! Ik word er echt totaal krankjorum van.

Omdat ze geen zin hebben om na te denken over een fatsoenlijk architectuur, maken ze er maar wat globale spaghetti van die ze afschermen met internal, een constructie over welk bestaansrecht je uitgebreid kunt discussieren.

Sorry, maar ik moest het ff kwijt. Zit al 3 dagen aan te hikken tegen de blackbox die .NET heet.

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 10:08

Haan

dotnetter

GrimaceODespair schreef op donderdag 18 oktober 2012 @ 14:17:
Sorry, maar ik moest het ff kwijt. Zit al 3 dagen aan te hikken tegen de blackbox die .NET heet.
Dé voornaamste eigenschap van een blackbox is dat je niet kunt zien wat er binnenin gebeurt. Hier heb je de source code inclusief comments, dus daar is weinig ondoorzichtbaars aan ;)

Verder wel benieuwd wat je dan zoal uitspookt dat je hier last van zou hebben?

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

Verwijderd

Deze kwam ik tegen op onstage.xebic.com ;(
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var err= "";
        
        function locateAppWindow(win)
        {
            try
            {
                var parent = win.parent;
                if (win != parent)
                {
                    var pApp = parent.Application;
                    if (pApp || !win.Application)
                    {
                        return locateAppWindow(parent);
                    }
                }
            }
            catch (ex)
            { }
            return win;
        }

Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 14:21

GrimaceODespair

eens een tettenman, altijd ...

Haan schreef op donderdag 18 oktober 2012 @ 14:37:
[...]

Dé voornaamste eigenschap van een blackbox is dat je niet kunt zien wat er binnenin gebeurt. Hier heb je de source code inclusief comments, dus daar is weinig ondoorzichtbaars aan ;)

Verder wel benieuwd wat je dan zoal uitspookt dat je hier last van zou hebben?
Vanuit ANSI C# (bestaat er eigenlijk zoiets?) gezien is het een blackbox ;)

Eigenlijk heb ik alleen hun standaard VirtualPathProvider provider nodig om een methode te testen die een VirtualPathProvider gebruikt. Die is dus van het type MapPathBasedVirtualPathProvider, een internal class. En dat hebben ze dus alleen maar internal gemaakt, omdat het zo slecht in elkaar zit dat het niet te isoleren valt. Dus heb ik maar mijn eigen PhysicalPathProvider gemaakt.

Vervolgens gebruikt de methode die ik probeer te testen ook nog ViewEngine.FindView, een methode die een cascade van internals, statics, sealeds en privates genereert.

Er is van dat hele framework zo ongeveer niks te isoleren of eenvoudig te mocken. Je vind online wel voorbeeld van gedeeltelijke mocks, maar die gaan niet ver genoeg voor mijn scenario.

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Ik zou zeggen, schrijf je eigen taal. :9

Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 14:21

GrimaceODespair

eens een tettenman, altijd ...

Davio schreef op donderdag 18 oktober 2012 @ 15:03:
Ik zou zeggen, schrijf je eigen taal. :9
Een eigen taal niet, een fatsoenlijk framework zou ik graag wel doen ;)

Maar ik vraag me serieus af wat voor soort developers daar in het team zitten. Ik weet dat ze een paar grote lichten hebben rondlopen die de architectuur uitdenken, maar het lijkt wel alsof ze het implementeren ervan als "dom klopwerk" beschouwen. Tenminste, zo laat de code zich lezen. Ik kan me nauwelijks voorstellen dat zoiets onderhoudbaar is...

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • Davio
  • Registratie: November 2007
  • Laatst online: 06-01 16:46
Ik denk dat het uiteindelijk een beetje is zoals in elk bedrijf: In een ideale wereld creëer je de meest elegante en bugvrije software en kun je daar een eeuwigheid over doen en oneindig veel geld aan besteden. In de praktijk heb je te maken met deadlines, verschil in kennis tussen collega's, communicatieve fouten en ga zo maar door.

Natuurlijk zal een bedrijf als Microsoft er alles aan moeten doen om waardeloze code te voorkomen, maar ook de Microsoft developers zijn niet perfect......hmm, zal mijn cv eens sturen. :)

Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 14:21

GrimaceODespair

eens een tettenman, altijd ...

Davio schreef op donderdag 18 oktober 2012 @ 15:13:
Ik denk dat het uiteindelijk een beetje is zoals in elk bedrijf: In een ideale wereld creëer je de meest elegante en bugvrije software en kun je daar een eeuwigheid over doen en oneindig veel geld aan besteden. In de praktijk heb je te maken met deadlines, verschil in kennis tussen collega's, communicatieve fouten en ga zo maar door.
Ik snap ook wel dat je niet altijd de schoonheidsprijs kunt verdienen met je code, maar ik zie ook het verschil tussen code die is neergezet door een genie en code die door een mindere god is ingeklopt en dan nog code die er alleen staat "zodat het werkt". Ik kan er zo moeilijk bij dat je met het potentieel dat MS heeft (lees: $$$) toch niet beter kan dan wat je in het framework overal tegenkomt.

Zal wel weer aan mij liggen en mijn ideaalbeeld van de wereld ;)

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • mcDavid
  • Registratie: April 2008
  • Laatst online: 09-09 17:48
GrimaceODespair schreef op donderdag 18 oktober 2012 @ 15:46:
[...]

Ik snap ook wel dat je niet altijd de schoonheidsprijs kunt verdienen met je code, maar ik zie ook het verschil tussen code die is neergezet door een genie en code die door een mindere god is ingeklopt en dan nog code die er alleen staat "zodat het werkt". Ik kan er zo moeilijk bij dat je met het potentieel dat MS heeft (lees: $$$) toch niet beter kan dan wat je in het framework overal tegenkomt.

Zal wel weer aan mij liggen en mijn ideaalbeeld van de wereld ;)
sja wij simpele zielen zien "winst" als een middel om meer personeel in te huren zodat iedereen meer tijd heeft om het product te verbeteren en leuker te maken. In de grote boze beursgenoteerde bedrijvenwereld is "winst" echter niet meer dan een middel om aandeelhouders aan een groter huis te helpen. Iedere gewerkte seconde zonder duidelijk resultaat, is weer een dakpan minder.

Acties:
  • 0 Henk 'm!

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
GrimaceODespair schreef op donderdag 18 oktober 2012 @ 14:51:
[...]

Vanuit ANSI C# (bestaat er eigenlijk zoiets?) gezien is het een blackbox ;)

Eigenlijk heb ik alleen hun standaard VirtualPathProvider provider nodig om een methode te testen die een VirtualPathProvider gebruikt. Die is dus van het type MapPathBasedVirtualPathProvider, een internal class. En dat hebben ze dus alleen maar internal gemaakt, omdat het zo slecht in elkaar zit dat het niet te isoleren valt. Dus heb ik maar mijn eigen PhysicalPathProvider gemaakt.

Vervolgens gebruikt de methode die ik probeer te testen ook nog ViewEngine.FindView, een methode die een cascade van internals, statics, sealeds en privates genereert.

Er is van dat hele framework zo ongeveer niks te isoleren of eenvoudig te mocken. Je vind online wel voorbeeld van gedeeltelijke mocks, maar die gaan niet ver genoeg voor mijn scenario.
Maar het is mij nog steeds onduidelijk wat je precies wil. Ik ken de VirtualPathProvider niet maar wat ik wel weet is dat 9 van de 10 keer mensen die dit soort problemen hebben zelf verkeerd zitten.

C# is een ISO standaard en er zijn maar weinig andere Microsoft producten die zo uitvoerig zijn gedocumenteerd en waarvan code beschikbaar is. De blackbox opmerking is mij dan ook een raadsel.

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

*zucht*. Mijn post ging over variabelennaamgeving, en ik wilde even snel een lambda tikken. Lees het dan maar als Objects.Where(o => o.Foo == bar);.


Ik last dit stukje op dat blog:
code:
1
foreach(Foo foo in foos){ statement involving foo; }

als "statement involving plankton". :P

[ Voor 18% gewijzigd door CodeCaster op 18-10-2012 19:44 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • flux_w42
  • Registratie: November 2006
  • Laatst online: 07-09-2024

flux_w42

jah, nu is het helemaal kapot

Vandaag iets grappigs tegengekomen: Blijkbaar bestaat er een contest om zo slecht mogelijk leesbare C code te maken :D "The International Obfuscated C Code Contest"
Goals of the Contest
  • To write the most Obscure/Obfuscated C program within the rules.
  • To show the importance of programming style, in an ironic way.
  • To stress C compilers with unusual code.
  • To illustrate some of the subtleties of the C language.
  • To provide a safe forum for poor C code. :-)
En tussen de inzendingen zitten echt briljante stukjes code die - ongelofelijk maar waar - perfect compilen met gcc _/-\o_

Enkele voorbeeldjes:

C:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
                                                      #include<stdio.h>
                                                typedef unsigned int _;_ d,b,
                                           #define i(I1,Il,lI)if(Il){lI;}else{I1;}
                                         I[256],            n,y,a,r,u,k,o
                                       ,L,l[                    256],O,K[
                                      /**/                      #define\
                                      q(g)                      g char\
                                      *C,                          *Q,c[\
                                      ]=                              "KfW"\
                                      ""                            "Ww|"\
                                       /*                              'UU!\
                                        %                                NYA!\
                                        */                                 "Z}"\
                                 ";fRo?JtJaV<x4@*?R?&JV1"                        ".s"\
                             "{Fyj2_;khB1xQ5oxm~mS@B|(pa>oRU"                         "Ro"\
                          "nB}h@o?)d.X)NSTIUCz7@%",*s[]={c,"#en"                        "di"\
                       "f/*}||1;\n__DATA__\40*/\n\n#ifndef\40q\n#d"                      "ef"\
                      "ine\x20q\n#include<stdio.h>\ntypedef\40unsign"                          "e"\
                    "d\x20int\x20_;_\x20K[]={\n#include\40__FILE__\n#u"                     "n"\
                   "def q","0},L,O,l[256],I[256],n,y,a,r,u,k,o;"#g"char"                     "*"\
                 "S,s[]=\"",c,c,"\";int main(){X();for(S=s+*K;*S>37;){for"                   "(o"\
                "=0;o<5;o++)r=r*85+(83+*S++)%89;r","^=*x();for(o=0;o<4;o++"                   ")"\
                "{s[O++]=r&255;r>>=8;}}return!fwrite(s,O-*S%5,1,stdout);}\n"                       "#"\
               "endif",c},S[256]="#ifdef/*\n'true'\40or\40q{\nexec\40head\40"                      "-"\
              "8\40$0\n};for(open$O,$0;<$O>;print\40if$f){$f|=/^$/;}q{*/q",/*                       */z;
              256];q(_*x(){if(!L--){y+=++a;for(o=0;o<256;y=l[o++]=I[255&(k>>10                      )]+u
              ){n^=(o&1)?n>>(( o& 2)?16:6):n<<((o&2)?2:13);u=I[o];k=I[o]=I[255&                     (u>>
             2)]+(n+=I[(o+128)  &   255]) +y;}L=255;}return&l[L];}_*X(){for(O=0                     ;256
            >O;I[O++]=0);for(O   =     0;   sizeof(K)/sizeof( _)> O;O++)I[O&255]                    ^=K[
            O];for(n=y=a=L=O=0 ;O<1<<24;++   O)x( );r=O=0x0; return&O;})int/*^^*/                   main
           (int p,char**P){FILE* Z=fopen(p>    (+  1)?P[01   ]   :"/dev/urandom",                   "rb"
          );i(;,Z,O=fread(K,256  ,4,Z);/*P          */     fclose(Z))X();for(p=b=d                  =O=
          0;O<256;K[O++]=0)*K=+  86;for(O                =1;12> O;K[O++]=*x());X();                 for
         (C=Q=S;r-8;){i(*C++=34,  (r-4&&r               -5)||C- S ,;)z=Q[p++];i(;,z                 !=
        32||r-3,i(i(C+=sprintf((    C),                 "%uU"    ",",K[b++]);i(d=1;C                   =S
       ;i(d=02,b-12,;),b%6,;),r-1                       ,i(b=   fread(c,1,4,stdin);i                   (p
       =O=0,b,for(d=O=0;O<04;O++)d                             +=(c[O]&255)<<(8*O);d                  ^=
      *x();for(p=5;p;c[--p]=O<32?O+                            95:O+6){O=d%85;d/=85;}                O=
     5)i(d=0,b<4,c[O++]=b?b-1?b-2?36:      37:33:35           ;d=2)c[O]=0,r-4,i(i (d=                2
    |d,C!=S+6,*C++=(*x()%34)+93;p--),r      -5,*s=          C;d|=2)  )),z ,i(*C++ =92               ,
   z-63||C [-1]-63||C>S+76,;)*C++=z))i(                   ;,d>1,d=  d-2  ;Q=s[r]  ;i(                  ;
  ,r<3||  r>5,d=1;i(;,r-1, *C=0)C=S)  i(;,            r-4, p=0)++   r)   i(*(C++ )=
 34,r    <4||r>5||   C<S+    78,;)i       (*C++=0;d=1; C=S   ,r<3       ||       r>
5        ||C<S+     79,;      )i(;,d,                         puts               (
        S);         d=0      )}  return
                                      0;}


C:
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
       Int L[A],m,b,*D=A,
        *c,*a=L,C,*U=L,u;s
         (_){u--&&s(a=*a);}
          char*B,I,O;S(){b=b
           --?b:m|read(0,&I,1
            )-1;return~I>>b&1;
             }k(l,u){for(;l<=u;
              U-L<A?*U++=46^l++[
               "-,&,,/.--/,:-,'/"
               ".-,-,,/.-,*,//..,"
              ]:exit(5));}p(Int*m){
             return!*U?*m=S()?U++,!S
            ()?m[1]=p(++U),2:3:1,p(U)
           :S()?U+=2:p(U[1]++),U-m;}x(
          c){k(7*!b,9);*U++=b&&S();c&&x
         (b);}d(Int*l){--l[1]||d(l[d(*l),
        *l=B,B=l,2]);}main(e){for(k(10,33
       ),a[4]-=m=e-2&7,a[23]=p(U),b=0;;e-2
      ?e?e-3?s(D=a),C=a  [3],++1[a=a[2]],d(
     D):c?D=c,c=*D,*D=    a,a=D:exit(L[C+1])
    :C--<23?C=u+m&1?O      =O+O|C&1,9:write(m
   ||(O=C+28),&O,1)+        1:(S(),x(0<b++?k(0,
  6),U[-5]=96:0)):(          D=B?B:calloc(4,X))
 ?B=*D,*D=c,c=D,D[            2]=a,a[++D[1]]++,D
[3]=++C+u:exit(6)              )e=L[C++],u=L[C];}

Respect 8)7

Acties:
  • 0 Henk 'm!

  • Grompie
  • Registratie: Maart 2010
  • Laatst online: 15-04-2024
Las hier deze morgen ook over, echt bizarre stukjes tussen. Gaat niet alleen om uiterlijk de code onleesbaar te maken maar ook voor "gevorderde" programmeurs op een verkeerd been te zetten met je code. De regels zijn ieder jaar anders met als doel dat men een gat vind in de regels om dat te misbruiken. vb Wikipedia: Quine (computing)

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
PolarBear schreef op donderdag 18 oktober 2012 @ 19:39:
[...]
C# is een ISO standaard en er zijn maar weinig andere Microsoft producten die zo uitvoerig zijn gedocumenteerd en waarvan code beschikbaar is. De blackbox opmerking is mij dan ook een raadsel.
Hij bedoelt dan ook niet C# de taal, maar .NET het platform. En dat is qua extensibility inderdaad ronduit een drama. Zelf je VPP schrijven? Copy paste maar de hele meuk vanuit de sources en maak je aanpassingen.

Het enige fatsoenlijk extensible stukje wat ze bij microsoft geproduceerd hebben is ASP.NET MVC, vanaf versie 3.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Geerrrt
  • Registratie: Juli 2008
  • Laatst online: 18-09 13:00
Afbeeldingslocatie: http://i.imgur.com/cym94.png

[ Voor 107% gewijzigd door Geerrrt op 19-10-2012 14:20 ]

Eury#2434


Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 14:21

GrimaceODespair

eens een tettenman, altijd ...

Grijze Vos schreef op vrijdag 19 oktober 2012 @ 13:34:
[...]

Hij bedoelt dan ook niet C# de taal, maar .NET het platform. En dat is qua extensibility inderdaad ronduit een drama. Zelf je VPP schrijven? Copy paste maar de hele meuk vanuit de sources en maak je aanpassingen.

Het enige fatsoenlijk extensible stukje wat ze bij microsoft geproduceerd hebben is ASP.NET MVC, vanaf versie 3.
Oef ... je bespaart me een rant :D

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Zag net dat de nieuwe layout van het forum nogsteeds tables gebruikt. Ik dacht dat de meesten tables gebruikte voor tabular data en de rest gewoon in divjes, blijkbaar had ik het fout.

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Ik doe op deze pagina cmd+u, en zie helemaal geen <table> ?

Acties:
  • 0 Henk 'm!

  • Hardfreak
  • Registratie: Augustus 2004
  • Laatst online: 24-05 19:22

Hardfreak

<!--

Dit is er eentje die ik heb teruggevonden in een java 1.4 VO, maar die mij alsnog deed huiveren :o
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
...
private Boolean canClone;

public void setCanClone(Boolean canClone) {
    if (canClone == null) {
        this.canClone = canClone;
    } else {
        this.setCanClone(canClone.booleanValue());
    }
}

public void setCanClone(boolean canClone) {
    this.canClone = new Boolean(canClone);
}



en dan vraag je je af waarom autoboxing/unboxing er pas in JDK5 bij is gekomen 8)7


//edit ... deze schoot mij ineens nog te binnen, had ik bij een collega is op het scherm gezien en we hebben er toch 5 minunten mee kunnen lachen (ps. heb de code niet meer, vandaar de stomme namen)
Java:
1
2
3
4
5
6
7
8
 
public void doSomething(boolean val) {
    if (val == true) {

    } else {

    }
}


//edit2: ... nu we toch bezig zijn, hoe sommige developers hun Integers omzetten naar een String
Java:
1
2
Integer i = 5; //bijvoorbeeld hé ...
String iAsString = "" + i;


//edit3: ... I'm on a roll. Een SQL query zoals hieronder heeft ons ooit is zware problemen bezorgd (ken de echte query niet, meer het kwam op hetzelfde neer).
SQL:
1
2
insert into db2.table1(id, codeType, codeSeq, actId, actType, modId) 
    select (nextval for db2.c_seq), t2.codeTypeCode codeType, t2.codeSequence codeSeq, t2.activityType actType, t2.activityId actId, t2.modUserId modId from db2.table2 t2;

[ Voor 56% gewijzigd door Hardfreak op 19-10-2012 20:18 ]

Things I wish my life had: a debug port, a try-catch feature and good memory management


Acties:
  • 0 Henk 'm!

  • Jegorex
  • Registratie: April 2004
  • Laatst online: 03-09 23:24
Hardfreak schreef op vrijdag 19 oktober 2012 @ 19:58:
//edit2: ... nu we toch bezig zijn, hoe sommige developers hun Integers omzetten naar een String
Java:
1
2
Integer i = 5; //bijvoorbeeld hé ...
String iAsString = "" + i;
Wat is hier zo slecht aan?
Ik weet dat er Integer.toString(i) is, maar ik gebruik regelmatig jouw voorbeeld.

Acties:
  • 0 Henk 'm!

  • jacobras
  • Registratie: Januari 2005
  • Laatst online: 18-09 13:18

jacobras

Developer

Jegorex schreef op vrijdag 19 oktober 2012 @ 23:14:
[...]

Wat is hier zo slecht aan?
Ik weet dat er Integer.toString(i) is, maar ik gebruik regelmatig jouw voorbeeld.
Gokje: er wordt een lege string aangemaakt, daarnaast wordt i gecast naar een string (explicit casting, weer een stringobject aangemaakt) en die twee worden aan elkaar geplakt waarbij een derde stringobject wordt aangemaakt. Dat in tegenstelling tot één string bij de toString?

Mijn laatste (grote) reviews: Medal of Honor (VR), Half-Life: Alyx (VR)


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Er wordt een StringBuilder gemaakt, waar vervolgens een lege String en een int aan worden geappend, waarop vervolgens toString() wordt aangeroepen.

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!

  • Hardfreak
  • Registratie: Augustus 2004
  • Laatst online: 24-05 19:22

Hardfreak

<!--

Hoe het exact verloopt weet ik niet, maar het is zeker niet zo efficiënt als i.toString().

Bovendien heeft i.toString() het voordeel NullPointerExceptions to throwen als i null is, als je code ineens rare dingen doet weet je ineens waar het vandaan komt (bijvoorbeeld wanneer je later Integer.valueOf(iAsString) zou moeten gebruiken dan krijg je een NumberFormatException en dan kan je maar gaan zoeken waar die "null" String vandaan kwam).

Things I wish my life had: a debug port, a try-catch feature and good memory management


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Grijze Vos schreef op vrijdag 19 oktober 2012 @ 13:34:
[...]
Het enige fatsoenlijk extensible stukje wat ze bij microsoft geproduceerd hebben is ASP.NET MVC, vanaf versie 3.
En zelfs MVC heeft nog zijn nukken. (*Kuch* DataAnnotationsModelValidatorProvider...)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hardfreak schreef op zaterdag 20 oktober 2012 @ 13:45:
Hoe het exact verloopt weet ik niet, maar het is zeker niet zo efficiënt als i.toString().
Zoals ik al zei.

Java:
1
2
3
4
5
6
7
8
String s = "" + i;

// is equivalent aan:

StringBuilder b = new StringBuilder();
b.append("");
b.append(i);
String s = b.toString();


Waarbij b.append(i) en Integer.toString(i) intern precies hetzelfde zullend doen (volgens de JDK 7 implementatie roepen ze beide de method Integer.getChars() aan).

Maar goed, het is natuurlijk ook afhankelijk van hoe de VM er vervolgens mee omgaat, kan best dat hij dit soort specifieke gevallen detecteert omdat ze nou eenmaal vaak gebruikt worden.
Bovendien heeft i.toString() het voordeel NullPointerExceptions to throwen als i null is
Dat geldt natuurlijk alleen voor Integer, niet voor int, die veruit het meest gebruikt wordt.

[ Voor 11% gewijzigd door .oisyn op 20-10-2012 15:14 ]

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!

  • Hardfreak
  • Registratie: Augustus 2004
  • Laatst online: 24-05 19:22

Hardfreak

<!--

.oisyn schreef op zaterdag 20 oktober 2012 @ 15:12:
[...]

Zoals ik al zei.

Java:
1
2
3
4
5
6
7
8
String s = "" + i;

// is equivalent aan:

StringBuilder b = new StringBuilder();
b.append("");
b.append(i);
String s = b.toString();


Waarbij b.append(i) en Integer.toString(i) intern precies hetzelfde zullend doen (volgens de JDK 7 implementatie roepen ze beide de method Integer.getChars() aan).

Maar goed, het is natuurlijk ook afhankelijk van hoe de VM er vervolgens mee omgaat, kan best dat hij dit soort specifieke gevallen detecteert omdat ze nou eenmaal vaak gebruikt worden.


[...]

Dat geldt natuurlijk alleen voor Integer, niet voor int, die veruit het meest gebruikt wordt.
Hangt er maar vanaf wat je wil :) , daarnaast is int nooit null (maar wel 0) en heb je dus minder side effects :) .

Java:
1
""

heeft trouwens niet altijd tot gevolg dat er een nieuwe String aangemaakt wordt, soms worden die pointers opnieuw gebruikt.
Enkel new String("") heeft als garantie dat er een nieuw object (nieuwe pointer) wordt aangemaakt.

[ Voor 12% gewijzigd door Hardfreak op 20-10-2012 17:54 ]

Things I wish my life had: a debug port, a try-catch feature and good memory management


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 12:51
Hardfreak schreef op zaterdag 20 oktober 2012 @ 17:51:
Java:
1
""

heeft trouwens niet altijd tot gevolg dat er een nieuwe String aangemaakt wordt, soms worden die pointers opnieuw gebruikt.
Alle string literals worden geïnternd, dus je kunt zelfs zeggen dat er nooit nieuw String object wordt aangemaakt als een literal meer dan eens voorkomt.

Acties:
  • 0 Henk 'm!

  • HeSitated
  • Registratie: April 2009
  • Laatst online: 03-12-2024
Hardfreak schreef op zaterdag 20 oktober 2012 @ 13:45:
Hoe het exact verloopt weet ik niet, maar het is zeker niet zo efficiënt als i.toString().
Sorry, maar met dit soort argumenten heb ik meer moeite dan met de zogenaamde inefficiënte code.... :(

Voor mij vragen voor het vaststellen van een slechte programmeerstijl:
  • Levert de code fouten op?
  • Is het onduidelijk wat er bedoeld wordt?
  • Is er sprake van inconsequentheid?
En ja als het in een lus gebeurd die honderd miljoen keer doorlopen wordt, heb je volledig gelijk. Maar dan zou ik toch maar eens gaan kijken of er niet ergens anders meer performance winst te halen valt.

Programmeren is op een gegeven moment ook stopen als het goed genoeg is, het hoeft niet altijd perfect te zijn...

En waarschijnlijk heeft deze collega zich dit ooit een keer aangeleerd en is er door niemand opgewezen. Daarvoor zijn codereviews nou uitermate geschikt en nuttig.... :)

[ Voor 0% gewijzigd door HeSitated op 21-10-2012 16:26 . Reden: inconsistent vs inconsequent: klein verschilletje ;) ]


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
HeSitated schreef op zaterdag 20 oktober 2012 @ 20:52:
[...]
En waarschijnlijk heeft deze collega zich dit ooit een keer aangeleerd en is er door niemand opgewezen. Daarvoor zijn codereviews nou uitermate geschikt en nuttig.... :)
Of de collega werkt in meer programmeertalen en vindt het een acceptable loss vs in elke programmeertaal de 100% exacte syntax kennen.

Als je hierover valt alszijnde "bad coding" dan verbaast het me meer dat je programma op meer dan 1 computer werkt. Ik bedoel de .net/java VM kan je ook wel omzeilen, directx kan je zelf ook veel efficienter implementeren, waarom nog memory allocation door het OS laten doen, dat kan je zelf efficienter dan gehinderd door code die ook rekening houdt met swap etc.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Gomez12 schreef op zaterdag 20 oktober 2012 @ 21:42:
directx kan je zelf ook veel efficienter implementeren, waarom nog memory allocation door het OS laten doen, dat kan je zelf efficienter dan gehinderd door code die ook rekening houdt met swap etc.
Been there, done that :7

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!

Verwijderd

Toch één van mijn grootste fouten is het niet gebruik maken van DRY. O.a. niet werken met partials, dezelfde stukken code gebruiken in ieder bestand, ...

Acties:
  • 0 Henk 'm!

  • Hardfreak
  • Registratie: Augustus 2004
  • Laatst online: 24-05 19:22

Hardfreak

<!--

HeSitated schreef op zaterdag 20 oktober 2012 @ 20:52:
[...]

Sorry, maar met dit soort argumenten heb ik meer moeite dan met de zogenaamde inefficiënte code.... :(

Voor mij vragen voor het vaststellen van een slechte programmeerstijl:
  • Levert de code fouten op?
  • Is het onduidelijk wat er bedoeld wordt?
  • Is er sprake van inconsistentie?
En ja als het in een lus gebeurd die honderd miljoen keer doorlopen wordt, heb je volledig gelijk. Maar dan zou ik toch maar eens gaan kijken of er niet ergens anders meer performance winst te halen valt.

Programmeren is op een gegeven moment ook stopen als het goed genoeg is, het hoeft niet altijd perfect te zijn...

En waarschijnlijk heeft deze collega zich dit ooit een keer aangeleerd en is er door niemand opgewezen. Daarvoor zijn codereviews nou uitermate geschikt en nuttig.... :)
Code is niet altijd inefficiënt door het feit dat er 4x meer cycles doorlopen moeten worden om hetzelfde te doen, code kan ook gewoon inefficiënt zijn omdat ze moeilijk te begrijpen valt. Op zich is een concatenate van een lege String met een random object om dit te casten naar een String niet echt onduidelijk, maar het helpt de leesbaarheid er ook niet op vooruit. Als je probeert om een 4 jaar oude webapp te debuggen waar ondertussen al 4 jaar lang wijzigingen aan zijn aangebracht (change request, bugfixes, ...) dan zie je liever .toString() staan dan iets anders :P .

En ja, daarom doen wij nu ook code reviews, maar zo'n dingen halen we gewoon niet aan gezien er belangrijkere punten zijn aan te halen dan dat (String compare met '==' bijvoorbeeld). Bovendien werken de developers van toen al lang niet meer aan die applicatie.
Gomez12 schreef op zaterdag 20 oktober 2012 @ 21:42:
[...]

Of de collega werkt in meer programmeertalen en vindt het een acceptable loss vs in elke programmeertaal de 100% exacte syntax kennen.

Als je hierover valt alszijnde "bad coding" dan verbaast het me meer dat je programma op meer dan 1 computer werkt. Ik bedoel de .net/java VM kan je ook wel omzeilen, directx kan je zelf ook veel efficienter implementeren, waarom nog memory allocation door het OS laten doen, dat kan je zelf efficienter dan gehinderd door code die ook rekening houdt met swap etc.
Meerdere programmeertalen denk ik niet, ik denk voornamelijk oude gewoonten uit Java 1.4 .

Ik noem dit geen bad coding, dit is ook geen bad coding topic, het is gewoon een slecht voorbeeld van een cast van een Integer naar een String object.

Ik snap ook niet waarom je hier begint over het omzeilen van VM's en DirectX. Ja die dingen kunnen efficiënter op sommige vlakken, maar als je dat doet werkt er juist een ander onderdeel weer minder efficiënt. Als je code alles aan moet kunnen, dan ga je een evenwicht moeten zoeken tussen efficiëntie, rubuustheid, featureset en maintainability. Dat is een delicaat evenwicht wat soms moeilijk te vinden en te behouden is.

De code waar ik het over heb heeft een lage maintainability, een lage efficiëntie, en lage robuustheid en een veel te grote en varierende featureset. Een String concatenate gebruiken puur en alleen om een cast uit te voeren maakt het er niet echt beter op (niet persé slechter, maar tel al die kleine details bij elkaar op en je hebt een monster van een applicatie).

[ Voor 32% gewijzigd door Hardfreak op 21-10-2012 11:33 . Reden: 2e quote beantwoord ]

Things I wish my life had: a debug port, a try-catch feature and good memory management


Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

C#:
1
2
3
4
5
CultureInfo culture = new CultureInfo("nl-NL");
DateTimeFormatInfo dfi = (new CultureInfo("nl-NL").DateTimeFormat);

var week1 = culture.Calendar.GetWeekOfYear(new DateTime(2012, 12, 31), dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
var week2 = culture.Calendar.GetWeekOfYear(new DateTime(2013, 1, 1), dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

week1 != week2 :(
This does not map exactly to ISO 8601.
:(

Voor het Internationaal Strafhof ermee :(


:(

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Down
  • Registratie: Februari 2005
  • Laatst online: 13:53
Ik moest eens interfacen met een hardware apparaat, deze werd geleverd met een library. Deze library spuugde op zijn buurt wat gegevens uit in een tekstbestand. Echter was nergens in de documentatie terug te vinden wat de encoding was. Heb zo'n beetje alles geprobeerd en uiteindelijk maar gekozen voor eentje die het minste garbage teruggaf. :X

Mother north, how can they sleep while their beds are burning?


Acties:
  • 0 Henk 'm!

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
kenneth schreef op vrijdag 02 november 2012 @ 15:13:
C#:
1
2
3
4
5
CultureInfo culture = new CultureInfo("nl-NL");
DateTimeFormatInfo dfi = (new CultureInfo("nl-NL").DateTimeFormat);

var week1 = culture.Calendar.GetWeekOfYear(new DateTime(2012, 12, 31), dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
var week2 = culture.Calendar.GetWeekOfYear(new DateTime(2013, 1, 1), dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

week1 != week2 :(


[...]

:(

Voor het Internationaal Strafhof ermee :(


:(
http://blogs.msdn.com/b/s...mat-in-microsoft-net.aspx

MS SQL 2008 heeft wel een werkende ISO week functie MSDN: DATEPART (Transact-SQL)

Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Dat linkje stond inderdaad in het artikel dat ik citeerde, het is alleen ongelofelijk stom. STOM :(

Gelukkig hoef ik het niet te fixen, dat is aan de andere developer O-)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik las net een artikeltje van Herb Sutter over C++11 waar hij stelt: "Use auto wherever possible."

'auto' is de automatische compile-time type deduction van de nieuwe C++ versie. Dus je kan nu dingen schrijven als:

C++:
1
2
auto x = some_function();
x->doStuff();


Erg handig, maar ik vraag me af wat men hier denkt over die uitspraak: use auto wherever possible. Ik zie zelf namelijk wel wat problemen met deze aanpak.

1) Als je vrijwel overal auto voor gebruikt zie je wat dieper in de code niet meer met wat voor type je nou precies werkt. Zoals in het voorbeeld hierboven, wat is 'x' nou eigenlijk? En wat als doStuff weer iets returned dat je weer als 'auto' variabele opschrijft. Ik ben bang voor functies waar je de hele code naar boven terug moet lezen om bij te houden met wat voor type je te maken hebt. Natuurlijk zal je code editor hier hints over geven, maar toch bevordert het volgens mij niet *altijd* de leesbaarheid van code.

2) Als ik het return type van some_function() hier aanpas, dan krijg ik geen compiler error op de assignment aan x, maar pas later in de code waar ik x gebruik. Of helemaal geen error maar ander programmagedrag. Even stom voorbeeld ter illustratie:

C++:
1
2
3
4
5
float someFunc() {return 3.0f;}

auto x = someFunc();

float y = 2 / x;

y is nu ~0.66. Stel dat ik nu someFunc verander om een int te retourneren, dan compilet alles prima, maar is y gelijk aan 0.0.

Ik heb dus een beetje gemengde gevoelens over 'auto'; in sommige gevallen heel erg handig, maar als programmeurs het overal als short-cut te gebruiken... kan het problemen geven.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Zoijar schreef op zaterdag 03 november 2012 @ 16:45:
Erg handig, maar ik vraag me af wat men hier denkt over die uitspraak: use auto wherever possible. Ik zie zelf namelijk wel wat problemen met deze aanpak.
Zelf vind ik dat ook een probleem, dus gebruik ik auto nu vooral voor iterators en in loops over ranges.
Auto in plaats van builtin types als float en int vind ik niet zo nuttig.

[ Voor 9% gewijzigd door Olaf van der Spek op 03-11-2012 16:54 ]


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 10:57
Zoijar schreef op zaterdag 03 november 2012 @ 16:45:
Ik las net een artikeltje van Herb Sutter over C++11 waar hij stelt: "Use auto wherever possible."
Is dat niet ongeveer hetzelfde als "var" in C#? Ik denk dat dezelfde regels dan wel gelden.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Styxxy schreef op zaterdag 03 november 2012 @ 17:07:
Is dat niet ongeveer hetzelfde als "var" in C#? Ik denk dat dezelfde regels dan wel gelden.
Ja, ik geloof het wel.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Styxxy schreef op zaterdag 03 november 2012 @ 17:07:
[...]

Is dat niet ongeveer hetzelfde als "var" in C#? Ik denk dat dezelfde regels dan wel gelden.
Welke regels zijn dat?

Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 10:57
Gebruik waar het handig is en onambigue is ;).

Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
* Alex) gebruikt het overal

We are shaping the future


Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 15:59

Onbekend

...

In oudere SQL-versies werkt dat niet goed, en dan nog kan het per installatie anders zijn ingestelt.
Ik weet dat 4 januari altijd in week 1 valt, en met de gevonden offset uit programmatuur en/of databases ga ik verder rekenen...
Het kan soms dubbelop en overbodig zijn, maar ik wil zelf dat het gegarandeerd goed is. :)

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Olaf van der Spek schreef op zaterdag 03 november 2012 @ 16:53:
[...]

Zelf vind ik dat ook een probleem, dus gebruik ik auto nu vooral voor iterators en in loops over ranges.
Auto in plaats van builtin types als float en int vind ik niet zo nuttig.
Ik zou dat ook zo doen. Debuggen van automatisch castende variabelen is erg lastig. Zelfs als je expliciet types gebruikt krijg je af en toe al rare toestanden, als de conversie-operator of constructor voor rare types is geimplementeerd. Ik ben het volgende commentaar wel tegengekomen bij een vorige opdracht (mocht iemand toegang hebben tot de letterlijke tekst, voel je vrij om het te verbeteren):
C++:
1
2
3
4
5
6
7
/*
==================================
==== Think big red FLASHING sign: ======
TO ALL INTEGRATORS: DO NOT IMPLEMENT OPERATOR BOOL!!!
If we implement operator bool on this coordinate type, we will get really strange unwanted behavior!
==================================
*/

Kennelijk maakten sommigen wat foutjes tijdens terugmergen van bugfixes uit andere branches. "Think big red flashing sign" staat er letterlijk in, in de header van een klasse die een XY-coordinaat voorstelt. Ik geloof dat het probleem was dat als je 2 instanties vergeleek, de C++-compiler het eerst naar een boolean converteert en daarna gaat vergelijken.

Ik heb recent zelf in een model-driven omgeving wat structuur aangebracht, dus ook interfaces aangepast, waarbij ik vergat wat argumenten van integer (default) naar real te veranderen. De compiler van de scripttaal keurt standaard een typeconversie van integer naar real en vice-versa goed. Bij gebrek aan een werkende simulatieomgeving bleek op het embedded device dat dat wat raar gedrag gaf :X Direct maar even de instelling veranderd, zodat integer naar real wordt geweigerd. Real naar int is veilig, aangezien ik geen situaties ken waar reals groter worden dan maxint famous last words ;).

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

MBV schreef op zaterdag 03 november 2012 @ 20:58:
Ik zou dat ook zo doen. Debuggen van automatisch castende variabelen is erg lastig.
Klopt. Ik implementeer die dingen ook nooit meer. Geen casts (maak dan gewoon een toXXX() member) en elke single parameter ctor explicit.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MBV schreef op zaterdag 03 november 2012 @ 20:58:
Ik geloof dat het probleem was dat als je 2 instanties vergeleek, de C++-compiler het eerst naar een boolean converteert en daarna gaat vergelijken.
Er is geen auto-generated operator==(), zoals er wel een auto-generated operator=() bestaat. Ik zou geen idee hebben waarom men ooit een operator bool() zou willen implementeren op een vector, maar als je ze wilt vergelijken moet je sowieso een operator==() hebben, en dan maakt het niet meer uit dat er een operator bool() bestaat.

En inderdaad, een conversion operator zorgt ervoor dat je type impliciet naar dat andere type te converteren is, en dat je er "gratis" dus ook ineens alle functies maar vooral operators bij krijgt die op dat andere type werken. Soms wil je dat ook (met als bijkomend nadeel dat als het type templatized is en zijn operators ook het dan ineens niet meer werkt :/), maar meestal niet. std::iostream heeft een operator void*(), zodat je wel if (std::cout) kunt doen, maar niet std::cout + 4. Wat eigenijk al aangeeft wat er mis mee is. Nog beter was het als ze een operator T::*() zouden doen, met T een private class, dan had je ook niets om aan te assignen (wat met void* natuurlijk wel kan), en dat je ook niet meer kan testen op kleiner/groter dan (wat met void* ook kan)

Dat implicit conversion operators een doorn in het oog zijn onderschrijft de standards committee ook (het std::iostream verhaal spreekt wat dat betreft ook boekdelen). Voor een conversion constructor had je al explicit. Sinds C++11 heb je die ook op conversion operators. Met een explicit operator bool() kun je je type wel testen in een if, maar kun je er niet zomaar iets bij optellen.

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!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Operator bool() voor strings lijkt me anders wel handig, ik check vaak op !empty()

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Olaf van der Spek schreef op zondag 04 november 2012 @ 01:20:
Operator bool() voor strings lijkt me anders wel handig, ik check vaak op !empty()
Ik zie nooit zo in dat het nou zo veel meer type-werk is om if (str.empty()) te doen ipv if (str), en de eerdere versie toont duidelijker aan wat het doet. if (str) lijkt een beetje op een nullptr check.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Olaf van der Spek schreef op zondag 04 november 2012 @ 01:20:
Operator bool() voor strings lijkt me anders wel handig, ik check vaak op !empty()
Zodat je ook ineens str + 5 kunt doen. Of een string geven aan een functie die een int verwacht. Ja, heel handig.

Overigens, toen ik het in mijn vorige post over een vector had ging het om een geometrische vector. Het voorbeeld van MLM ging namelijk om een coordinaten-type. Wat moet een operator bool() dan doen, kijken of hij (0, 0) is?

[ Voor 26% gewijzigd door .oisyn op 04-11-2012 02:09 ]

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!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Een van de weinige dingen die ik zie waar ik een cast operator heb is voor m'n matrix classes naar value_type*, zodat ik ze makkelijk door kon geven aan opengl functies. Maar bij nader inzien is dat ook eigenlijk onnodig complex en moet ik die gewoon vervangen door toFloatPtr() oid.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op zondag 04 november 2012 @ 02:08:
[...]

Zodat je ook ineens str + 5 kunt doen. Of een string geven aan een functie die een int verwacht. Ja, heel handig.
Explicit operator bool() const, operator const void*() const of iets beters van Boost dan? Het gaat om het idee.
Overigens, toen ik het in mijn vorige post over een vector had ging het om een geometrische vector. Het voorbeeld van MLM ging namelijk om een coordinaten-type. Wat moet een operator bool() dan doen, kijken of hij (0, 0) is?
Ligt eraan, als je een invalid value hebt voor de coordinaten class kun je daarop checken.
Zoijar schreef op zondag 04 november 2012 @ 01:25:
if (str) lijkt een beetje op een nullptr check.
Is het toch ook een beetje?
Als je een var hebt is het inderdaad simpel, maar als je iets hebt als
C++:
1
2
3
4
5
6
7
8
9
10
std::string f() { return "Olaf"; }

int main()
{
  if (std::string s = f())
    use(s);

  while (std::string s = f())
    use(s);
}

dan is empty() toch ineens een stuk lastiger. Voor types als SQL result en row is zoiets ook handig.
Zoijar schreef op zondag 04 november 2012 @ 02:14:
Een van de weinige dingen die ik zie waar ik een cast operator heb is voor m'n matrix classes naar value_type*, zodat ik ze makkelijk door kon geven aan opengl functies. Maar bij nader inzien is dat ook eigenlijk onnodig complex en moet ik die gewoon vervangen door toFloatPtr() oid.
Wat is er complex aan? data() is trouwens de standaard naam voor zo'n functie. ;)

[ Voor 5% gewijzigd door Olaf van der Spek op 04-11-2012 14:01 ]


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Olaf van der Spek schreef op zondag 04 november 2012 @ 14:00:
dan is empty() toch ineens een stuk lastiger. Voor types als SQL result en row is zoiets ook handig.
Ja, daar is het wel handig geef ik toe. Dit is niks, zeker niet met veel argumenten en foutgevoelig:
C++:
1
        for (std::string x = f(); !x.empty(); x = f()) {}

of anders moet je je var buiten de scope halen:
C++:
1
2
        std::string x;
        while (x = f(), !x.empty()) {}

maar dan heb je ook buiten je loop toegang tot x als nadeel (Als dat echt heel erg is knal je er twee braces omheen...) Dan is je bool cast wel elegant.
Wat is er complex aan? data() is trouwens de standaard naam voor zo'n functie. ;)
Mogelijk onvoorzien gedrag in verschillende situaties.

C++:
1
2
3
4
OGLMatrixFunc(float* M) {}

Matrix A;
OGLMatrixFunc(A + 1);

Telt niet bij elk element 1 op, omdat ik geen scalar operator+ heb. Argument is nu een pointer naar het tweede element, OGL leest over boundary, crash.

Zal ook een deel persoonlijke voorkeur zijn.

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
.oisyn schreef op zondag 04 november 2012 @ 02:08:

Overigens, toen ik het in mijn vorige post over een vector had ging het om een geometrische vector. Het voorbeeld van MLM ging namelijk om een coordinaten-type. Wat moet een operator bool() dan doen, kijken of hij (0, 0) is?
Je bedoelt mijn voorbeeld? Autocorrect :? Ik vermoed het, ik ben niet de 1000 branches afgegaan om te kijken waar hij nog wel gedefinieerd stond. Perforce is niet echt snel met dat soort dingen ;)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Jawel man, gewoon timelapse view met branch history :P

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!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Timelapse-view werkt best aardig, maar daarmee loop je alleen door het pad vanaf je huidige branch totaan het begin van Perforce. Nee, de revision graph moet je hebben om te zien in welke branch ze die belachelijke operator hebben toegevoegd. Voor de God-classes (die veel worden aangepast in alle branches) duurde dat volgens mij iets van 5 minuten, als je het beperkte tot mijn workspace. Als je ergens een vinkje verkeerd zette was hij na de lunch nog niet klaar :X

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Misschien praten we langs elkaar heen, maar je wilt toch gewoon weten in welke revisie die comment is toegevoegd, met de assumptie dat dat de change is die ook operator bool() weg heeft gehaald?

.edit: ah wacht ik zie het al, de timelapse view gaat alleen maar de root-branch in vanaf revisie #1 in de branch, hij splitst niet af bij elke willekeurige integrate. Je moet dus op de comment klikken, dan in de integrate tab een timelapse view op de source doen, dan daar weer de comment opzoeken en dat herhalen tot je bij de daadwerkelijke change uitkomt.

[ Voor 50% gewijzigd door .oisyn op 05-11-2012 16:20 ]

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!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
Ik moet zeggen dat ik niet zeker weet of ik daar wel eens op de timelapse-view heb geklikt met branches aan, maar het is zo'n bestand dat al in geen jaren is aangepast.

Acties:
  • 0 Henk 'm!

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Zoijar schreef op zondag 04 november 2012 @ 14:51:
Telt niet bij elk element 1 op, omdat ik geen scalar operator+ heb. Argument is nu een pointer naar het tweede element, OGL leest over boundary, crash.
Dat is het nadeel van pointers. Explicit helpt hier ook niet echt.

Acties:
  • 0 Henk 'm!

  • PolarBear
  • Registratie: Februari 2001
  • Niet online
Onbekend schreef op zaterdag 03 november 2012 @ 20:01:
[...]

In oudere SQL-versies werkt dat niet goed, en dan nog kan het per installatie anders zijn ingestelt.
Ik weet dat 4 januari altijd in week 1 valt, en met de gevonden offset uit programmatuur en/of databases ga ik verder rekenen...
Het kan soms dubbelop en overbodig zijn, maar ik wil zelf dat het gegarandeerd goed is. :)
2008 is 4 jaar oud, aan ouder doe ik niet. We draaien hier inmiddels 2012 in productie.

Acties:
  • 0 Henk 'm!

  • zzattack
  • Registratie: Juli 2008
  • Nu online
Een stukje C#...
code:
1
2
3
4
5
6
7
8
9
#region PUKE HAZARD
SuspendDispatch = true;
var tick = Environment.TickCount;
while (Environment.TickCount - tick < 2500)
    OpenNETCF.Windows.Forms.Application2.DoEvents(); // please god no... :@
lock (SuspendDispatchLock) {
    SuspendDispatch = true; // make double-sure
}
#endregion

I rest my case.

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 12:39
En voor welk probleem was dit de workaround? :X

Acties:
  • 0 Henk 'm!

  • zzattack
  • Registratie: Juli 2008
  • Nu online
De UI thread moet op 'iets' wachten, en de thread die 'iets' aan kan leveren kan op dat moment op de UI thread aan het wachten zijn --> deadlock. SuspendDispatch=true zorgt ervoor dat de aanleverende thread zal wachten op de UI thread alvorens nieuwe opdrachten aan te leveren. De loop met DoEvents() erin geeft de UI ongeveer 2500ms de tijd om achterstallig werk bij te werken, zodat de thread die 'iets' kan aanleveren daar ook daadwerkelijk mee kan beginnen.

Het hele idee dat de UI thread moet gaan wachten op iets is natuurlijk bij voorbaat fout. Een betere methode zou ongeveer het volgende moeten zijn: de UI thread zegt dat het een notificatie van 'iets' wil. Over (zeg) 10 seconden schedule je een callback die, indien 'iets' niet gebeurd is, daar melding van maakt en appropriate action onderneemt. De UI thread wacht nergens op en gaat lekker verder. Mocht 'iets' gebeuren, dan kan die de "er iets niets gebeurd" callback uitschakelen, en de UI thread vertellen dat 'iets' is gebeurd.

Acties:
  • 0 Henk 'm!

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 14:21

GrimaceODespair

eens een tettenman, altijd ...

Eigenlijk zou er voor Threading zoiets als een rijbewijs moeten zijn: Je mag niet aan threading doen als je geen Threading-bewijs hebt. Anders ben je strafbaar.

Wij onderbreken deze thread voor reclame:
http://kalders.be


Acties:
  • 0 Henk 'm!

  • zzattack
  • Registratie: Juli 2008
  • Nu online
GrimaceODespair schreef op dinsdag 06 november 2012 @ 17:05:
Eigenlijk zou er voor Threading zoiets als een rijbewijs moeten zijn: Je mag niet aan threading doen als je geen Threading-bewijs hebt. Anders ben je strafbaar.
Met soortgelijke boetes voor overtredingen dan wel! En verplicht op cursus bij te schrijnende overtredingen :D
Pagina: 1 ... 96 ... 103 Laatste

Dit topic is gesloten.

Let op:
Uiteraard is het in dit topic niet de bedoeling dat andere users en/of topics aangehaald worden om ze voor gek te zetten. Lachen om je eigen code, of over dingen die je "wel eens tegengekomen bent" is prima, maar hou het onderling netjes. :)