Samstag, 5. Oktober 2013

Optional Parameters in PHP, and NULL

Consider the following PHP5 code:

<?php
class A{
      function foo() {}
}
function f(A $a = NULL) { var_dump($a); }
function g(A $a) { var_dump($a); }
f(new A());
f(NULL);
g(new A());
g(NULL);


Now, consider its output:

class A#1 (0) {
}
NULL
class A#1 (0) {
}

Catchable fatal error: Argument 1 passed to g() must be an instance of A, null given, called in a.php on line 13 and defined in a.php on line 8

Okay. So, a parameter, with or without a type hint, whether required or optional, receives an A if given an A. No surprise there.

An optional, type-hinted parameter, when given a NULL, results in a NULL. I guess that's fine, too.

However, a required parameter can not ever be set to NULL.

You're right: Setting something to NULL in the parameter list means something totally different than setting something to NULL anywhere else in your code.

I guess what they were trying to do was force the = NULL, passing NULL "idiom" to represent the fact that the parameter is optional, and is not set. I guess the reason is that you can not default a type-hinted parameter to anything besides NULL. The function body can not distinguish between a NULL stemming from the default in the parameter list, and an actual NULL, and NULL is the only indication that the optional parameter was left out, so passing a NULL is disallowed in the case of a required parameter.

Or something like that. (If you omit the type hint, passing the NULL works perfectly fine, by the way, thus making it even more confusing...)

Regardless of how long, or how hard I think about it, it keeps making no sense at all. It is neither consistent, nor is it useful. It is, at best, an attempt of the language to be clever - an attempt, I should say, that went terribly terribly wrong. At worst, it is a result of some obscurity in the parser that nobody ever really thought through.

In any case, it makes me even more sad to be forced every working day to work with tools as broken as that.

Dienstag, 24. September 2013

Magento and Getters

From the Magento core code (in class Magento_Core_Model_App):

    /**
     * Retrieve request object
     *
     * @return Mage_Core_Controller_Request_Http
     */
    public function getRequest()
    {
        if (empty($this->_request)) {
            $this->_request = new Mage_Core_Controller_Request_Http();
        }
        return $this->_request;
    }


Folks... puleaze!!!?

I just wasted about an hour on finding out where $this->_request was initialized. I debugged over $this->getRequest() about a gazillion times. This is just not the way to write code, for crying out loud! The phpdoc block actually states this, right up there: Retrieve request object. Retrieve!!!!!!!!1112. It doesn't say anything about initializing it.

I mean, yeah, by now I should probably be able to anticipate stuff like that, seeing as some of the magento standard models' load() methods have an optional parameter $create that defaults to... you guessed it! True!!

Some. Not all. That would be too consistent (even if it's decidedly wrong).

Duh.

Dienstag, 10. September 2013

realX

I know that this is not a very unique idea, but it's such a common mistake one cannot be reminded of it often enough.

Only recently, I stumbled upon a code fragment that performed something akin to sudo on a webshop. It took a customer_id from the request, checked the logged-in customer's permissions, and then it went about and set a

realCustomer

to the customer from the session... or it set the customer from the request to the realCustomer, while the session customer remained untouched.... or...

See what I'm aiming at?

If you're ever tempted to use something like "real" to distinguish between two objects, please take the time and think about what that object actually represents. The adminCustomer, maybe, the loggedInCustomer, or the effectiveCustomer. But never the realCustomer.

thesaurus.com is a valuable, and deeply underappreciated, resource for coders.

Mittwoch, 5. Juni 2013

Fields a table should always have

These are fields I think should be available in (almost) every database table, everywhere:


  • id
    • A unique identifier. There might be a few exceptions, but almost every time I designed a table without a primary key, I came to regret it afterwards.
  • created_by
    • Almost always, you want to be able to find out who did what, when, where.
  • created_at
    • Almost always, you want to be able to find out who did what, when, where.
  • updated_at
    • Almost always, you want to be able to find out who did what, when, where. Obviously you don't need this field on insert-only tables.
  • is_active
    • Most of the time, you do not actually want to delete data. You want to deativate it, mark it deleted. On rare, VERY rare occasions, it makes sense to move it to another table or database. But that's really the exception. By default, just mark it as unactive or deleted or whatever. Quite often, you might want a status instead of a flag. (But only VERY rarely, methinks, do you want both. It's a smell to have a lot of flags, and it's another smell to have a status field plus flags.)
  • source
    • AT LEAST on tables that you (might at some point) import from another database, you want to mark the source. I can't count the times I've had to create enormous code monsters just to heuristically find out what data came from the last import, just to then delete it and re-start the process. DELETE FROM funny_table WHERE source='my_funny_import' would have made my life so much easier! (There, I said it: Delete. Yep, that's definitely one exception where it actually makes sense.)

Samstag, 6. April 2013

iTunes

Folks... hello??? What the heck is wrong with you guys?

Controls that don't provide visual feedback on activation; a "new" watermark that never seems to vanish; when you're in the midst of the download and then have to switch off the 'puter, after switching it on again, the download doesn't restart. You have to find the mechanism to restart it inside of some obscure non-standard menu. And when you download 2 or more things, you don't get any information about that.

And here I was, thinking that apple was overpriced and arrogant, but at least they knew how to hire usability experts for my money.

Have you eaten fruit that didn't smell good, or something?

Dienstag, 2. April 2013

A Change Of Style

It used to be that I insisted on my conditionals alwaysinghave the positive part in the front, like so:

if (isOkToDoStuff)
    doStuff();
else
    throw new Exception('unable to do stuff');

My logic was that the use of !s should be minimized, that the positive part naturally should come first, and that you should have the actual code for your function on top.

However, in recent times, I find myself liking another idiom better: handling exceptional and error cases first, and then doing what the function is supposed to do, like this:

if (!isOkToDoStuff)
    throw new Exception('unable to do stuff');
if (!otherPrerequisiteINeed)
    throw new Exception('unable to do stuff');

doStuff();


The advantage being no (ugly!) indentations or (unreadable!) &&-ed expressions for additional error conditions. Which will always creep up after the first deployment, or at least after the initial coding session. 

Plus, no occasion to forget adding curly braces to the if clause. ;-)

The other, more important advantage, is that the idiom doesn't change over time. You always have the error conditions first, the code to ultimately run at the end, and the actual code is not buried under 16-indentation-weights forged out of nested ifs.

Somehow, it isn't as elegant. But more practical. Which, mostly, is to be preferred, whether we like it or not.

Freitag, 29. März 2013

My Big Fat Christkindle Wishlist

Dear Christkindle,


this is a - probably growing - list of rules, principles and just... nice features that I would rather much like our beloved industry to implement/adhere to:
  • Webshops and web20 frameworks
    • I want ONE way to search, and one customary location for the search field (upper right corner, or upper left, or upper middle... just... ONE location)
    • In general, I want more customs for webpage design, so it gets easier for users to find their way around.
    • Keyboard shortcuts across different websites and web20 frameworks should adhere to a few agreed-upon standards (can you confirm a popup with Enter? Ctrl+Enter? Does Shift-Enter add a linefeed in a textarea?, etc.). In an ideal world, those standards should always reflect the way the user's OS does it, because that's probably the way she wants it.
    • There needs to be some framework that deploys field and form validations to the server and the client from the same source. It is unacceptable that we mess around in PHP on the one end, and then do the same thing (or, rather, hopefully something akin to the same thing) in JavaScript on the other end.
  • Other web stuff
    • There are thousands of sites that fall into a large category of content: For example, there are thousands of blogs out there, mostly consisting of large chunks of texts (aka articles). I want them presented the way I find most readable - in a large, readable font, with columns that contain about 5-6 words per line, and with good contrast (roughly the way the Readability Redux plugin for Chrome does it). The same goes for other kinds of data. 
    • At the very least, the interface should be consistent across ONE site - most sites don't even manage to adhere to that basic idea.
    • Whenever you can design something as asynchronous, you should. I don't understand why I have to wait for the whole form to reload just to realize that I forgot to fill out a field, and when I enter my zip code, I want the damn thing to fill in my city as soon as possible.
  • IDEs
    • Keyboard shortcuts in IDEs should be standardized (especially the debuggers... they're such a pain in the glute, because they use similar-but-slightly-different keys.)
  • Coding Patterns
    • SQL
      • A primary key is an arbitrary value that has no meaning beyond uniquely identifying a tuple. Never give in to the temptation of using user-provided, editable values (such as email addresses) as primary keys. It'll come around and bite you in the abdomen big time! (There is an argument to be made for meaningful keys, as long as they don't change, or change only once every few years - such as a country code. I'm quite undecided in that case, frankly. Overnormalization vs chaos.)
    • Naming conventions
      • I won't make the mistake of starting holy wars here, though I think it might be time to start thinking about some general rules that everyone knows as a matter of honor - as things currently are, I'd be happy if they even existed on a per-team basis, at least. Working with external libraries that have different conventions is a pain in the sphincter, and having underscore_fields in sql, then camelCaseFields in php, but underscore_fields again in your html forms is, at the very least, very ugly - but for the time being, I don't see that changing, so I'm going for second best.
      • At the very, very least, if the database field name is is_locked, then the name in the code should not be isOpen, hasALock, or numOfChimneysInTheFactory. Yes I've seen (and, possibly, even produced) code at a similar level of insanity, sadly.
  • General stuff
    • If an object could be represented as a file, (such as an email or a bookmark, or an actual file in a filesystem) then it should be stored in a hierarchical system of tags, much the way gmail does it.
As you can see, my general principles here are the following three:

  1. The user should not be afraid of the designer, but rather, the designer should respect the user.
  2. Whatever we manage to standardize, is one issue we don't have to think about anymore.
  3. I forgot what the third one was.

Projects I Would Love To Get Done

This is a list of projects that keep floating in and out of my head, with precious little chance of ever getting done properly. But I still love fantasizing about them, and they inspire me to learn stuff, so they are actually rather useful still.

* An ERP
* A declarative data evaluation framework
* An ORM
* An in-browser scrum board
* A game based on evolutionary algorithms
* A browser plugin to normalize pages to the user's preferred view, based on evolutionary algorithms
* That android application my father would like to have
* A working DocBook editor

If you are so kind as to respond, please don't tell me that most or all of those already exist / are way too much work for one guy / are useless / make no sense, etc. I know all that. This is not about usefulness in the technical sense.

Instead, maybe you would like to share a few of your beloved dream projects that will probably never see the light of the screen.


 This is about having fun, for the very special value of fun that geeks like me subscribe to.

Mittwoch, 6. März 2013

Where is the gorram list of E_STRICT conditions...?

I've spent something like 20 minutes now, googling and perusing php.net, in search of a comprehensive list of the conditions under which PHP 5 will issue an E_STRICT warning.

I haven't found one yet.

So.... does anybody out there have a link for me? Pretty please...?

Dienstag, 5. März 2013

I Call Poe On That One (und zwar auf Deutsch, meine Lieben!)

Unter dem Titel "Aufmarsch der Hyperkorrekten" hat sich ein gewisser, sonst unauffälliger Alexander Kisser die Seele aus dem Leib geschrieben. Das ist zunächst einmal einfach einer, der uns auch schon über "Religionsfeindlichkeit, die neue Trendsportart" und ähnliche abendländische Untergänge ausgesprochen amüsant zu unterhalten verstanden hat.

Meine Mutmaßung: Es muss sich hier um einen Poe handeln. Wie anders ist zu erklären, dass er ausgerechnet die alten, doch deshalb noch lange nicht zusammengewachsenen Themen Vegetarismus und Homosexualität wieder in die ihnen ausschließlich von unseren lieben Fundis verordnete Zwangsehe presst? Gewiss verlässt er sich auf unseren Feinsinn, unser Ironiegespür, wenn er - ausgerechnet in einem öffentlichen Artikel im Internet - den Verlust seiner Meinungsfreiheit beklagt. Dass es sich bei seiner um eine Meinung handelt, die dank ihrer jahrtausendelangen politischen Umsetzung mit allen Mitteln von politischer Macht und frommer Rücksichtslosigkeit Millionen von Menschen in ihrer Freiheit massiv beschnitten hat und auch heute noch beschneidet, gibt dem ganzen erst den gehörigen Pfeffer. Es hat schon ein gerüttelt Maß an Metahumoristik, wenn so einer so etwas abseimt.

Ich vermute aber, er möchte uns nur auf künstlerisch subversive Weise darauf hinweisen, dass einige wenige unter unseren lieben christlichen MitbürgerInnen das Konzept der Meinungsfreiheit noch nicht vollständig zerebral resorbiert haben dürften. Sie laborieren scheinbar unter dem Wahn, dass es sich dabei um die Freiheit handelt, unter allen Umständen alles und jedes hervorzuwürgen, ohne dass ihnen widersprochen wird. Zur Sicherheit sei es noch einmal erwähnt, wenn es denn auch das hunderttausendste Mal ist: es geht ausschließlich darum, dass der Staat, und nur der Staat, die Absonderung auch absonderlicher Meinungen nicht zu verhindern hat, sofern sie nicht gegen höheres Rechtsgut verstößt.

Interessant ist natürlich immer auch die Frage, worin eigentlich die beklagte Unterdrückung besteht - um echte fundamentalistische DenkerInnen noch besser imitieren zu können, hat der Autor jede Andeutung dazu gekonnt vermieden. Ich vermute, er meint damit, dass ihm die letzten beiden Male, als er seine leise Furcht vor den privaten sexuellen Präferenzen wildfremder Leute offen zur Sprache brachte, jemand mit ein paar handfesten Argumenten lautstark klargemacht hat, warum er falsch gewickelt ist. Wenn du Schwachsinn reden darfst, darf ich auch entsprechend darauf antworten. So ist es nun einmal. Aber eine solche parodistisch überhöhte Wehleidigkeit kennen wir ja von vielem, was im Fundianerlager die Veräppelung tanzt, um dessen tolldreiste Dummheit der verdienten Lächerlichkeit preiszugeben.

Um beim Thema der gekonnten Parodie zu bleiben: Ganz besonders schmunzeln musste ich beim Satz "Wer es aber wagt, leise Zweifel anzumelden, zum Beispiel, ob vielleicht Homosexuelle doch nicht die besseren Eltern sind, der wird in Bann und Acht gesteckt, vergleichbar dem mittelalterlichen Spießrutenlauf." Auch bei langen, tiefen und tiefsinnigen Meditationen will sich meinem Gedächtnis keine Szene erschließen, in der jemand behauptet hätte, Homosexuelle seien bessere Eltern. Schon gar nicht kann ich mich an Szenen erinnern, in denen irgendjemand wegen seiner Angst vor dem bösen Schwulen zu einer tödlichen militärischen Strafe verurteilt wurde. (Nachlesen hilft durchaus, bevor man sich in unpassende Metaphern versteigt.) Soweit ich mich erinnere, war es am Stammtisch noch vor so ein, zwei Jahren durchaus normal, dass gegen Schwule gehetzt wurde, meist nach der höchst versöhnlichen Einleitung "Ich hab ja nix gegen Schwule... ABER...". Eine dem entsprechende Hetze gegen Heten meine ich hingegen kein einziges Mal gehört zu haben.

Man hätte halt gern mal ein paar handfeste, methodisch saubere Studien, die belegen, dass Homosexuelle schlechtere Eltern sind. (Schlechter inwiefern übrigens, gemessen woran? Wie geht man daran, das zu messen? Und wenn ja, wie groß ist überhaupt die Standardabweichung der Elternqualität? Stellen sich manche in ihrer skurrilen Weltsicht tatsächlich vor, dass zwei hasserfüllte, dafür aber heterosexuelle Eltern, die ihre Kinder schlagen und vergewaltigen, für diese Kinder besser sind als zwei liebende Männer oder .... oh Schreck... gar Frauen, weil letztere nicht dem Natur-, Schöpfer- und Volkswillen entsprechen, erstere aber schon?)

Ja, ich würde so etwas unter Umständen sogar lesen. Und dann die Metastudie dazu. Ich lasse mich jederzeit davon überzeugen, dass Schwulenehe bzw. Adoption durch Homosexuelle eine schlechte Idee ist - nur bräuchte es dazu halt Argumente und Evidenz statt Essentialismus und Intuition. Ich gebe nicht vor, zu wissen, welche Kombination von Eltern ideal ist - ich vermute eher, dass es niemand weiß. Und die, die behaupten, es doch zu wissen, kommen mir allgemein etwas um Argumente verlegen vor. Ganz davon abgesehen, dass das Leben nun einmal im Großen und Ganzen zumeist nicht sonderlich ideal verläuft.

In der Gesamtwertung war der Artikel eine parodistische Glanzleistung, die ich sehr gerne gelesen habe.

An einer Stelle hat mir der Artikel allerdings doch nicht so sehr gefallen. Da hat er seine ironische Absicht ein wenig zu deutlich verraten. Wenn er gegen Unisex-Toiletten anschreibt, weiß auch noch der letzte internetzkulturell herausgeforderte Mensch: Jetzt will er uns verarschen.

NetBeans warning against multiple assignments in PHP

ETA: I originally thought that this warning came directly from PHP's E_STRICT setting, but later found out that it was actually a NetBeans warning. I have now updated the title and part of the content accordingly.

I have a test function (*) which contains the following code:


        $line = 'a,b,c';
        $delims = array(';', ',');
     
        $delim = $helper->determineDelimiter($line, $delims);
        echo " $delim/, ";
        echo "<br/>";

        $line = 'a;b;c';
        $delims = array(';', ',');
     
        $delim = $helper->determineDelimiter($line, $delims);
        echo " $delim/; ";
        echo "<br/>";


Now, NetBeans will complain about the re-assignment of $line and $delim.

While I totally understand and support the intention - multiple assignment to the same variable is a smell under most circumstances - it kind of makes me wonder. We're dealing with an imperative language here, local variables are essentially just junk that gets overwritten whenever we please (moreover, lots of core functions overwrite their parameters, but no-one complains about that). And on top of that very basic feature of an imperative language, we impose restrictions borrowed from the functional paradigm, to keep us from shooting ourselves in the foot.

It's not like one had a chance to turn this feature off for this one specific method, I guess?

I can't help finding this a little bit odd. Either the language does give me the chance to code as I please, and kill myself in the process, or it doesn't. Nobody expects assembler to warn you about arbitrarily increasing the instruction pointer, most likely blowing your program to pieces in the process. Having tons of little exlamation marks to the left of my code doesn't help me find the actual mistakes. It is only confusing me, nothing more. The IDE shouldn't add its own warnings on top of the warnings the language will produce... Actually, my original mistake in this posting resulted from me thinking that this was going on under the hood: NetBeans passes the text to a php process and evaluates the resulting warnings.

But alas, the good folks over at the NetBeans factory chose to be wiser than the PHP developers. I think that this was a mistake.




------------------------------------------------------------------------
(*) a very clumsy one, because I didn't get phpunit to run on my puter

Montag, 4. März 2013

How not to code (Magento raeg #1/10.000)

A little poem from the original Magento codebase:
    public function getProduct($productId, $store, $identifierType = null) {
        $loadByIdOnFalse = false;
        if ($identifierType == null) {
            if (is_string($productId) && !preg_match("/^[+-]?[1-9][0-9]*$|^0$/", $productId)) {
                $identifierType = 'sku';
                $loadByIdOnFalse = true;
            } else {
                $identifierType = 'id';
            }
        }
 ... 

Okay. Once and for all: If you have to have parameters go through a regex to find out what type they are, you're definitely doing something wrong. Even with PHP, this is a smell. Not even a code smell. It's the smell of a public toilet that hasn't been cleaned in like 50 years or so. It's code puke.

Donnerstag, 21. Februar 2013

Y Kant Debuggers Show Return Values?

Only recently, a colleague complained that people use chains of methods like

$xyz = $this->getRequest()->getParam('xyz');

His complaint was not about the Law of Demeter though, but about the lack of debuggability. Regardless of whether you "step into" those methods, or "step over" the line, you'll never see the return value of getRequest().

Of course, it is questionable whether

$request = $this->getRequest();
$xyz = $request->getParam('xyz');

is really more desirable from a readability perspective (I think nay; he thinks yay).

But apart from that, the question arises why debuggers are not able (or unwilling) to show me the last return value, or even a stack thereof, so I can "step into" getRequest() and see what it returns to my calling function.

Is this technically impossible for some reason? Or is that feature indeed available, and I just have not found it yet? It doesn't seem to appear in the netbeans php debugger, nor in gdb or any other debugger I've used; or at least it has never presented itself to me in a way that I was able to recognize.

Questions upon questions!