Conventies, policies, en achtergrond

Er zijn meerdere manieren waarop R-code kan worden geschreven voor een bepaalde taak, en er zijn zelfs nog meer manieren waarop deze R-code met JS kan worden gegenereerd. Hoe u dit precies aanpakt, is helemaal aan u. Maar er zijn een aantal overwegingen die u moet volgen, en achtergrondinformatie die u moet begrijpen.

De local() omgeving begrijpen

Vaker wel dan niet moet u een of meer tijdelijke R-objecten aanmaken in de code die door uw plugin wordt gegenereerd. Normaal gesproken wilt u die niet plaatsen in de werkruimte (workspace) van de gebruiker, waardoor zelfs misschien variabelen van de gebruiker kunnen worden overschreven. Daarom moet alle door de plugin gegenereerde code werken in een local() omgeving (zie R help-pagina voor functie local()). Dit betekent dat alle variabelen die u aanmaakt tijdelijk zijn, en niet permanent worden opgeslagen.

Als de gebruiker expliciet vraagt dat een variabele wordt opgeslagen, moet u dat object (een waarde) toekennen met .GlobalEnv$objectname <- value. Gebruik, in het algemeen gesproken, niet de operator <<- operator. Die kent in .GlobalEnv niet noodzakelijk (een waarde) toe.

Een grote valkuil is het gebruik van eval(). U moet hier beseffen dat eval standaard bij de evaluatie (waardebepaling) de huidige omgeving gebruikt, bijv. de lokale. Meestal werkt dat goed, maar niet altijd. Dus, als u eval() nodig heeft, moet u waarschijnlijk de envir-parameter opgeven: eval(..., envir=globalenv()).

Programma-code formatteren

Het belangrijkste is dat uw gegenereerde R-code werkt, maar die moet ook gemakkelijk te lezen zijn. Let er daarom op dat u dit ook goed formatteert. Enkele beschouwingen:

Normale top_niveau R-statements moeten links uitgelijnd zijn.

Statements in een lager blok moeten een tab inspringen (zie onderstaand voorbeeld)

Indien u erg complexe berekeningen doet, voeg dan hier en daar wat commentaar toe, vooral om logische secties te markeren. Merk op dat er een speciale functie comment() is, voor het toevoegen van vertaalbaar commentaar in de gegenereerde code.

Bij voorbeeld, kan de gegenereerde code er aldus uitzien. Dezelfde code zonder inspringen en commentaar zou behoorlijk lastig te lezen zijn, hoewel die maar tamelijk complex is:

# Bepaal eerst de wobble en de rotatie
my.wobble <- wobble (x, y)
my.rotation <- wobble.rotation (my.wobble, z)

# boggling-methode hangt af van de rotatie
if (my.rotation > wobble.rotation.limit (x)) {
        method <- "foo"
        result <- boggle.foo (my.wobble, my.rotation)
} else {
        method <- "bar"
        result <- boggle.bar (my.wobble, my.rotation)
}
                

Omgaan met complexe opties

Vele plugins doen meer dan een ding. Bij voorbeeld, de plugin Descriptive Statistics (beschrijvende statistiek) kan gemiddelde, bereik, som, product, mediaan, lengte, etc. berekenen. Maar gewoonlijk zal de gebruiker alleen maar enkele hiervan berekenen. In zo'n geval, moet u de gegenereerde code zo eenvoudig mogelijk proberen te houden. Die moet alleen die gedeelten bevatten die overeenkomen met de werkelijk geselecteerde opties. U kunt dit bereiken, met een voorbeeld van een algemeen design pattern (ontwerppatroon) zoals u die zou gebruiken (hier, in JS, zouden "domean", "domedian", en "dosd" <checkbox> elementen zijn):

function calculate () {
        echo ('x <- <' + getString ("x") + ')\n');
        echo ('results <- list ()\n');

        if (getBoolean ("domean.state")) echo ("results$" + i18n ("Gemiddelde waarde") + " <- mean (x)\n");
        if (getBoolean ("domedian.state")) echo ("results$" + i18n ("Mediaan") + " <- median (x)\n");
        if (getBoolean ("dosd.state")) echo ("results$" + i18n ("Standaard deviatie") + " <- sd (x)\n");
        //...
}