The Stack Overflow Antipattern, part 2

I enjoyed Riggraz’s observation of “The Stack Overflow Antipattern”, and it made me think of another very similar pattern that I see a lot on Stack Overflow, but it occurs after the pattern that Riccardo describes, and I thought I’d outline that here.

Image by wal_172619 from Pixabay

I answer a lot of questions on Stack Overflow. I ask very few, but I’ve still fallen into this trap myself.

Once you’ve been through Riccardo’s antipattern (ignoring the other antipattern of those that don’t even make it to step 1), you are here:

  1. You’ve searched and found some random results
  2. You’ve read some SO questions that were in those results
  3. You’ve still not found a solution

If you’ve got this far, the breadth of the question you want answering has probably been narrowed a little (which helps in its own right: searching is a mild form of rubber ducking), and probably contains the basis of a worthwhile Stack Overflow question.

So you focus on the problem, write it up, and (assuming this rubber-duck exercise didn’t lead you to a solution) post the question, and answers and comments appear reasonably quickly (hey, Stack Overflow rocks!). But often these responses are bogus, half-answers, or raise further questions. It’s at this point that we see the same “not taking the time to think” that Riccardo observed. You are so focused on the original question, you become incapable of solving a far simpler follow-on question.

Here’s a small example I often see:

“I’ve seen docs and code referring to autoload.php, but I can’t find that file”

Searching for autoload.php will find a zillion irrelevant results, because pretty much every PHP project in existence has one. So the question is posted on SO. There is a simple answer to this question, which is

“install composer, run `composer install`, and it will create the autoload.php file for you”

This inevitably leads to the follow-on question:

how do I install composer?”.

This is a new sub-problem, but one that is instantly solvable by searching because it’s far less ambiguous. However, this is where the abdication of thinking kicks in, and rather than actually doing that search, you ask in the SO question comments, and sit around waiting for an answer from Someone Who Knows™ that posted an answer to the original question. This is frustrating for the answerer, who knows that the asker could find the answer to this question far faster by searching for themselves, but they choose not to because their thinking is turned off. There’s also an element of panic – the asker has obtained the attention of someone capable of understanding their problem, and doesn’t want them to escape before they have addressed the full recursive stack of sub-problems. This has led to the existence of passive-aggressive responses like LMGTFY, which are demeaning and condescending, but reflect the frustrations of those who answer questions.

What’s weirder is that I have observed myself doing this very thing, and I’ve sometimes had to stop myself posting trivial follow-up questions without thinking. Avoiding having to think is evidently a compelling driver.

I emailed Riccardo about his article with some of the thoughts that led me to write this, and he came back with another interesting observation: This loss of confidence that leads one to post trivial follow-up questions is very much like imposter syndrome. Having had to ask a question in the first place can provoke feelings of embarrassment or inadequacy, and anyone that responds in a positive way will appear to be in some way superior, which is fully expected, but at the same time provokes feelings of “we’re not worthy”, further reducing one’s confidence to be able to deal with even simple problems.

We’re not worthy

I know that Stack Overflow (and GitHub issues) can sometimes be harsh on new users, and old hands (like me) can forget what it’s like to be a beginner. It can be very frustrating to answer questions that have been answered many times before (“my PHP script just gives a white screen”), and I’ve occasionally found myself editing my initial reaction to avoid unkindness. In those situations I usually try to overcompensate by offering more general advice about how to avoid getting stuck in dead-end situations like that, rather than just answering the precise question asked.

In PHPMailer I have tried to head off support questions before they arise by adding links to documentation in error messages, but it doesn’t stop people posting questions like this:

I have this error:
> 2020-05-16 07:28:11 SMTP connect() failed.
> https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting

I have been stuck on this for 2 weeks, and I searched the entire internet three times
Where can I find out how to fix it? You must help me urgently!

I don’t really know what to do when faced with this. Posting a substantive answer is probably pointless – if they have not read what’s right in front of them despite their evident frustration, chances are they will not read any answer you post either, especially since it will only contain exactly what’s in the link provided anyway. Sometimes the best thing to do is vote to close the question, usually as an inevitable duplicate. I see very similar things happening in GitHub issue templates – askers delete the boilerplate text, removing something which would usually help them solve their exact problem in a few seconds, but they go out of their way to make the process take longer and involve others unnecessarily, because apparently not having to think is a more attractive proposition.

I’ve also considered pushing in the other direction, such as by adding “delete this line from the debug output before posting questions about it, or your question will be ignored” as a way of enforcing reading the error messages, but that’s unkind.

I’m not sure how to address the abdication of thinking issue though. Perhaps offer up search results derived from comments or answers, much in the same way that Stack Overflow does when you first post a question? There are probably extensive psychological studies on this pattern of behaviour, and it may well have a name, but that’s a question for another Stack Exchange site.

WordPress Rewrites without .htaccess

It’s been known for many years that apache’s AllowOverride .htaccess files incur a performance hit, as every node on the path from the location hit to the document root need to be checked for .htaccess files and parsed. I’ve mostly avoided the whole issue by hosting on nginx instead, but I recently needed to host WP on Apache again and ran into this issue. Many places offer a snippet like this for rewrites from a .htaccess file:

RewriteEngine On
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L]

This says:

  • If the request is for index.php, serve it as is.
  • If the request is for a file or folder that does not exist, serve index.php instead.
  • Implicitly, if the request is for a file or directory that does exist, serve that.

The problem is that while this will work in a .htaccess file, it won’t work in main apache config because REQUEST_FILENAME will just be a filename, not a whole path, so it’s unlikely to match. The solution to this is to prepend the document root:

RewriteEngine On
RewriteRule ^index.php$ - [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L]

This took me a silly amount of time to solve. I found the critical info in this post, but I thought I’d clarify it here. HTH!

Getting the modulus of an SSL public key

Getting a hash of the modulus of SSL keys and certificates is a nice simple way of making sure they match.
I’ve found lots of docs that tell you how to get the modulus of a private key, CSR or certificate, but I had trouble finding how to do the same for a public key, where the PEM-encoded file begins -----BEGIN PUBLIC KEY-----. The public key is x509, but this openssl command produces an error because it’s expecting a certificate rather than a public key:

openssl x509 -noout -modulus -in mykey.public | openssl md5
unable to load certificate
140735178354768:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:701:Expecting: TRUSTED CERTIFICATE
(stdin)= d41d4e9400998ecf8cd98f00b208427e

The solution is simply to tell it that it’s a public key with the -pubin switch:

openssl rsa -noout -modulus -pubin -in mykey.public | openssl md5
(stdin)= 6ab17b2db672280921e1c5fed6908187

(Hashes altered to protect the innocent!)

Review of “Getting Started with PhantomJS”

Review of Packt Publishing’s “Getting Started with Phantom JS” by Aries Beltran

[iframe src=”http://rcm-na.amazon-adsystem.com/e/cm?t=marcboin-20&o=1&p=8&l=as1&asins=1782164227&ref=tf_til&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr” style=”width:120px;height:240px;” scrolling=”no” marginwidth=”0″ marginheight=”0″ frameborder=”0″]

I was asked by Packt to review several books, but I chose “Getting Started with PhantomJS” because I was actually interested in it! I’ve used various faceless web browsers before, in particular webkit in GTK applications like wkhtmltopdf or with python or PHP bindings. wkhtmltopdf (and the related wkhtmltoimage) in particular has been suffering from neglect – it has lots of depedencies and it’s difficult and unreliable to build and use (something I’ve written about before). I’ve most often used server-side browsers for tasks like generating page preview images, and seeing that phantomjs will do that, I’ve long thought I’d like to know more about it so that I could get away from custom-building complicated webkit stacks.

As far as I’m concerned, the two key things that phantomjs brings are a straightforward build process (a simple ‘brew install phantomjs’ for me) and a simple way of scripting the virtual browser, with the ability to inject scripts into the page, without having to resort to peculiar tricks, messing with virtual frame buffers or installing odd browser plugins.

I hadn’t realised phantomjs’s own scripting environment was quite so complete, supporting commonJS module integration. The separation between browser and page contexts (using `evaluate`) is clean and easy to get to grips with, and the book presents this well.

The book mentions several extensions to phantomjs that I had not encountered and look useful (particularly casper).

I hadn’t spent much time reading phantomjs’s own docs, but when I looked at them I found that they are very limited. Even though it’s not long, the book goes deeper into examples and explanations than the docs, so there is genuine value in having the book.

All of the example code I tried worked without a hitch. Packt’s web site sets a wrong MIME type on zip downloads, resulting in a page full of rubbish, but it unzips ok when saved manually. There are more example files than are mentioned in the book, which is a welcome bonus.

One small error I spotted suggested using single quotes around JSON values – that’s not valid JSON, though it is valid Javascript. It also mischaracterises JSON slightly – object syntax is part of the Javascript language, so it’s not a separate thing when you’re already in a Javascript context.

One formatting issue costs a little typing – while all the code samples are provided as text and in files, all the displayed command lines (for example when a long URL is passed as a param) are in images, so you can’t copy and paste commands as text. Call me lazy!

The English is generally good, concise and to the point. This is not a long book, but it doesn’t need to be as a “getting started” guide on something that is a pretty confined subject. The editing had a few holes – several typos had sneaked through, things that would have been caught by any spell checker. The code samples had been updated recently, but there were no errata. Oddly, getting to errata is annoying on Packt’s site – when you’re looking at a book’s page there is no link for it. You have to go to the “code and errata page” and select the book from the pop-up menu. This menu is sorted by the exact book title (and contains ALL their book titles!), so I had to look under ‘getting…’ rather than ‘phantomjs’. This could be made much easier.

There are several other books and resources for learning and using phantomjs, and they may be sufficient for some users as it is a fairly small subject to cover. Overall I was impressed with the book. It does exactly what the title says, provides useful links for further reading, and provides effective, useful scripts that cover much of what many will want phantomjs to do in sufficient detail to make it easy to derive your own. Well done Aries!