Sunday, July 10, 2011

Avoid Fetch-Object Abuse

Lately I'm finding a lot of instances of the mysql_fetch_object() function being used in a particular codebase I help maintain. Unfortunately, I've yet to see it used correctly. It always seems to be used to retrieve a stdClass object from a query result where mysql_fetch_array() or mysql_fetch_assoc() would be the more appropriate choice.
$row = mysql_fetch_object($result);
$kitten = new Kitten();
$kitten->setName($row->name);
$kitten->setColor($row->color);
...
Put aside the argument that the code should be using PDO or the MySQLi extension instead of the legacy MySQL extension. mysqli_result::fetch_object() and PDOStatement::fetchObject() have the same potential for abuse. The above code is wrong because the returned result is an object but treated like it's an array.

The mysql_fetch_array() and mysql_fetch_assoc() functions are used to retrieve a row from the query's result set. I prefer to use mysql_fetch_assoc() so I can access the values using column names.
  • mysql_fetch_array() - return an array corresponding to the fetched row and move the internal data pointer to the next. The array is indexed numerically if MYSQL_NUM is specified, associatively if MYSQL_ASSOC is specified, or both by default or if MYSQL_BOTH is specified.
  • mysql_fetch_assoc() - return an associative array corresponding to the fetched row and move the internal data pointer to the next. It is the same as calling mysql_fetch_array() using MYSQL_ASSOC.
mysql_fetch_object() on the other hand was designed to create and populate an instance of an object using the row of data.
$kitten = mysql_fetch_object($result, "Kitten");
If mysql_fetch_object() is called without the second argument, the name of the object type to create, then a stdClass object is returned that has public properties named after the result columns to expose the data. There isn't any benefit to this over an array. It is just an object for the sake of having an object, and not a very useful object at that. Incidentally, an array can always be casted to a stdObject later if, for some odd reason, it's needed:
$obj = (object)$array;
An object is a data structure that encapsulates variables to maintain state and related functions to manipulate the state. A stdClass data object just collects values and then exposes them as public properties. It does not observe proper encapsulation, there is no state, and there are no methods to interact with the object. It is no more than an array that uses object-syntax. My rule of thumb is: if you call mysql_fetch_object() without specifying a class name, you're "doing it wrong."

A related point worth mentioning is even a good programmer may run into some difficulty when trying to use mysql_fetch_object() correctly since the function is intrinsically broken (though some will argue differently). The function first creates an instance of the specified class, then populates its internal variables, and lastly invokes the constructor. The purpose of a constructor is to initialize the object's values and resources, but since the constructor is called last the values set from the result row may be overwritten. The programmer must take this into account and guard against it if the objects might be instantiated by both mysql_fetch_object() and new.
class Kitten
{
    private $name;
    private $color;
    ...
    public function __construct() {
        if (!isset($this->name)) {
            $this->name = "Unknown";
        }
        ...
If you're like me and have a large codebase with the misuse of mysql_fetch_object() deeply entangled throughout, it may not be practical to find and fix each instance. The best advice I can offer is to educate yourself and others how the function should be used so its abuse isn't perpetuated. Then, be cautious when using mysql_fetch_object() correctly and understand the process it follows to create and return an object. If not for yourself, then do it for the kittens.

Every time you abuse mysql_fetch_object() God kills a kitten!

Monday, July 4, 2011

Smalltalk Challenge: Post 10 - Conclusions

So here I am, more than 20 hours with Smalltalk and 10 blog posts about my experiences as required by the terms of my challenge. Josh said he chose Smalltalk for me because of the language's history of helping giving rise to object-oriented programming, which he thinks I hate. (For the record I don't hate OO; I hate the awkwardness and complexity its over-zealous application inflicts.) But I think secretly he was hoping it would endear me to Java in the same way as I was hoping OCaml would help him see past Java. Smalltalk gave me a newfound respect, not for OO, but for the language's innovations and lasting influence. If anything in relation to current-day OO practices, my experience confirmed how botched OO adoption has been given what it was intended to be. Regardless, while I don't think I'll be using Smalltalk in the foreseeable future, it was definitely fun to explore and gave me a lot of things to think about.

Smalltalk isn't a popular "mainstream" language like Java or PHP, but it was highly influential on many of them. It's a language that hasn't been afraid to try bold, new ideas. Other languages adopted its innovations; some did so successfully, others not so much. Will new innovations from Smalltalk and its community be just as influential in the future? I can't help but think that if Squeak has successfully abandoned the MVC architecture in favor of Morphic, maybe the days of MVC web frameworks such as Struts, Zend Framework, and Rails are numbered.

Message passing is a key concept in Smalltalk and provides the flexibility of duck typing. But late/dynamic binding prohibits many compiler-time optimizations that could otherwise be performed on statically-compiled code. Is there continued benefit to such an approach now that we're inundated with so many dynamic languages that have (or at least seem to emulate reasonably well) direct invocation, and thus better performance, such as Lua and JavaScript? Perhaps a greater benefit could be realized if message passing was handled asynchronously.

In Smalltalk, everything is an object. Even basic language constructs such as if-statements and while loops have been distilled down to objects and message passing. I respect Kay for intentionally taking an extreme position to force new ways of looking at things, though I believe the "everything is a" mindset can lead to awkward perceptions. The human mind is adept at categorizing things into different classifications exactly because not everything is the same. Ruby claims everything is an object too, which is misleading because it still has basic language constructs. I wonder where the sweet spot between abstraction and reality is, and in what ways can programming languages more accurately reflect how we view the world so we don't end up with with shimmed, over-architectured, spaghetti code.

Overall I found the core concepts of Smalltalk pretty easy to learn (since there are so few), and it was fun to write Smalltalk code and explore objects and Morphs in Squeak's environment. I encourage others who may not be familiar with Smalltalk to spend a little time with it as I did. I can't say it made me a better programmer, but in some sense it made me a better person because I now have a better understanding of history and a lot of things to think about.

Sunday, July 3, 2011

Smalltalk Challenge: Post 9 - Koans

Besides tinkering with turtles and hashes in Squeak, I secretly went back to GNU Smalltalk and went through some of the Smalltalk Koans. Sssh... don't tell Josh!

Programming koans are a series of failing unit tests that a student reads through and corrects. Each test demonstrates a particular concept in the language. They can be a fun way to review one's understanding of a language, and occasionally learn something new. Here's an of a koan:
testSingleCharacterFromString [
    | string |

    string := 'Smalltalk'.

    self expect: (self fillMeIn) toEqual: (string at: 1).
    self expect: (self fillMeIn) toEqual: (string at: 6).
]
When the test suite is run, it displays:
Do not lose hope.  Expected value should equal actual value.

Expected : FILL ME IN
Actual   : $S  (an instance of Character)

TestString#testSingleCharacterFromString has damaged your karma
(in src/koans/TestString.st)
The name of the method indicates it is possible access the characters that make up a string. The test shows how the at: message is passed to a string to obtain a character at the given index. The programmer must replace (self fillMeIn) with the correct value which will allow the test to pass and the student to proceed.
self expect: $S toEqual: (string at: 1).
self expect: $t toEqual: (string at: 6).
This demonstrates that in Smalltalk character instances are preceded by a dollar-sign, and indexes start at 1, not 0 as in many other languages.

Going through the koans, I thought the ones from TestString.st, TestMessage.st, and TestDictionary.st were exceptionally good. My favorite was this one from TestMessage.st, which demonstrates an unintuitive edge-case resulting from Smalltalk's everything-is-an-object and message passing philosophies.
testMessageCascading [
    | value |

    value := 3 + 2; * 100.  "';' separates each message sent to '3'"

    self expect: (self fillMeIn) toEqual: value.

    "Think about it: we are sending multiple messages to '3'."
]
The correct answer is 300. Pretty evil, eh?

Saturday, July 2, 2011

Smalltalk Challenge: Post 8 - Virtual Images

Virtualization is in vogue right now as companies use such technology to run multiple systems on consolidated hardware. Remember, Smalltalk was designed as a language and an environment. No one is about to replace Windows (or Ubuntu, though I'm tempted) with Smalltalk as their operating system, so it makes sense for it to be implemented as a virtual machine.

Similar to products like VMWare Workstation or VirtualBox, most Smalltalk implementations consist of a Virtual machine (VM) application and an image file. The image file contains the definition and state of the Smalltalk environment which is realized by the VM. It may be helpful to think about the image file as a program saved somewhere on your computer's hard drive, and the VM is your computer's processor that executes the code to do something useful.

A Squeak installation consists of four files: a VM executable and three files that make up the image.
  • The VM is the interpretor that "runs" a Smalltalk image.
  • The .sources file contains the core Squeak system and base libraries.
  • The .image file contains the current state of the running system.
  • The .changes file is contains a log of changes made to the system.
You can save the state of the environment at any time while working in Squeak, which is stored between the .image and .changes files. Such snapshots can be loaded later to go back to previous sessions, or shared with others as a means of distribution.

As with most things in life there are advantages and disadvantages with image-based imperative programming. Apparently though the disadvantages outweigh the advantages. The latest standardization attempt of Smalltalk, ANSI/INCITS 319 1998 (ANSI Smalltalk), does away with the old model and specifies a fully declarative model for writing Smalltalk programs. Some reasons for adopting the new model were:
  • Programs could be inaccessible if the image becomes out dated or corrupted.
  • Because the same image is used for development and production, is makes it very difficult to support situations where the development and target execution environments must be different (security restrictions, for example).

I did a quick screen recording to show what writing code in the environment is like. In Squeak, the programmer writes the code for a class and its methods directly in the System Browser window. At the top of the window are selection lists; from left to right, they list class categories, classes, method categories, and methods. Below them is a text area where the code is typed and saved. When the code is saved, Squeak automatically compiles it and makes it available to the rest of the system.

Friday, July 1, 2011

Smalltalk Challenge: Post 7 - Turtles Ahoy!

I can remember going down to the computer lab while in grade school and using Logo on the then state-of-the-art Apple IIe computers. Supposedly Logo allowed students to explore mathematics in a tangible way, but I don't remember doing much more than drawing shapes by moving the little "turtle" around on the green screen and I still don't have much confidence in my math skills 20 years later. I don't think Logo helped kindle my interest in computers, either; games like The Oregon Trail and Where in the World is Carmen Sandiego and the Commodore 64 computer were far more influential to me. But drawing little green triangles and squares was fun. And while Logo may not have been as influential in my education as Papert would have hoped, it was extremely influential to Smalltalk. In fact, the graphics Pen object is actually very similar to Logo's turtle.

The Pen class is used for drawing. It inherits from BitBlt which allows it to perform raster drawing on any form its bound to. The World is a form itself, so a pen bound to it will appear to draw on top of other windows and elements! The following example draws an octagonal-spiral on top of anything that's visible in the environment, centered around the point of a mouse click:

pen := Pen new.
    pen roundNib: 8;
    color: Color random;
(Sensor waitButton; redButtonPressed)
    ifTrue: [
            pen up;
            goto: Sensor mousePoint;
            down.
        x := 1.
        10 timesRepeat: [
            4 timesRepeat: [pen go: 10 * x; turn: 45].
            x := x + 2]].

A new Pen instance is created, the size of the line it draws is set to 8px by the roundNib: message (what better thickenss to draw octagons with?), and the color of the pen's line is randomly set by the color: message.

Sending a down message is like placing a pen against a sheet of paper. When the pen is against the paper and is moved, a line is drawn. There is also the up message which is like lifting the pen up away from the paper so it can be repositioned without making any marks.

The pen is moved about the screen using the goto:, go: and turn: messages. Like its Logo progenitor, the pen object responds to messages relative to its current position and direction. When asked to move 10px, the pen moves forward in which ever direction it's pointing in. Turning the pen 45 degrees and moving another 10px would result in a 45° angle drawn. The direction of the pen's motion can also be set with north, east, west, south, and direction.