diff --git a/assets/content/cookbook/Expert/-07.GoodCodingPractices.md b/assets/content/cookbook/Expert/-07.GoodCodingPractices.md new file mode 100644 index 00000000..afd1a6d8 --- /dev/null +++ b/assets/content/cookbook/Expert/-07.GoodCodingPractices.md @@ -0,0 +1,134 @@ +[tags]: / "expert,misc,hscript" + +# Good Coding Practices + +This article will go over practices that can be applied to your code, improving its quality. These are not mandatory, so it's up to you whether to make use of them. + +# Be Fairly Local! + +A feature of many programming languages is local variables, which are variables that you define inside of functions. + +One advantage of using them is making the code cleaner, a topic we will address in this sub-article. Let's take this code snippet as an example of how local variables can be of use. + +```haxe +function foo():Void +{ + if (FlxG.state?.subState is FreeplayState) + { + if (FlxG.state.subState.ostName.length > 8) + { + FlxG.state.subState.ostName.size = 0.5; + } + } +} +``` + +At a first glance, we can see a lot of repetitive references to `FlxG.state.subState`. This doesn't hurt, but is not desirable. Now let's see the same snippet, but with a local variable being used instead. + +```haxe +function foo():Void +{ + var currentSubstate:FlxSubState = FlxG.state?.subState; + if (currentSubState is FreeplayState) + { + if (currentSubState.ostName.length > 8) + { + currentSubState.ostName.size = 0.5; + } + } +} +``` + +As it can be seen, we are now storing the result of `FlxG.state.subState` inside of a variable. You may notice we didn't do the same to `ostName`, since it's not really referenced a lot. In a real scenario, the current substate could be referenced much more depending on what the code needs, which is why we store it. + +This is actually more efficient too! For every instance of `FlxG.state.subState`, each field has to be obtained individually; a local variable essentially stores the result of that. + +Have in mind that storing a value (like a number or a text string) you got from an object in a variable, then assigning another value to it, will not affect the object. + +Below is an example of that. `titleText` is an `FlxText` whose `text` field contains the content. Modifying `text` will _not_ modify the contents of `titleText`. + +```haxe +var text:String = FlxG.state.titleText.text; +text = 'My Awesome Mod'; +``` +# Explicit Types + +Unlike Haxe, in hscript there's usually no need at all to specify variables types, whether those are local variables, parameters, or even class-level fields, because, as a scripting language, it is dynamically typed. So they are simply ignored, except for `Map<..., ...>`, which does get interpreted, however it's a bit unreliable. + +Nonetheless, it might be useful to do this if you decide to revisit your code later, as they can help you understand what the code is doing. + +A type is specified using the `:TypeName` syntax. For instance, a variable for a piece of text can be represented as `var text:String`. Since these are ignored in nearly all cases, you can put pretty much anything for the type name. + +## Function Return Types + +Functions can also have **return types**, and the syntax is pretty much identical to variables. +```haxe +override function getPipis():Array +{ + if (scene == null) + { + return super.getPipis(); + } + return scene.pipisList; +} + +function spareEnemy(?enemy:Enemy):Void +{ + if (enemy == null) + { + enemy = scene.enemies[0] ?? return; + } + + enemy.performSpareAnimation(); + scene.remove(enemy); + // ... +} +``` + +Just like with variables, these types don't actually do anything, but they make it clearer what each function may do and whether to expect them to return something. + +# Formatting Rules + +Formatting rules are a set of standardized guidelines for structuring code. In this article, we'll go over two common styles for styling your code. + +## Allman Style + +```haxe +function foo(params:FooParams):Void +{ + if (condition) + { + // Pretend this does something. + } + else + { + // Ditto. + } + + var validatedParams:FooParams = { + bar: params.bar ?? new Bar() + // ... + }; +} +``` + +## K&R Style + +```haxe +function foo(params:FooParams):Void { + if (condition) { + // Pretend this does something. + } else { + // Ditto. + } + + var validatedParams:FooParams = { + bar: params.bar ?? new Bar() + // ... + }; +} +``` + + + +> Author: [NotHyper-474](https://github.com/NotHyper-474) \ No newline at end of file