{"id":1081,"date":"2017-09-06T13:22:17","date_gmt":"2017-09-06T13:22:17","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=1081"},"modified":"2021-10-08T11:07:59","modified_gmt":"2021-10-08T11:07:59","slug":"the-evolution-of-the-accessors-library","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2017\/09\/06\/the-evolution-of-the-accessors-library\/","title":{"rendered":"The Evolution of the accessors Library"},"content":{"rendered":"<p><em><a href=\"http:\/\/www.funkwerk.com\"><img loading=\"lazy\" class=\"alignleft size-medium\" src=\"http:\/\/www.funkwerk.com\/wp-content\/themes\/funkwerk\/library\/images\/logo.png\" width=\"250\" height=\"81\" \/><\/a>Ronny Spiegel is a developer at <a href=\"http:\/\/www.funkwerk.com\/\">Funkwerk AG<\/a>, a German company whose passenger information system is developed in D and was <a href=\"https:\/\/dlang.org\/blog\/2017\/07\/28\/project-highlight-funkwerk\/\">recently highlighted on this blog<\/a>. In this post, Ronny tells the story of the company&#8217;s open source <a href=\"https:\/\/github.com\/funkwerk\/accessors\">accessors library<\/a>, which provides a mechanism for users to automatically generate property getters and setters using D&#8217;s robust compile-time features.<\/em><\/p>\n<hr \/>\n<h3>A little bit of history.<\/h3>\n<p>We&#8217;ve always used UML tools to visualize the internal structure and document details of software. That&#8217;s true for me not only at Funkwerk, but also in the companies I worked before I joined the team here in Karlsfeld. One of the major issues of documentation is that at some point in time it will diverge from the actual implementation and become outdated. Additionally, if you have to support old versions of your components you will have to take care of old versions of your documentation as well.<\/p>\n<p>The first approach to connecting code and model is to generate code from the model, which requires the model to reflect the current implementation. When I joined Funkwerk we were using <a href=\"http:\/\/argouml.tigris.org\/\">ArgoUML<\/a> to manage class diagrams which were used as input to generate code. Not only class or struct skeletons were generated (existing code was kept), but also methods to access members which were not even part of the model. In order to control whether a member should be accessible, annotations, similar to UDAs (<a href=\"https:\/\/dlang.org\/spec\/attribute.html#uda\">User-Defined Attributes<\/a>), were used as part of the member documentation. So it was very common for us to annotate a member with <code>@Read<\/code> or <code>@Write<\/code> even though it was only in the documentation. The tool which we used to generate code was powerful enough to create the implementation of these field accessor methods supported by annotations to synchronize access, or to automatically use invariants for pre- and post-conditions as well.<\/p>\n<p>Anyway, the approach of using the model as a base for code generation always suffers from the same problem: it is very hard to merge models!<\/p>\n<p>So we reversed the whole thing and decided to create documentation from code. We could still use code which had been generated before, but all the new classes had to be supplied with accessor functions. You can imagine that this was very annoying.<\/p>\n<pre class=\"prettyprint lang-d\">public class Journey\r\n{\r\n    private Leg[] legs_;\r\n\r\n    public Leg[] legs()\r\n    {\r\n\treturn this.legs_.dup;\r\n    }\r\n\r\n...\r\n}\r\n<\/pre>\n<p>(Yes, we\u2019ve been writing Java and compiling as D.)<\/p>\n<p>Code which was generated before still had these <code>@Read<\/code> and <code>@Write<\/code> annotations next to the fields. So I thought, &#8220;These look like UDAs. Why not just use those to generate the methods automatically?&#8221; I&#8217;d always wanted to use mixins and compile-time introspection in order to move forward with a more D-like development approach.<\/p>\n<h3>A first draft&#8230;<\/h3>\n<p>The very first version of the accessors library was able to generate basic read- and write-accessor methods using the <a href=\"https:\/\/dlang.org\/spec\/traits.html#allMembers\"><code>allMembers<\/code> trait<\/a>, filtering by UDAs, and generating some basic code like:<\/p>\n<pre class=\"prettyprint lang-d\">public final Leg[] legs() { return this.legs_.dup; }<\/pre>\n<p>It works&#8230; Yes, it does.<\/p>\n<p>We did not replace all existing accessor methods at once, but working on a large project at that time we introduced many of them. The automated generation of accessor methods was really a simplification for us.<\/p>\n<h3>&#8230;always has some issues.<\/h3>\n<p>The first implementation looked so simple &#8211; there must have been issues. And yes, there were. I cannot list all of them because I do not remember anymore, but some of these issues were:<\/p>\n<h4>Explicitly defined properties suppressed generated ones<\/h4>\n<p>We ran into a situation where we explicitly defined a setter method (e.g. because it had to notify an observer) but wanted to use the generated getter method. The result was that the defined setter method could be used but accessing the generated getter method (with the same name) was impossible.<\/p>\n<p>According to <a href=\"https:\/\/dlang.org\/spec\/template-mixin.html\">the specification<\/a>, the compiler places mixins in a nested scope and then imports them into the surrounding scope. If a function with the same name already exists in the surrounding scope, then this function overwrites the function from the mixin. So if there is a field with a <code>@Read<\/code> annotation and another explicitly defined mutating field accessor, then the <code>@Read<\/code> accessor is overwritten by the defined one.<\/p>\n<p>The solution to this issue was rather simple. We had to use a <a href=\"https:\/\/dlang.org\/mixin.html\">string mixin<\/a> to import the generated code into the class where it shall be used.<\/p>\n<h4>Flags<\/h4>\n<p>We have a guideline to avoid magic <code>bool<\/code>s wherever possible and use much more verbose flags instead. So a simple attribute like:<\/p>\n<pre class=\"prettyprint lang-d\">private bool isExtraJourney_;<\/pre>\n<p>Becomes:<\/p>\n<pre class=\"prettyprint lang-d\">private Flag!\u201disExtraJourney\u201d isExtraJourney_;<\/pre>\n<p>This approach has two advantages. Providing a value with <code>Yes.isExtraJourney<\/code> is much more verbose than just a <code>true<\/code>, and it creates a type. When there are two or more flags as part of a method signature, you cannot change the order of the flags (by accident) as you could with <code>bool<\/code>s.<\/p>\n<p>To generate the type of the return value (or in case of mutable access of the parameter) we used <code>T.stringof<\/code>, where <code>T<\/code> is the type of the field. Unfortunately, this does not work as expected for Flags.<\/p>\n<pre class=\"prettyprint lang-d\">Flag!\u201dfoo\u201d fooFlag;\r\n\r\nstatic assert(`Flag!\u201dfoo\u201d`, typeof(fooFlag).stringof); \/\/ Fails!\r\nstatic assert(`Flag`, typeof(fooFlag).stringof); \/\/ Succeeds!<\/pre>\n<h4>Unit Tests<\/h4>\n<p>When using the mixin in private types defined in unit tests, a similar issue arose. Classes defined in unittest blocks have a prefix like <code>__unittestL526_8<\/code>. It was necessary to strip this prefix from the used type string.<\/p>\n<h4>Private Classes<\/h4>\n<p>While iterating over members of private classes, we stumbled across the issue that the <code>allMembers<\/code> (or <a href=\"https:\/\/dlang.org\/spec\/traits.html#derivedMembers\"><code>derivedMembers<\/code><\/a>) trait returns, in addition to __ctor, an unaccessible member called <code>this<\/code>. This issue <a href=\"https:\/\/issues.dlang.org\/show_bug.cgi?id=14740\">remains unsolved<\/a>.<\/p>\n<h3>The current implementation&#8230;<\/h3>\n<p>The <a href=\"https:\/\/github.com\/funkwerk\/accessors\">currently released version<\/a> covers the aforementioned issues, although there is still room for new features.<\/p>\n<p>An example might be to provide a predicate which is then used for synchronizing access to the field. That was possible using the old version of the code generator by annotating it with <code>@GuardedBy(\u201cthis\u201d)<\/code>. Fortunately, we&#8217;ve advanced in our D coding skills and have moved away from Java code compiled with DMD to a more D-like style by using structs wherever we need value semantics (and we don\u2019t have to deal with thousands of copies of that value). So at the moment, this doesn\u2019t really hurt that much.<\/p>\n<p>Another interesting (and <a href=\"https:\/\/github.com\/funkwerk\/accessors\/issues\/11\">still open issue<\/a>) is to create accessors for aliased imported types. The generated code still refers to the real name of the type, which is then unknown to the compile unit where the code is mixed in.<\/p>\n<h3>&#8230;has room for improvement!<\/h3>\n<p>If you\u2019re interested in dealing with this kind of problem and want to dive into CTFE and compile-time introspection, we welcome contributions!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;ve always used UML tools to visualize the internal structure and document details of software. That&#8217;s true for me not only at Funkwerk, but also in the companies I worked before I joined the team here in Karlsfeld. One of the major issues of documentation is that at some point in time it will diverge from the actual implementation and become outdated. Additionally, if you have to support old versions of your components you will have to take care of old versions of your documentation as well.<\/p>\n","protected":false},"author":24,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[26,28,9],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1081"}],"collection":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/users\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=1081"}],"version-history":[{"count":6,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1081\/revisions"}],"predecessor-version":[{"id":1376,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1081\/revisions\/1376"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=1081"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=1081"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=1081"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}