That way lies madness

PHP is well-documented. It is forgiving at first but can be ratched up in strictness. My knowledge of the language gained me my first serious employment and began my software engineering career, and this last point has secured it a place in my heart where it will never be dislodged, if admittedly in an Iron Man sort of way.

But baby, why?

<?php
	class Animal {
		static $dbTable = "animals";

		function printDbTable() {
			echo(self::$dbTable);
		}
	}

	class Bear extends Animal {
		static $dbTable = "bears";
	}

	$bear = new Bear();
	$bear->printDbTable(); # prints "animals"
?>

This has somewhat stymied a reasonably hefty piece of refactoring of this very site's backend, which I had hoped to do this weekend. I was hoping to make it so that the name of the table where a particular class of object, such as a Page or a Comment, is stored, could be reconfigured just by altering a static variable in each class. Unfortunately the Row superclass's retrieve() method, which would need to grab that static variable in order to query the database correctly, can't. It just can't. At all. Oh, and get_class() has the same issue. There is get_called_class(), which is only in 5.3.0 plus. I'm on 5.2.0. I should ask my host to upgrade, perhaps. Or find a programming language which isn't broken.

Just another of the whacking great heap of enraging programming fun which I've ploughed through so far this week. Most of you know I've been hitting the JavaScript quite hard, and most of you will probably therefore not need to be told why that has irked me of late. Here's another which springs to mind, this time a piece of code by someone else which I had to refactor slightly. This is Perl, but the programming language is basically irrelevant because the problem is universal and eternal. Why would anybody write this:

for(my $i = 0; $i < 10; $i++) {

	# code

	if( [condition1] ) {

		# maybe 200 lines of double indented code

		if( [condition2] ) {

			# hundreds more lines of triple-indented code
			# etc., maybe to two more levels of indentation
			# and the first loop was probably indented a bit already anyway

		}

		# no code at all down here
	}

	# or here
}

When something like:

for my $i (0..9) {

	# code

	next unless [condition1];

	# 200 lines of code

	next unless [condition2];

	# hundreds more lines
}

is entirely acceptable? If you're about to say "coding standards", the script in question plainly predates such things. Maybe the original coder is from Single Point Of Exit land. I'm not. Perl has these lovely keywords for a reason. This can be done in almost every other language too, if a little less beautifully.

One more minor riddle which wasn't worth a distinct post. Every few weeks, seemingly at random times and triggered by nothing whatsoever, Notepad would open on my laptop. The problem was so rare and intermittent that I never bothered to look it up. The reason? Dell's touchpad drivers have an additional "feature" which opens Notepad if you hold down three fingers on the pad for more than one second.

This feature is completely absent from the mouse/touchpad settings. I know this having been over every detail of the available options when I first acquired the machine in question. It cannot be configured or disabled. The only way one could possibly know that the feature was there was if you first investigated the specific touchpad driver, discovered that it had been manufactured by Synaptic, and then stumbled onto this page which actually documents this baffling, inexplicable feature.

Meanwhile there are people running around out there who think that they have a virus of some kind! They're running virus scans and upgrading their firewalls. The worst part is how difficult it is to figure out how to reproduce. Whoever even heard of a touchpad which did anything when three fingers were applied? This may be the very first thing I've seen which behaves so much like a bug and yet genuinely is not a bug, but an undocumented feature.

Discussion (18)

2010-05-08 00:46:59 by DTal:

TRWTF is that somebody actually spent real time and effort implementing something so utterly, patently useless. Notepad is hardly what you'd call an essential windows power tool, and nobody is EVER going to use a shortcut like that anyway. If it's a *really* frequently used app the user will bind a hotkey for it. Hardcoding a "shortcut" with a built-in delay to a seldom-used program is clearly boneheaded. How often have you used it to actually bring up notepad, now you know it exists? This sort of rushing ahead without consulting basic user interface principles annoys the hell out of me, and causes people to associate bad experiences with the machinery when the blame ought to fall squarely on the company. No company is innocent; no, not even Apple - especially not Apple in fact. And neither is the problem new. All those jokes about programming VCRs, clock radios, sat navs, etc... The next computing revolution is the interface revolution.

2010-05-08 01:50:56 by Paul:

Most programming languages (atleast php, Java & C) have the following construct available: for() { if(condition1) continue; //code } the continue keyword breaks the for loop and moves on to the next iteration, which I believe is what you are looking for.

2010-05-08 03:15:11 by JeremyBowers:

Paul: Perl has that feature. It works exactly as the code above shows. Sam's complaining that people don't use it correctly, not that it doesn't exist. ("unless" is another fun perlism. It's like if, except the conditional goes the other way. Finally, both "if" and "unless" (and a couple other things) can actually be applied after a statement. So, "next unless $i_wanna_keep_going;", assuming that's a valid variable, is a valid Perl statement. As a matter of style I prefer not to use it unless it is literally one next, one "if" or "unless", and one variable; anything more complicated than that and I prefer it broken into a conventional statement block. YMMV.)

2010-05-08 03:33:42 by Ross:

Three finger touch is a multitouch gesture. Blame Apple for making them fashionable. My new MSI external USB touchpad adds these strangely conceived gestures: three finger tap for right button two finger tap for middle button three finger drag up to open "My Computer" three finger drag down to bring up the alt-tab menu two finger drag for scrolling Some of them are configurable, but not the 3 finger drag up/down. Sigh.

2010-05-08 06:41:12 by Lar:

In my experience, a two finger drag for scrolling works very well, and I use it often. However, three button shortcuts of dubious value seem like features for features' sake.

2010-05-08 09:57:01 by Baughn:

Sane languages, eh. Hum. Have you looked at Haskell?

2010-05-08 17:54:18 by Brent:

Here's how to do exactly what you want in JS. for(my $i = 0; $i < 10; $i++) { # code if( ! [condition1] ) continue; # maybe 200 lines if( ! [condition2] ) continue; # hundreds more lines }

2010-05-08 18:07:34 by Baughn:

Hum. If we're comparing languages, here's the Haskell version. You'd probably pick more meaningful names in a real-life situation, of course. foo = replicateM 10 block1 where block1 = do code unless condition block2 block2 = do code unless condition block3 block3 = ..etc. It can get considerably more interesting if flow control is more complex. Monad transformers are *fun*. Here's hoping the parser doesn't ruin my indentation-sensitive code...

2010-05-08 21:52:22 by qntm:

Um, I do actually know how to do that in JavaScript. And every other programming language I've learned. Has something given people the impression that I didn't?

2010-05-09 00:10:26 by Baughn:

Hm. No, I don't *think* so?

2010-05-13 21:33:04 by DanKuck:

I got it. You were complaining about programmers in that part, not languages. Maybe because the gripe started by being about PHP. For PHP, I've found that static methods do override parent static methods. I use it at my job for the same thing you're trying.

2010-05-13 23:08:21 by qntm:

Static methods, yes, static variables, no.

2010-05-19 02:37:39 by JohnM:

I am generally in the same camp. I agree that there is need to always have a single point of exit. However in this case, I think I would prefer the indentation. The reason is that there are hundreds of lines, so a continue (I guess next in Perl) in the middle of that would be easily missed. Extra vertical space around the continue helps, but it does not differentiate the sections as well as the tabs. My first thought though would be to factor out the large sections of code into their own subs so that the structure of the loop is more apparent.

2010-05-19 02:38:34 by JohnM:

Bah, that should say "NO need" to have a single point of exit.

2010-05-26 00:57:42 by Mike:

@DTal: Didn't that revolution already happen? Like, [s]twenty[/s] thirty (gosh, I'm getting old) years ago? Well, that's actually a humongous time scale fail as it's closer to forty, but whatever. I myself prefer to code in C (if I need something more high-level I use Objective or ++, not #) because not only can the primitives be easily figured out even if you have never seen them (i. e., they allude to English), but because they can theoretically do whatever you want them to do. All logical functions are available, and can be expanded and deexpanded at will. It doesn't have any HTML functions, but you can just write a routine which converts C code (with a few minor modifications) to HTML. Call it CbHTML (C-based HyperText Markup Language). Or, Cb (teehee, C flat). And then its got logiccal funkshins!!!!!!!!!1!!1! But HTML doesn't work that way, and most browsers don't support Cb (Firefox does, thanks to my unreleased plugin). Thus, you have to resort to using a PHP... converter thingy. And THEN things get complicated. Then again, I'm practically BSing here. Also, don't bring Python into this.

2010-06-07 16:30:16 by Cory:

The hundreds of line block of code is what I would complain about, not the way the conditional was expressed. There's no way that's part of a modular design. Although perhaps I've been spoiled by Haskell, where if you've written a block of code longer than 10 lines, you've more than likely done something so disgraceful that you should commit suicide to preserve your family's honor.

2010-06-20 22:51:25 by sapphirecat:

Ah yes, PHP. Static variables in subclasses aren't visible from the parent because PHP helpfully *compiles* self:: to resolve to the current class. Besides the function you mentioned, 5.3.0 also added new semantics to static, so that checking static::$dbTable will do what you want. (Unless something on the way has invoked parent::, I think. This may not be accurate because I still write to 5.2.0+.) But again, it runs into the version problem. IIRC, static methods are also subject to this problem, where if you have A call self::B in a superclass, then the superclass's B is invoked, never the subclass, for the same underlying reason. This is the sort of thing that gave us things like Propel, where a separate PHP-generation step happens to get around the compile-time limits. I may have written a system once where X($a,$b) is implemented in every subclass, to call parent::_X(__CLASS__, $a, $b), which lets _X use call_user_function(array($cls, $method), ...) to invoke a static method in the originally called class. Or, I may have decided that madness lies that way, too, and completely re-engineered the mess.

2015-10-29 13:48:43 by Resuna:

Answer for "why would anyone code that way": "Maybe the original coder is from Single Point Of Exit land. I'm not." Virtually anyone who learned programming academically under the Pascal generation has been indoctrinated by Pascal's "Bondage and Discipline" coding style, which was an overeaction to the spaghetti code Fortran era. They believe in STRICT STRUCTURED CODING UBER ALLES. Single entry. Single exit. Technically you could return from the middle of a function, but you'd lose marks. When I was at Berkeley I dropped a class and took it again the next term under a different professor because the first professor was a Wirth Purist and the second had us coding in C.

New comment by :

Plain text only. Line breaks become <br/>
The square root of minus one: