• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Discussion] vJASS Standard 4


vJASS Standard 4
_______________________________________________________________________________________________________________________________________________________________________


Notation Table
_______________________________________________________________________________________________________________________________________________________________________

Notation
________________________________________________________________________________
Example
_______________________________________________________________________________________

Standard C / GNU notationmouse_weight
Hungarian notationiMouseWeight
Camel case (or lower Camel case)mouseWeight
Pascal case (or upper Camel case)MouseWeight
All capitals case (SHOUTY)MOUSE_WEIGHT
All lower casemouseweight


Design

Modular

Minimal functionality and maximal use of external resources.
Encapsulation
Protect as many things within the resource as possible.
Documentation
  • All algorithms within the resource must be commented.
  • API must be listed with details of all structs/routines/arguments/returns/fields that aren't obvious
  • Resource must be described if not obvious
  • Examples must be included within the API showing the usage of everything within the API that isn't obvious (iterating over a list, etc)
No Extensions
An extension is defined as a resource that is included in a resource that it requires via static ifs.
No Static Plugins
A static plugin is defined as a resource that is included in a resource that it requires via optional modules.
Standardized Collections
Unless special behavior is necessary, such as when writing other collections, a collection can't be written inside of a resource.
Standardized Allocation
Unless allocation requires special behavior, an allocator can't be written inside of a resource.
Standardized Unit/Item Data
It is not allowed to use SetUnitUserData/SetItemUserData outside of a unit/item indexer.
Standardized Error Checking
  • A resource must catch all possible user errors with the use of ErrorMessage.
  • A resource must be tested, checking for all possible cases. A testing suite or unit testing can be used, but all test code used must be posted to prove that the resource is free of bugs.
  • A resource should not disable itself in the event of an error, it should rely on ErrorMessage.
  • All arguments must be displayed in the error message as well as the resource name, the object name that caused the error (thistype), and the instance that caused the error.
  • Error checking is debug only.
All Fields/Globals Must Be Private. Static readonly/constant Fields and constant Globals May Be Public.
Unless Used For Syncing, TriggerSleepAction Is Not Allowed
Leaks Must Be Cleaned
Objects (units, items, etc) Must Be Dynamically Generated When Required By A Script (no cnp map)
All Initializers Must Be Within A Module
Must Mimic Warcraft 3 Behavior If Applicable
Interfaces/Function Interfaces Aren't Allowed
Extending Structs (Due To OnDestroy) Is Not Allowed, As Such All Structs Must Extend Array To Prevent Struct Extension
Convention

All Labels Must Be Sensible

Variables

Constants
Must be all capitals case with _ between words.
FieldsMust be camel case.
GettersFor any pair getter,field, the getter shall be name and the field shall be p_name or _name
JASS:
							private integer p_myField
							method operator myField takes nothing returns integer
								return p_myField
							endmethod
Methods

Constants
Must be all capitals with _ between words.
OtherwiseMust be camel case.
Functions

Constants
Must be all capitals with _ between words.
OtherwiseMust be pascal case.
Libraries/ScopesMust be pascal case.
Text MacrosMust be all capitals with _ between words.
Keywords/KeysMust be camel case. Keys Are Constant Globals/Fields. Keywords May Only Be Private.
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
If people would submit resources that they actually use / have used, we would have much less bugs and non sense resources.
Instead people (including me) just post resource for the sake of it, and for the e-penis or something else, while they don't use it and worse, they will probably never use it at all.

Also i don't seriously think you can force a jass naming convention nowadays, it's just too late, now if you have free time to lose, it's ok.
Personnaly as long it's readable and constant without non sense it's ok for me.
 
Well, I'm submitting a lot of resources that I plan to use/can be used for future resources :\, and because I haven't used them yet, they end up being buggy while getting approved. I used Timer Tools quite a bit without running into bugs, but that ended up having bugs too >.<.

The more complex a resource is (Timer Tools, IsPathBlocked), the more likely it will have bugs even under usage (had IsPathBlocked in a map and didn't run into any bugs when there were in fact bugs).

A crazy testing suite, like the one I'm using for collections right now, will ensure that all bugs are caught.
 
Level 15
Joined
Feb 15, 2006
Messages
851
Just to remind an old, ooooold experience in WC3C: imposing standards is a waste of time, this coding/mapping activity is not a serious nor profit thing (even though some of us take it in that way, sometimes, like me :xxd:). And if anybody here decides to impose a standard, then it will contribute to the boredom in submitting things. Just focus in the real readability, like comments and some basic indent.

That happened in WC3C and at the end just the people in a closed group could be able to submit resources. you could transform this activity (indirectly) in something elitist and it goes against the community. The outcome: you can see it in the inactivity of WC3C.

Anyways, I do acknowledge your interest in developing something that will help in the readability and usability of Jass / vJASS

HUGS!!!
 
moyackx, we have current standards, they just aren't really documented anywhere

The current standard is vJASS Standard 3. Standard 1 was defined on wc3c, standard 2 on TH, and standard 3 on THW. Why do you think some stuff that works perfectly gets rejected? Because they don't follow Standard 3.

We're now moving on to Standard 4, which is a much stricter version of Standard 3 ;o. Standard 4 is there to ensure that all resources have 0 bugs when being approved with proof that they were tested for 0 bugs. It's also there to ensure that all resources have proper error checking (I know that I personally get really lazy on checking for errors a lot of the time cuz error checking is annoying). It's about raising the quality of resources ;).

vJASS Standard 4, like Standard 3, will only apply to the JASS Section. Spells section will continue to follow a very relaxed Standard 3.


The reason wc3c died was because they did not allow for new innovations. Once they approved one resource of a type, then they would never ever approve a new resource of the same type regardless of any innovation in it or dif pros/cons. THW follows a very different philosophy, which allows people to continue to innovate.

What we can and probably should do is create a new forum called JASS Lab, where people can put up experimental code that may not have lots of error checking and stuff ;o.

edit
And also, believe me, with Standard 4, I am hurting myself more than anyone else. I'd have to redo the majority of my resources + create toolchains to make some of them possible under standard 4 >.<. Not much can even be written under Standard 4 until a good jasshelper thing is created because some of the requirements will raise syntax errors under the current jasshelper.
 
Why are you limiting it in the Jass's section only?, this should be implemented in the Spell's section as well or as a rule...

(1) It would have to be a consensus (involving all the spell mods), not just Nes.
(2) Too many restrictions == lack of submissions. Plus, we like to encourage writing in JASS/vJASS as much as possible. I feel that having such limiting standards in the spells section would be a deterrent to both submitting resources and learning vJASS. It is okay to have here--the JASS section already has higher standards than the spells section.
(3) The JASS section behaves differently. :) In the spells section, you will see at least 100 knockback spells all doing 90% the same thing. There are a lot of duplicates. In the JASS resources section, it is competitive. If yours is in, that usually means the other is out (or that they have enough differences to peacefully coexist). This is one reason why standards are important. If we have just one resource for something, it should be good. We shouldn't have to switch around coding styles between scripts. I don't know if it is something to be 100% anal about, but it is usually for the better.
 
mckill said:
Why are you limiting it in the Jass's section only?, this should be implemented in the Spell's section as well or as a rule...

no, just no... It's not really a good idea to put a super strict rule in the spells section... unless you want all JASS/vJASS resources in the spells section to be sent to the JASS section...
 
Well I'm still voting to implement this as a rule...I remember a moderator and me had an argument about conventions in spell's section and it forces me to change api 'name' and letter cases of my functions even though it's not required, so better to implement this so that no future argument will rise...

On the other hand, if this is NOT a rule, then mods doesnt need to complain about cases and where to put that and this :D...
 
do we need a rule/standard for jass spells in the spells section, yes
do we need a rule/standard for jass spells in the spells section that is this strict, I don't think so

basically, in the resource (excluding JASS section and map section), moderating is a matter of the mods perception... we don't really have defined, well-written standards there... I'm talking about skins/icons/models/spells...

or maybe let's just separate the GUI and JASS/vJASS/ZINC/whateverscript spells sections... then we can implement the standard for the non-GUI spells section...

that's my opinion...
 
Level 15
Joined
Feb 15, 2006
Messages
851
moyackx, we have current standards, they just aren't really documented anywhere

The current standard is vJASS Standard 3. Standard 1 was defined on wc3c, standard 2 on TH, and standard 3 on THW. Why do you think some stuff that works perfectly gets rejected? Because they don't follow Standard 3.

We're now moving on to Standard 4, which is a much stricter version of Standard 3 ;o. Standard 4 is there to ensure that all resources have 0 bugs when being approved with proof that they were tested for 0 bugs. It's also there to ensure that all resources have proper error checking (I know that I personally get really lazy on checking for errors a lot of the time cuz error checking is annoying). It's about raising the quality of resources ;).

vJASS Standard 4, like Standard 3, will only apply to the JASS Section. Spells section will continue to follow a very relaxed Standard 3.


The reason wc3c died was because they did not allow for new innovations. Once they approved one resource of a type, then they would never ever approve a new resource of the same type regardless of any innovation in it or dif pros/cons. THW follows a very different philosophy, which allows people to continue to innovate.

What we can and probably should do is create a new forum called JASS Lab, where people can put up experimental code that may not have lots of error checking and stuff ;o.

edit
And also, believe me, with Standard 4, I am hurting myself more than anyone else. I'd have to redo the majority of my resources + create toolchains to make some of them possible under standard 4 >.<. Not much can even be written under Standard 4 until a good jasshelper thing is created because some of the requirements will raise syntax errors under the current jasshelper.
Sorry for not answering (RL is evil), but with this intentions and your interest in not to form a closed circle of coders, that's pretty good. Jut keep with open mind and enjoy the game.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Standards are helpful for readability of script resources, as they are supposed to be used by other people other than the one who wrote it.
 
Level 16
Joined
Aug 7, 2009
Messages
1,406
if we dont enforce things, people will not learn...if there is no law to jail people who shoplift, then what would the world be?...

True, but telling people how to name their variables and other stuff is a different story and is just r*****ed. Well, I guess it makes sense if you want to shorten the list of actively posting people (not that we had many of them anyways, but it's no surprise).
 
Ew. When I read about a dying modding language becoming vJass standards.
Yes, it's okay with having them defined. No, I don't completely agree with the standards.
And no, those standards should never be forced, always optional.

As for me, I like to have my own commenting/programming type, it seems to work as I can understand my code pretty well after 9 months of not looking at it.
 

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
Some comments/suggestions on the standard:

(most of the points are just about wording, because some things in the standard are not possible to fulfill as it stands now)

A resource must catch all possible user errors with the use of ErrorMessage.
In general, it is not possible to catch all user errors or it would be too much work to do it. Maybe relax this condition a bit.

A resource must be tested, checking for all possible cases.
In general, it is not possible to test all possible cases. Maybe relax this and just say all nontrivial functions in the API should be tested.

… to prove that the resource is free of bugs
In general this is not possible with tests.

Error checking is debug only
Silently ignoring errors is not a good idea in my opinion. It can lead to very strange and hard to find bugs. Removing error messages should only happen in performance critical code (e.g. fast periodic code, inner loops, etc.)

Interfaces/Function Interfaces Aren't Allowed
I think this should only apply for performance critical code. Or it there an other reason which speaks against using them?

Extending Structs (Due To OnDestroy) Is Not Allowed, As Such All Structs Must Extend Array To Prevent Struct Extension
This one was really "wtf?" for me. Could you explain why extending structs is a problem? I think it is more important that the library i readable, because that makes it easier to check it.


Additional guidelines I would add:
  1. Textmacros must be used only internally (Maybe there are a few exceptions where it makes sense to have a textmacro in the API but this should be very rare)
  2. Modules must be syntactically complete (for example if a module includes the beginning of a function it must also include 'endfunction').
  3. When using distances/speeds/accelerations in the API, the values should not depend on the internal timer interval of the system or other internals. (I think this point is partially covered by "Must Mimic Warcraft 3 Behavior If Applicable" but maybe make it explicit)
 
Last edited by a moderator:
  1. Textmacros must be used only internally (Maybe there are a few exceptions where it makes sense to have a textmacro in the API but this should be very rare)
  2. Modules must be syntactically complete (for example if a module includes the beginning of a function it must also include 'endfunction').

Textmacros and modules are totally useful by breaking these rules. Granted, the learning curve is intense at time to import such a script, but it provides functionality/safety/abstraction that's not possible doing it any other way.

I don't understand your third suggestion. Do you have an example?
 

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
Textmacros and modules are totally useful by breaking these rules. Granted, the learning curve is intense at time to import such a script, but it provides functionality/safety/abstraction that's not possible doing it any other way.
Yes, I agree that textmacros are sometimes the best way to do something. But I would say that if you have the choice between using plain functions/structs/modules and using textmacros you should not use textmacros.

Concerning the module rule: I just think it is clearer to use a textmacro in this case. Using modules like this feels like exploiting a jasshelper bug to me, as such a use is not in the manual.


I don't understand your third suggestion. Do you have an example?

For example if you have a function

JASS:
method startMissile(real x, real y, real directionRadians, real distance, real speed)


Then distance and speed should have the same units as wc3 has. For example a speed of 800 should mean "the missile moves 800 wc3-units in one second". I have seen some systems where 800 means "the missile moves 800 wc3-units in 1/32 seconds (or in 1/TIMER_INTERVAL seconds)".
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I think some of the suggestions should be changed as they are either inpractical or too strict:

  • Only allowing structs to extend array is a bad idea imho. The compiler might generate some useless code when extending nothing/structs but why should that be a problem? Performance wise its impossible to feel this difference and extending structs can improve readability a lot. Also array structs don't allow array members, so thats very bad in some cases.
  • Same applies for interfaces and function interfaces. If I want to pass a function to another function it is absolutly neccessary to use a function interface. At the moment I'm working on a library for nonlinear optimization and without a function interface its not possible to pass a user defined cost function to the optimization algorithm. The user would have to modify the system code to pass his functions which is not acceptable.
  • Error checking and relying on ErrorMessage is ok, but forcing people to upload testcases which cover all possible errors is completly impossible and impractical. But as Systems like Trigger got approved without providing any of those testcases, I guess this isn't required anyway.

And what about hooking, delegates and the public access modifier?
 
Same applies for interfaces and function interfaces. If I want to pass a function to another function it is absolutly neccessary to use a function interface. At the moment I'm working on a library for nonlinear optimization and without a function interface its not possible to pass a user defined cost function to the optimization algorithm. The user would have to modify the system code to pass his functions which is not acceptable.

A function interface is a trigger. You can do the same thing with modules and triggers. I show how in a tutorial. It's also much faster >.<.

Error checking and relying on ErrorMessage is ok, but forcing people to upload testcases which cover all possible errors is completly impossible and impractical. But as Systems like Trigger got approved without providing any of those testcases, I guess this isn't required anyway.

Well, with Trigger, I did in fact test everything, I just didn't upload the test code >.<. I think that the best approach is to create a randomized testing suite and ensure that you hit all of the cases you can think of n number of times each with a minimum of t tests.

Also, standard 4 isn't enforced yet, it's up for discussion


so interfaces and function interfaces are the slow crappy lazy way to do the same thing you can do with triggers and a combo of a module and a list

you can create arrays in struct extends array just fine >.>, you just need to do the math yourself instead of letting jasshelper do it for you
extending structs will make it so that triggers are evaluating whenever you do struct.destroy because jasshelper permits polymorphism, implemented via triggers
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
A function interface is a trigger. You can do the same thing with modules and triggers. I show how in a tutorial. It's also much faster >.<.

Ok, I will take a look.

you can create arrays in struct extends array just fine >.>, you just need to do the math yourself instead of letting jasshelper do it for you

Multiple arrays too?

Well, with Trigger, I did in fact test everything, I just didn't upload the test code >.<.

Haha, good one :D

Then this rule is already omitted practically, which is good imho.


EDIT:

Ok I checked the tutorial, but this isn't working as I want it to (appart from the fact that the example doesn't compile):

  • I want to use something like call Optimization.minimize(costfunction, parameter). With this approach all the optimization algorithms would have to be copied to every struct that uses the minimization. That breaks encapsulation. I want to collect all optimization methods in one struct and not copy them around into every struct that needs them.
  • In your example, the firerer method would be my optimization algorithm. But as this method is a trigger condition, you can't pass any arguments to it! But an optimization algorithm would require various parameters like start values, tolerances, datapoints etc.
  • The user defined cost function would have to have a predefined name which is also not acceptable as you will most likely have various cost functions at the same time. Of course I could define multiple firerer methods, but that is very ugly and bad style.

Btw I did a benchmark and the function interface was actually much faster than your approach. How did you measure the speed difference between those two approaches?
 
Last edited:
Level 10
Joined
Sep 19, 2011
Messages
527
A function interface is a trigger. You can do the same thing with modules and triggers. I show how in a tutorial. It's also much faster >.<.

yes, we all know that things in vjass can be improved to be more faster/efficient/magical/coffee maker/etc. do they need those improvements?, 99% cases they don't. why?, because they do their job, and they do it pretty well. real maps don't need these optimisations, only imaginary ones do.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Here are my test setups to check the performance of function interfaces.


The benchmark for the standard function interface runs on my PC with constantly 60 fps:


JASS:
function interface CostFunction takes real r returns real

function MyCostFunction takes real r returns real
    return I2R(2*2*2*2*2*2*2*2*2*2*2)
endfunction
    
    
struct InterfaceTest extends array

    private static method minimize takes CostFunction tfun, real para returns real
        return tfun.evaluate(para)
    endmethod
    
    private static method callback takes nothing returns nothing
        local integer i = 0
        local CostFunction costFun = CostFunction.MyCostFunction
        loop
            exitwhen i > 150
            call minimize(costFun, 1.0)
            set i = i + 1
        endloop
    endmethod
    
    private static method onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), 0.001, true, function thistype.callback)
    endmethod
endstruct


The proposed method from this tutorial runs only with about 30 fps:


JASS:
struct InterfaceStruct extends array
    private static trigger eventTrig = CreateTrigger()
    private static trigger fireTrig = CreateTrigger()
    static thistype data = 0

    private static method onEvent takes nothing returns boolean
        local integer prevData = data
        set data = 5 //event data
        call TriggerEvaluate(fireTrig)
        set data = prevData
        return false
    endmethod

    private static method onInit takes nothing returns nothing
        call TriggerAddCondition(eventTrig, Condition(function thistype.onEvent))
    endmethod

    static method register takes boolexpr bc returns nothing
        call TriggerAddCondition(fireTrig, bc)
    endmethod
endstruct

module INTERFACE_MODULE

    static if thistype.MyCostFunction.exists then
        static method minimize takes nothing returns boolean
            call thistype(InterfaceStruct.data).MyCostFunction(1.0)
            return false
        endmethod

        private static method onInit takes nothing returns nothing
            call InterfaceStruct.register(Condition(function thistype.minimize))
        endmethod
    endif
endmodule



struct InterfaceTest extends array
    private static method MyCostFunction takes real r returns real
        return I2R(2*2*2*2*2*2*2*2*2*2*2)
    endmethod
    
    private static method callback takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i > 150
            call minimize()
            set i = i + 1
        endloop
    endmethod
    private static method onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), 0.001, true, function thistype.callback)
    endmethod
    
    implement INTERFACE_MODULE
endstruct


From these results (as far as I did not make any fundamental mistake in the code above) I would conclude two things:

- function interfaces are very efficient (60 fps at 150 calls every 0.001 seconds), at least efficient enough that they can be used without any concerns
- The proposed method to manually build interfaces is quite bad?

Please correct me if I'm wrong.

lfh


EDIT:
Ok, the interface module has to be implemented above the callback function, then its a bit faster than vJass function interfaces (about 20 percent under extreme conditions). However, I don't think
that little performance gain justifies the disadvantages of using such a method. I usually want to pass not only a function as an object but parameters as well, otherwise I can just use code.
 
Last edited:
Level 14
Joined
Dec 12, 2012
Messages
1,007
How?

This is the interface module from your example:

JASS:
module INTERFACE_MODULE

    static if thistype.MyCostFunction.exists then
        static method minimize takes nothing returns boolean
            call thistype(InterfaceStruct.data).MyCostFunction(1.0)
            return false
        endmethod

        private static method onInit takes nothing returns nothing
            call InterfaceStruct.register(Condition(function thistype.minimize))
        endmethod
    endif
endmodule

As minimize is used as a trigger condition it can't take any parameters. The 1.0 in MyCostFunction should be passed as a parameter, not as a hardcoded value, otherwise this doesn't make sense.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I looked at UnitIndexer and I dont see where I can pass extra parameters. Maybe I don't get it. For example you have this code in UnitIndexer:

JASS:
static if thistype.index.exists then
            static if thistype.deindex.exists then
                private static method onInit takes nothing returns nothing
                    call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
                    call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
                endmethod
            else
                private static method onInit takes nothing returns nothing
                    call RegisterUnitIndexEvent(Condition(function thistype.onIndexEvent),UnitIndexer.INDEX)
                endmethod
            endif
        elseif thistype.deindex.exists then
            private static method onInit takes nothing returns nothing
                call RegisterUnitIndexEvent(Condition(function thistype.onDeindexEvent),UnitIndexer.DEINDEX)
            endmethod
        endif

and all these functions are boolexprs, so you can't pass values to them, for example onIndexEvent.


The following code is basically your example from the tutorial. Look at the initializer of the struct InterfaceTest (the second one where minimize is called). The minimize method and the costfunction get executed correctly but how should I pass any parameter to the minimize method?

JASS:
struct InterfaceStruct extends array
    private static trigger eventTrig = CreateTrigger()
    private static trigger fireTrig = CreateTrigger()
    static thistype data = 0

    private static method onEvent takes nothing returns boolean
        local integer prevData = data
        set data = 5
        call TriggerEvaluate(fireTrig)
        set data = prevData
        return false
    endmethod

    private static method onInit takes nothing returns nothing
        call TriggerAddCondition(eventTrig, Condition(function thistype.onEvent))
    endmethod

    static method register takes boolexpr bc returns nothing
        call TriggerAddCondition(fireTrig, bc)
    endmethod
endstruct

module INTERFACE_MODULE

    static if thistype.MyCostFunction.exists then
        static method minimize takes nothing returns boolean
            call BJDebugMsg("minimize!")
            call thistype(InterfaceStruct.data).MyCostFunction(1.0)
            return false
        endmethod

        private static method onInit takes nothing returns nothing
            call InterfaceStruct.register(Condition(function thistype.minimize))
        endmethod
    endif
endmodule



struct InterfaceTest extends array
    
    private static method MyCostFunction takes real r returns real
        call BJDebugMsg("costfunction!")
        return I2R(2*2*2*2*2*2*2*2*2*2*2)
    endmethod
    
    implement INTERFACE_MODULE
    
    private static method onInit takes nothing returns nothing
        // Parameters?
        call minimize()
    endmethod
endstruct
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Yes, with global variables. Thats exactly what I already suspected.

Then I have to set global variables before each function call, that is super messy (function interfaces do the same, but as its handled by the compiler its fine). Also you still have to use a predefined name for the costfunction.

Those things were actually made to improve readability and level of abstraction. Of course I can use globals, but I also can just use a hardcoded costfunction too, which would be the fastest of all possibilities. But that would be a quite bad design, as a costfunction is usually (no, always) problem specific and therefore up to the designer.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
I don't say its hard. It just has many disadvantages as mentioned above. I think readability, level of abstraction and ease of use should also be considered when making a new standard, not only pure performance.

The user would not just have to use a predefined name for the function but also remember the names of the global "parameters" to set. The method is error prone and the code will be very ugly and unneccessary long.


That its a standard practise here is not relevant. Why do you want to have a new standard? Because you don't agree with some of the things that may be standard practise here, right?
 
Top