<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Naming on PHP Boy Scout</title><link>https://blog-570662.gitlab.io/tags/naming/</link><description>Recent content in Naming on PHP Boy Scout</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><copyright>Matt Cockayne</copyright><lastBuildDate>Sun, 28 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog-570662.gitlab.io/tags/naming/index.xml" rel="self" type="application/rss+xml"/><item><title>A flag is not a setting</title><link>https://blog-570662.gitlab.io/a-flag-is-not-a-setting/</link><pubDate>Sun, 28 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog-570662.gitlab.io/a-flag-is-not-a-setting/</guid><description>&lt;img src="https://blog-570662.gitlab.io/a-flag-is-not-a-setting/cover-a-flag-is-not-a-setting.png" alt="Featured image of post A flag is not a setting" /&gt;&lt;p&gt;I was reviewing a change to rust-tool-base&amp;rsquo;s scaffolder when a word stopped me dead. &lt;code&gt;rtb generate config-field&lt;/code&gt;. I couldn&amp;rsquo;t have told you why in that first second&amp;hellip; I looked at it and just knew it was wrong.&lt;/p&gt;
&lt;p&gt;The verb there is &lt;code&gt;generate&lt;/code&gt;, and the verb is fine. It was the &lt;em&gt;noun&lt;/em&gt; that grated, &lt;code&gt;config-field&lt;/code&gt;, the name of the thing being made. Renaming it is a small change. It&amp;rsquo;s also a &lt;em&gt;breaking&lt;/em&gt; one, and a gut feeling is no reason to break someone&amp;rsquo;s command, so before I touched it I went and worked out what the instinct was reacting to.&lt;/p&gt;
&lt;h2 id="accurate-and-still-wrong"&gt;Accurate, and still wrong
&lt;/h2&gt;&lt;p&gt;Here&amp;rsquo;s the awkward bit: &lt;code&gt;config-field&lt;/code&gt; is correct. The thing it makes really is a field on a config struct. If that name lived deep in a package, somewhere only another developer reading the source would ever trip over it, it&amp;rsquo;d be fine. The code&amp;rsquo;s audience is me, and &amp;ldquo;config field&amp;rdquo; is exactly what the code sees.&lt;/p&gt;
&lt;p&gt;But it doesn&amp;rsquo;t live deep in a package. It sits right out on the command line, on the one surface a user actually types, and a name out there has a different job. It has to telegraph what it does to someone who has never read a line of the source, in words a layperson would reach for. By that test &lt;code&gt;config-field&lt;/code&gt; fails, and not because it&amp;rsquo;s wrong. It fails because it&amp;rsquo;s right about the wrong thing. It describes the plumbing when all the user wants is to turn on the tap.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the rule I keep coming back to anywhere a person actually touches the tool: accurate is the floor, not the bar.&lt;/p&gt;
&lt;h2 id="what-the-noun-names"&gt;What the noun names
&lt;/h2&gt;&lt;p&gt;The right name falls out of what the thing actually is, so I went and pinned that down. rtb&amp;rsquo;s scaffolder makes three different things, and the noun is how you pick which:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rtb&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# a new subcommand&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rtb&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# a command-line argument on a command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;rtb&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# a field on the tool&amp;#39;s typed config&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A flag and a setting sound like cousins, but they answer two different questions: &lt;em&gt;where does the value come from&lt;/em&gt;, and &lt;em&gt;how long does it live&lt;/em&gt;. A flag is something the user types for a single run (a &lt;code&gt;clap&lt;/code&gt; argument, in Rust terms), like &lt;code&gt;deploy --region eu&lt;/code&gt; or &lt;code&gt;--dry-run&lt;/code&gt;. Transient, scoped to the one command. A setting is a typed field on the tool&amp;rsquo;s &lt;code&gt;AppConfig&lt;/code&gt;, read from its layered config: a file, the environment, or a one-off override on the CLI. Persistent, and tool-wide. (&lt;a class="link" href="https://gitlab.com/phpboyscout/rust-tool-base/-/blob/eb13cd9/docs/concepts/flags-vs-settings.md" target="_blank" rel="noopener"
 &gt;The full contrast is its own doc now&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Put the two side by side and the old name gives itself away. &lt;code&gt;flag&lt;/code&gt; says what the thing is &lt;em&gt;to a user&lt;/em&gt;. &lt;code&gt;config-field&lt;/code&gt; said what it is &lt;em&gt;to the code&lt;/em&gt;. One tells the truth at the surface; the other leaks an implementation detail you were never meant to care about.&lt;/p&gt;
&lt;h2 id="why-theyre-two-things-at-all"&gt;Why they&amp;rsquo;re two things at all
&lt;/h2&gt;&lt;p&gt;This is the bit that makes the rename honest rather than fussy, and it&amp;rsquo;s where rust-tool-base and go-tool-base part ways.&lt;/p&gt;
&lt;p&gt;In go-tool-base, a flag and a setting are pretty much the same object. cobra and viper (Go&amp;rsquo;s CLI and config libraries) fuse them: you bind a flag, viper reads its value from a config file or the environment, and you&amp;rsquo;re done. One persistent flag laid over a config bag. That&amp;rsquo;s no compromise, it&amp;rsquo;s an excellent convenience abstraction, gtb leans on it to the hilt, and for what it&amp;rsquo;s worth it&amp;rsquo;s the model I personally find the &lt;em&gt;simpler&lt;/em&gt; of the two. One mechanism, one thing to keep in your head.&lt;/p&gt;
&lt;p&gt;Rust won&amp;rsquo;t hand you that fusion, and it&amp;rsquo;s right not to. rtb&amp;rsquo;s config is a typed &lt;code&gt;AppConfig&lt;/code&gt; (built on figment, a Rust config library), not a dynamic &lt;code&gt;get_string(&amp;quot;key&amp;quot;)&lt;/code&gt; bag, so a command-line argument and a config field genuinely are different types with different lifetimes. Splitting them isn&amp;rsquo;t rtb being puritanical about it. It&amp;rsquo;s the shape Rust&amp;rsquo;s type system gives you, and the framework leans in and makes the most of it. The rtb version is, no argument, the more type-safe of the two.&lt;/p&gt;
&lt;p&gt;So neither is better. They suit different paradigms, and both do the job beautifully. But the knock-on for naming is concrete. Once a flag and a setting really &lt;em&gt;are&lt;/em&gt; two different things, calling one of them &lt;code&gt;config-field&lt;/code&gt; doesn&amp;rsquo;t just expose the plumbing, it tells a small lie: it implies a setting is the same kind of object as the struct field it happens to sit in. &lt;code&gt;setting&lt;/code&gt; tells the truth. This is the thing you configure once and the tool remembers, the sibling of &lt;code&gt;flag&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;(rtb has form here, mind. &amp;ldquo;flag&amp;rdquo; already pulls double duty: a runtime feature flag and a &lt;a class="link" href="https://blog-570662.gitlab.io/two-kinds-of-feature-flag/" &gt;compile-time Cargo feature&lt;/a&gt; are two &lt;em&gt;more&lt;/em&gt; genuinely different things the framework keeps deliberately apart. Stretch one word across that many concepts and naming each one precisely stops being pedantry and becomes the only way anyone keeps them straight.)&lt;/p&gt;
&lt;h2 id="the-change"&gt;The change
&lt;/h2&gt;&lt;p&gt;So &lt;code&gt;config-field&lt;/code&gt; became &lt;code&gt;setting&lt;/code&gt;, and picked up its mirror image &lt;code&gt;remove setting&lt;/code&gt; to round out the trio of &lt;code&gt;command&lt;/code&gt; / &lt;code&gt;flag&lt;/code&gt; / &lt;code&gt;setting&lt;/code&gt;. It&amp;rsquo;s a &lt;a class="link" href="https://gitlab.com/phpboyscout/rust-tool-base/-/commit/eb13cd9" target="_blank" rel="noopener"
 &gt;breaking change&lt;/a&gt;, &lt;code&gt;rtb generate config-field&lt;/code&gt; is gone for good, and it earned its keep. The cost is a line in a changelog. The return is a command surface that says what it means.&lt;/p&gt;
&lt;h2 id="name-the-tap"&gt;Name the tap
&lt;/h2&gt;&lt;p&gt;The gut reaction was right, but the gut reaction was never the point. The point is what it was reacting to: a name, out on a surface a human uses, describing the machinery instead of the job. &lt;code&gt;config-field&lt;/code&gt; was accurate. It still made the user stop and think about a struct field when all they wanted was to set something up and get on with it.&lt;/p&gt;
&lt;p&gt;Nobody turning on a tap wants to think about the pipework behind the wall. Name the tap.&lt;/p&gt;</description></item></channel></rss>