8 ms·
Be careful of the examples you use. They stick
- teddyh 3y agoOh, absolutely. If you give people an example (and you should), the overwhelming majority will copy the example exactly and then only change what they are forced to change when it doesn’t work otherwise. Therefore, prepare your examples accordingly.
- bradley13 3y agoThis may be an actual answer to the problem. If you show "someprefix" as an example, then give users a helpful error message if they actually type in "someprefix". Something like "Dear user, someprefix is only an example, please replace this with a name appropriate to your business."
- teddyh 3y agoNo, you’ll only get “someprefix1”, and about 14 similar variants. What you need to do is either prepare a reasonable prefix valid for all (or at least most) users, or have the documentation to be dynamically prepared for each user, with a dynamically generated appropriate prefix for each user. Alternatively, you’ll have to teach users what kinds of prefixes would be appropriate, with an example which is obviosly not appropriate for any of your actual user. This will take some length of text to explain, and many users will not read it, and may instead abandon your service. Relatedly, I’ve always disliked when programs force me to name N number of things without adequately explaining • What the names are (Is this some kind of group name? Instance name?) • How the name will be shown. (Should I prefix the name with the company name myself, or will that always be visible? Will this name be shown together with numerous other names which are all UPPER CASE? Will the name be automatically converted to lower case?) • If any of these names will be publicly visible. • If any of the names can be changed later, and how hard it is. • What characters are allowed (Are spaces, underscores, or dashes allowed? How about Unicode? Emojis? What is the normal naming scheme?) • How long is the name allowed to be? (Will it be silently truncated at 8 or 16 characters (or grapheme clusters)?)
- jmondi 3y agoAbout 5 years ago I made a blog post detailing how to use Traefik/LE with PHP. For about one day, I realized I had my personal email in the template for the warning email for when the Lets Encrypt cert is expiring. I still get emails warning random people that their domain is going to expire. Prepare your examples accordingly.
- Qwertious 3y agoThis sounds like a great way of getting some petty revenge while writing documentation.
- OkayPhysicist 3y agoThis also applies to code. I come across the situation A LOT in OOP codebases that they have completely superfluous interfaces and/or abstract classes, that are made pointless by the fact that every single implementation extends some example implementation. The most egregious example I ever found was a Minecraft mod which had an interface, implemented by an abstract class, which had another abstract class that extended it, which was implemented by a an example class. Every single mod I could find (sample size of ~1000) just extended the example.
- andirk 3y agoCan we please use `example.com` for an example domain name instead of like `somedomain.com`? It can create accounts with emails that someone can actually intercept.
- tialaramex 3y agoThere is also an entire TLD, .example so that you can put multiple names in a TLD and distinguish big-corp.example from my-local-store.example and it's clear that those aren't related, they just share a registry the same way as letsencrypt.org and wikipedia.org do
- azeemba 3y agoexample.com is officially reserved in the spec for this use case. Is the .example TLD reserved as well?
- bawolff 3y agoYes https://www.rfc-editor.org/rfc/rfc2606.html https://www.rfc-editor.org/rfc/rfc2606.html
- jxf 3y agoIt is (in RFC 2606), along with .test, .invalid, and .localhost, for similar reasons [0]. https://datatracker.ietf.org/doc/html/rfc2606 https://datatracker.ietf.org/doc/html/rfc2606
- Cyykratahk 3y agoYes, here are the reserved TLDs [0]: test example invalid localhost local localdomain domain lan home host corp 0. https://www.ietf.org/archive/id/draft-chapin-rfc2606bis-00.html#legacy https://www.ietf.org/archive/id/draft-chapin-rfc2606bis-00.h...
- Karunamon 3y agoBe careful, that is a decade plus old expired draft of a proposed update to RFC 2606. The current version of the standard, including 6761 which updates it, does not reserve most of those. https://datatracker.ietf.org/doc/html/rfc2606#page-2 https://datatracker.ietf.org/doc/html/rfc2606#page-2 https://datatracker.ietf.org/doc/html/rfc6761 https://datatracker.ietf.org/doc/html/rfc6761 You are probably safe using names like .lan and .corp but they are not currently protected by standard in the way example is.
- alex-moon 3y agoThe opposite is also true. It happens rarely, but I have been bitten by trying to configure something to be what I would like it to be, only to discover it had to be what was in the documentation for it to work, generally with nothing in the documentation itself to clarify. Can't think of any examples now though I'm afraid.
- gjvc 3y agoCan't think of any examples now though I'm afraid. Dodged a meta-bullet there...
- mh_ 3y agoHeh. "You can totally put in any value here, as long as its exactly this one"
- DoreenMichele 3y ago"You can have any color car you want. As long as it's black." -- Henry Ford
- doctor_eval 3y agoCompletely off topic aside but I read somewhere recently that the reason for this was that black paint dried much faster than any other colour, which meant less time taking up space in the drying room, which meant more production capacity. So basically it was black because that kept production costs down.
- tetrep 3y agoI don't think that's in opposition to the posted article, it's just a lack of documentation ("with nothing in the documentation itself to clarify").
- PeterisP 3y agoAn interesting thought is that the examples in your documentation don't necessarily need to be static and the same for everyone. For example, if a user is logged in, you can autofill the appropriate accounts/domains/ids/etc to make the example work out of the box; and if some ID needs to be essentially random, then you can make it actually random when you generate the example.
- nicexe 3y agoThey don't have to be static but making them dynamic might not worth the cost. From a simple static page, now you need an API service, most probably connected to a DB or somehow integrated to the rest of your backend. So markdown suddenly isn't enough and you need some server-side logic. For random strings, you can do this with client-side logic, which in some cases might be easier than server-side logic. But you are still moving from no-logic (static) to somewhere-logic.
- tough 3y agoSwaggerUI/OpenAPI support this to add your own users API credentials to the api call examples, if you care to implement. as a develoer, is just a nice touch that I can copy paste an example of code snippet and since I'm logged in they can give it to me already with a valid api key. ymmv They also allow to output examples in as many langugages/sdk's as you need too
- nicolaslem 3y agoThis unfortunately encourages users to hard-code secrets since the example snippet they get literally does it.
- nicexe 3y agoI'm thinking if invalid characters in the examples given would be an acceptable solution. For DNS records this could be XML-like tags like <someprefix>.<yourdomain>.<tld> On one hand, it prevents blind copy-pasting but on the other hand, your example is invalid.
- kevincox 3y agoFor procedure documentation I often use ${service_namr:?} For similar reasons. If the variable isn't set you get a clear error. And it provides an easy way to use the template without modification. It isn't perfect, common variable names may already be set or have been set in a previous execution of this playbook on a different problem. But it catches common issues while being convenient.
- croes 3y agoAn invalid example could confuse the customer and create unnecessary support calls.
- sanderjd 3y agoYeah I think this is the only good solution, really. Otherwise it's just often unclear which things are required to have a specific value, and which things can be replaced. In this example, I'm sure plenty of people thought it was possible that "someprefix" was required, rather than just an example.
- l0b0 3y agoThis is also an opportunity to think about the value of a piece of configuration. If an example configuration value works for 40% of users without modification, should that value even exist? Think Bash's `HISTCONTROL=erasedups`, which shouldn't be necessary to set in the 21st century. Or should it be auto-generated, like Docker's container names? In the very best case, the defaults are so good that an empty configuration does what most people want. Think ripgrep, …, welp, I can't really think of many good examples. Browsers need extensions, Bash needs a decent prompt, even many pro cameras need to be configured to save raw images by default.
- kzrdude 3y agoHow do we combine evolution and development with backwards compatiblity? I think it's quite natural that we end up with this conundrum. Like say for example Vim having outdated defaults, because changing them could disrupt existing users. A reboot/fork of it can reset and start fresh but will eventually in its own development hit the same problem. Are there examples of projects who solve this well? Ripgrep's author is also very careful about breaking changes - I think that means it will also one day have outdated defaults!
- Karellen 3y agoA reasonable compromise would be to allow changing defaults whenever there's a major version bump. ripgrep seems to have a major version bump every 18 months or so, which seems a bit excessive. OTOH vim went through 9 versions in 30-something years which seems more reasonable. Although I think there was more churn early on. ISTR vim 6 being around for a long time.
- burntsushi 3y agoDoes vim follow semver? (vim predates semver...) So how do you know you're comparing apples-to-apples? Look at the breaking changes in each ripgrep major release. I don't use major releases as a means of breaking popular workflows. I use major releases even when there are very small breaking changes with minimal impact.
- personjerry 3y agoWhy is "use more examples" the solution? If the users are copy pasting the code, why not just generate random strings thereby showing an example and also fulfilling their own requirement of non-identifiable strings?
- albinowax_ 3y agoA random string may look suspicious and the goal of this is to avoid suspicion
- hardware2win 3y agoHow about generating randomish suggestion like company-35642.domain.com
- jan_Sate 3y agoI find it funny how people would just happily use `someprefix` as the subdomain. Isn't it obvious that it's meant to be replaced with another prefix?
- assbuttbuttass 3y ago> When given an example, a significant number of users default to using that same example in their customisation. The behaviour is consistent across customers and configurations. This surprised us! This is not surprising to me at all. Maybe the authors have never used an example before?
- codeflo 3y agoWell, I’m also the sort of person who wouldn’t. Similarly, I also never copy&paste example code when reading documentation, instead, I immediately jump into writing my own variation. It took me a while to realize that’s not typical.
- RegW 3y agoOften examples don't make it clear what is expected. As a consequence you might copy the example value temporarily until your understanding solidifies, but it never does, or doesn't before it gets a dependency on it. So foo.bar.com or my-subdomain.example.com?
- Sakos 3y agoI'd rather try the defaults, see if it works or what doesn't work, or just to gain some experience for how everything involved works, and then work off of that known baseline. Anything else just feels like randomly throwing shit at the wall to me. Especially if I'm not familiar with the thing I need the example for.
- DoingIsLearning 3y agoWasn't the DMCA takedown of youtube-dl also caused by an example in documentation where they used a youtube link to some big name vevo artist?
- chasd00 3y agoI gave what my company calls a “lunch and learn” presentation once of some interesting tools. People liked it and shared my deck around which was cool. But then my quick/dirty examples started showing up in best practice (I loathe that term) decks shared to very large teams with my name at the bottom. A security guy, who I greatly respect, raised some questions and I had to go through the whole story with him and then find all references to my examples and fix them. It was pretty embarrassing.
- ThalesX 3y agoI did a similar thing as part of a "lunch and learn". NodeJS + Express was super fresh and I did a small example app. When returning the user profile, I just queried the database and returned the entry displaying some properties on the frontend. The team lead was like "show us the request in the console", and I opened it up and there was the non-encrypted password, createdAt date and basically all the not-needed properties. I still cringe thinking about it.
- l33t7332273 3y agoI don’t think that’s so bad. It’s a demo, not an end product.
- ranting-moth 3y agoNo need to cringe, this is exactly what demos are. A hack to demonstrate functionality.
- chasd00 3y agohah what i did involved a db too, a string based query without sanitization introducing a possible sql injection. The input never came from a user and was sourced from a config file but i still should have known better. I learned that if you put it in a slide, no matter scope/purpose, it better be production quality because people are just going to copy/paste.
- catchnear4321 3y ago
- xeonmc 3y agoprintf("Hello World")
- jhoechtl 3y agoVery true. Good examples consume a lot of time. I was bitten a couple of times when the customer nailed me down with "But this example can never occur" and my futile attempt to justify "But it's an example!" Good examples make documentation worthwhile to read. Good defaults make an application worthwhile to use.
- bawolff 3y ago40% !! I could kind of tell where this article was going from the first paragraph, but i never thought "some-prefix" would be used by 40%. That is such a high number.
- teddyh 3y agoOn the contrary, for those of us who have experienced The Public it seems rather low.
- fastball 3y agoThis isn't quite the point of the article, but we allow people to apply for student discounts for our service, and provide the following example that we ask users to send to us over Intercom: > Hello, could I please apply for the student discount? > > [PLEASE READ AND DELETE THIS – After sending this initial message, please attach a proof of your student status, such as a photo of your valid Student ID so we can process this quicker!] I don't think any of the countless people that have asked for the discount have ever removed the "PLEASE REMOVE" part, and many don't bother to send the proof until we ask for it either.
- im3w1l 3y agoI think you should just remove that example entirely then. It barely adds anything and as you said it is causing recurring issues.
- lornajane 3y agoThis is such a great story and an important one. I always optimise examples for people copying and pasting, trying to make it as safe and meaningful by default as possible. It doesn't matter why you're copying and pasting - you may not have a lot of skills in this specific area, or you might be in a hurry. If you know what you're doing, you can probably improve the code, but if you use it as-is, it shouldn't come back to bite you!
- recursivetech 3y agoA few years back, I recall reading about some automotive manufacturers who had just copied an example "airbag arming authorization" code/value that appeared in a shared spec document (IIRC) for their vehicles. There was a Metasploit module created (for the Hardware Bridge) that would send CAN bus messages to just check/verify if a particular vehicle uses this insecure arming code. For vehicles using this known code, an attacker with CAN bus access could deploy airbags on an unsuspecting target during vehicle operation. https://www.rapid7.com/blog/post/2017/12/22/metasploit-wrapup-21#nowavailableairbagauthentication https://www.rapid7.com/blog/post/2017/12/22/metasploit-wrapu...
- eschneider 3y agoI've done some commercial software SDKs and this strikes me as the least surprising thing in the world. MOST programmers will copy and paste example code into production applications without really thinking about how well it fits into what they're doing. The takeaway is similar to the article: think very, VERY hard about your examples and sample code. It doesn't just have to be correct and demonstrate the features, it also needs to be fairly robust so that customers don't hurt themselves with it.
- BtM909 3y agoI think this is also true for trivial / hypothetical examples. I used to work at a global company that would use 'acme' as an example domain, including for emails and such. Because when we started, the domain didn't exist so test emails would just disappear in void. Until the domain was registered and is actively being used.
- SilasX 3y agoThere used to be a blog where someone registered DoNotReply.com and posted all the replies he got as a result of companies using that as a default reply-to in emails — which often included sensitive information. It’s not around anymore but here’s a discussion of it when it was up: https://boards.straightdope.com/t/donotreply-com/442816 https://boards.straightdope.com/t/donotreply-com/442816
- im3w1l 3y agoIn-band signalling often seems to have this issue where it's not 100% clear what is part of the message and what is part of the meta-message. Edit: I think it's mildly amusing and further drives the point hom that some people in this thread missed endnote 1, where you say it was not the actual prefix.
- JohnMakin 3y agoReminds me of a large company I worked at, I had some documents for developers how to set up some local environment thing they had to do exactly 1 time and never again. It was just a handful of terminal commands, all starting with the traditional shell notation like: $ (some command) Over the course of a year I got periodic complaints that it "wasn't working" and I tried to find issues on my end and couldn't. One particularly vocal dev came to me directly and insisted it was broken, so I went on a shared session with him, it turns out they were pasting the "$" into the terminal causing it to say: "$: command not found." That was the source of all the complaints, once I removed it, they stopped.
- hiAndrewQuinn 3y agoIs there a reason websites put that $ in front of commands you are fully expected to mindlessly copy and paste? I've seen it happen more and more and it simply baffles me.
- bsilvereagle 3y ago“$” for non-root shells and “#” for root shells instead of writing out sudo/su.
- youainti 3y agoThis is exactly why. If you are doing linux maintenance, this is really helpful because you can tell if you should be running a specific command as root or user. If you are just giving instructions on what to do for a normal user, omitting it is probably fine. If you are doing something that will require both, it might be good to explain it at the beginning of your instructions.
- jabroni_salad 3y agoAs a generalist with many operating systems in use, I like that this tells you what OS the command is for. Especially now that powershell with its many unix-like aliases is getting popular, this isn't always evident.
- afry1 3y agoIf I had a dime for every time I saw somebody copy and paste "#myExampleWidget" into production code ...
- jcynix 3y agoIronically enough that this posting's title seems to be ignored by people which cite parts of RFC 2606 which states at the beginning: > Updated by: 6761
- EvanAnderson 3y agoI've run into a number of networks in my area (private businesses, a couple municipalities, a couple law enforcement agencies) all using the 192.9.1.0/24 subnet. There was some overlap in these sites w/ respect to IT service companies involved in their setup. Best as I can guess it came down to one person who floated between the employ of a couple (or three) IT service companies leaving a swath of 192.9.1.0/24 in their wake (or maybe training other technicians during their time at these companies). It seems like this work might have been done pre-RFC 1597 (which is, I think, the first place that what is today's RFC 1918 address space shows up) but I think they were just following examples. I'd love to know what examples motivated the us of this address space. I find some old Sun docs[0] referencing this address space, and RFC 2328[1] makes reference to it. [0] http://bitsavers.informatik.uni-stuttgart.de/pdf/sun/sunos/3.0/800-1323-03B_System_Administration_for_the_Sun_Workstation_198602.pdf http://bitsavers.informatik.uni-stuttgart.de/pdf/sun/sunos/3... [1] https://www.ietf.org/rfc/rfc2328.txt https://www.ietf.org/rfc/rfc2328.txt
- pxc 3y ago> Frankly it’s a reason enterprise software is often so terrible; tons of options you barely understand or know about, and are configured according to tutorials/examples rather than understanding. This article stresses that it's not a 'customer-side problem', and what they'll do to try to address it on their end. But is there anything that enterprises can do in order to encourage people not to work blindly from tutorials? What do companies where workers avoid this pitfall look like?
- superfrank 3y ago> It’s important to realise this isn’t a customer-side issue; they shouldn’t have to consider the impact of every configuration option we choose to put in front of them. They don’t have the full context and knowledge, and expecting them to be experts in the nitty gritty of Canarytoken discoverability Yes! > Going forward, we will show multiple examples of prefixes. A user looking to add a custom domain will see a variety of example zones when they visit the page, and the examples will cycle each time they open the configuration page. We want to convey that they have options in choosing the name, and we show them a variety of sample options. Our hope is that this will prompt customers to pick their own names, and if they do rely on our examples then those are now spread over a large list of examples. No! They were so close and yet it sounds like they've still missed the point. The issue is that users don't understand the "why" behind the prefix. Just randomizing the prefix that they're shown does nothing to change that. IMO, a better solution would be. 1. The shortest possible explanation under the field of why you shouldn't use "someprefix". 2. Prevent users from using "someprefix" as the prefix and show them the warning again. By eliminating the default option as an option, you force your users to leave auto-pilot mode and actually consider their choice.
- cmovq 3y ago> 2. Prevent users from using "someprefix" as the prefix and show them the warning again. Don't do this - examples in documentation should be valid. Having an example that doesn't work when the user tries it out will just lead to frustration.
- Tobani 3y agoI ran a blogging SaaS platform for a while. I had some instructions for configuring a reverse proxy to serve the blog. There were instructions for most major web servers. One step was adding a custom header. - Go to <link> and get your publisher ID - Add the following line to your config(replacing xxx-xxxx-xxxxx with your code from the previous step): AddHeader X-Publisher-Id: xxxx-xxxxx-xxxxx; We had a bunch of people leave the x's in and were confused why it wasn't working. So we made a blog that explained the misconfiguration, and replaced xxxx-xxxx-xxxxx in the documentations with that blog's ID. We got far fewer support requests after that.
- tangentstorm 3y agoThis reminds me of the association between tetanus and rusty nails. Why would rust make the presence of bacteria more likely? Is it a food source? No, tetanus on a rusty nail was just an example used in an article many years ago. Sadly, I cannot find a source for the idea coming from an article at the moment. :/
- Lammy 3y agoSee also: Every zpool named 'tank' https://serverfault.com/questions/562564/why-are-all-the-zpools-named-tank https://serverfault.com/questions/562564/why-are-all-the-zpo...
- stared 3y agoAny template strings are ambiguous unless there is more than one example. For example, let's imagine that there is an instruction saying that in a config file, there should be: PASSWORD=[password] Let's say our password is "admin". Then it could be that: PASSWORD=admin PASSWORD=[admin] or even PASSWORD=[password] as it is not a place to actually store the password, but to select an authentication method. Sure, sometimes (but not always!), it is possible to deduce how to fill the pattern. If the field has some canonical value, go with a sane default e.g. "canary.their-company.com", with a note that any other suffix works instead of "canary". Sensible defaults save us a lot of brainpower (vide https://en.wikipedia.org/wiki/Convention_over_configuration https://en.wikipedia.org/wiki/Convention_over_configuration).