Sunday, December 13, 2015

On faking QObject-derived classes (part 1)

Introduction

After reading Michael Feathers' book Working Effectively with Legacy Code, I recently got interested in techniques for making code more testable.  One of these techniques is Extract Interface, which can be used to replace objects of a certain class with fake versions. While trying to apply this to some legacy code, I stumbled upon a problem.  This post describes that problem and how I solved it.  However, I do have my doubts concerning the elegance of my solution. So therefore: feel free to comment and share alternative solutions!

Starting point

Our starting point is a class derived from QObject:

Because this is a QObject-derived class, it can use methods like setObjectName and objectName, but it can of course also have its own member functions like doFooStuff. Our purpose now is to extract an interface for the Foo class, so we can create a FakeFoo class as a replacement for Foo.

Extracting the interface

Faking the Foo class seems easy at first sight: following Feathers' advice, all I should do is extract a FooInterface and let my Foo and FakeFoo implement it. My first attempt in doing this, looked as follows:

Unfortunately, this resulted in the following compiler errors using g++ 4.9.2:


failed_attempt.cpp: In function ‘int main()’:
failed_attempt.cpp:29:14: error: ‘class FooInterface’ has no member named ‘setObjectName’
     fakeFoo->setObjectName("fake foo");
              ^
failed_attempt.cpp:30:27: error: ‘class FooInterface’ has no member named ‘objectName’
     std::cout << fakeFoo->objectName().toStdString() << std::endl;
                           ^
failed_attempt.cpp:34:14: error: ‘class FooInterface’ has no member named ‘setObjectName’
     realFoo->setObjectName("real foo");
              ^
failed_attempt.cpp:35:27: error: ‘class FooInterface’ has no member named ‘objectName’
     std::cout << realFoo->objectName().toStdString() << std::endl;

Needless to say I was a bit disappointed in realizing that FooInterface indeed did not have a setObjectName or objectName function. Inspired by the section The Case of the Onion Parameter and The Case of the Aliased Parameter in Feathers' book, my current best attempt so far in solving this issue consists of creating a QObjectInterface with these methods and letting FooInterface derive from that:

This works, as is visible in the output of the program:


fake foo
Foo::doFakeFooStuff()
real foo
Foo::doFooStuff()
But my current solution has several drawbacks:
  1. I need to add every QObject member function that I use, to my QObjectInterface.
  2. If I want QObjectInterface and FooInterface to be real interfaces, that forces me to do the implementations of every QObject member function that I use in both my Foo and FakeFoo class. These implementations are just forwardings of method calls to the QObject class. That is quite mechanical, cumbersome and errorprone. I don't like that.
Is this really the best way to go? Or have I overlooked more elegant solutions that don't require me to do all that mechanical, cumbersome and errorprone work?

Conclusion

I did find a way to fake QObject-derived classes, but my solution requires quite some brain-dead QObject-method implementing in the original class and its fake version. I am open for more elegant designs. Please enlighten me! All code in this blog post is available in a public Gist.

Sunday, November 22, 2015

Testing GitHub gists

Occasionally, i day-dream about sharing some random thoughts about certain aspects of software development. An important practical tool needed for this kind of idea-sharing, is being able to nicely embed code-snippets in my blog posts. Googling around for solutions, I came across GitHub gists. This is my first test to embed small pieces of code into my blog posts. If you see a "Hello world!" program below this paragraph, it means my test succeeded...

If you also see a "Hello people!" program below this second paragraph, then it means I'm able to display several different pieces of code into my blog posts.

If you think you know better solutions for embedding code-snippets into Blogger articles, do not hesitate to post a comment!

Wednesday, August 12, 2015

Show your Google Contacts on a map using Google Fusion Tables

Just for the fun of it, I decided to investigate ways to display my Google contacts on a map.  One solution I use already quite a while is the Contacts on map app on my Android smartphone.  But I also want a desktop solution that doesn't require me to enter my Google credentials on a website.  Finding such a solution turned out to be hard, so in the end, I decided to be creative and construct my own solution.  These are the steps I followed.  Google Fusion Tables to the rescue!

Step 1: export your Google contacts

  1. Surf to http://contacts.google.com
  2. In the left menu-bar, under More, find Export and go to the old Google Contacts (because the new Google Contacts doesn't allow you to export your contacts yet).
  3. In the old Google Contacts, select More followed by Export and export your contacts in Outlook CSV format (the Google CSV format didn't work for me):

Step 2: import your CSV file in Google Fusion tables

  1. Surf to http://drive.google.com
  2. Check if you have Google Fusion Tables available under New / More.  If you don't have it yet, install the Google Fusion Tables app.
  3. Create a new Google Fusion Table using New / More / Google Fusion Tables.
  4. Under Import new table use From this computer and select and upload your contacts.csv file.  Use comma as separator character and select UTF-8 character encoding:

Step 3: select the column to use as a location

  1. First, you can remove some unnecessary columns using the Select Columns menu item from the Rows 1 tab.
  2. Then, pick the column you want to use as your location column (e.g. Home Address), and change its type to Location.
  3. Now go to the tab called Map of Home Address and select Home Address as Location column:

  4. Press Begin geocoding and once that's finished, you should see a nice map of all your contacts.

Step 4: finetune

To change several map feature styles and the content of the info window that appears when you click on a contact from the map, go to the tab of the map and select Change map.  It is even possible to display your contacts in a heat map.  My map finally looks like this:


Conclusion

If you keep all your contacts centralized in Google contacts, then visualizing for example their home and work address on a map is rather easy using Google Fusion Tables.  I use these kind of maps a lot when I go somewhere and want to say hi to friends that I haven't seen in a while.

Comments and suggestions on this article are more than welcome!

Friday, August 2, 2013

Kleuterfilosofie... of hoe een kind probeert de wereld te snappen.

Naar aanleiding van nog maar eens de zoveelste filosofische vraag die ik vandaag van Jenne kreeg, heb ik besloten om een lijst aan te leggen met leuke uitspraken.  Van tijd tot tijd zal deze lijst worden aangevuld.  Enjoy!

02/08/2013: "Papa, een éénwieler, wat is dat eigenlijk?  Is dat een voorwiel of een achterwiel?"

02/08/2013: "Papa, waarom staat dat standbeeld hier?" (nabij het Leiemonument in het Koning Albertpark te Kortrijk).

Sunday, October 21, 2012

Godverdomme! Mijn Brompton plooifiets is gestolen!

Op zaterdag 20 oktober 2012 werd ik spijtig genoeg nog maar eens geconfronteerd met de oneerlijkheid in onze maatschappij. Mijn Brompton plooifiets ter waarde van 1199 EUR bleek verdwenen na een cinemabezoek in Antwerpen. Ten eerste is het wat betreft de prijs best jammer dat dit dure fietsje aan mij ontvreemd werd, maar het zorgt ook voor heel wat praktische beslommeringen: zo moet ik nu weer met de bus pendelen naar mijn werk (= vroeger opstaan en afhankelijk zijn van de busuren), en kan ik 's ochtends wegens tijdsgebrek niet meer mee naar de schoolpoort om ons 3-jarig zoontje uit te wuiven.

Aan de oneerlijke stelers: GROTE KLOOTZAKKEN ZIJN JULLIE!  Ik hoop uit het diepste van mijn hart dat jullie branden in de hel!

Bij deze geef ik hieronder alle informatie ivm de diefstal, in de hoop dat het iets oplevert...

Tijdstip diefstal

Zaterdag 20 oktober 2012 tussen 18u45 en 21u45.

Plaats van de diefstal

Vlakbij het adres 'De Keyserlei 56B, 2000 Antwerpen', ergens tussen Juwelier Slaets
en M&G Diamonds (coördinaten: 51,217442 N 4,419108 E).  De fiets was met een kabelslot (zie foto) vastgemaakt aan een andere damesfiets en een verlichtingspaal.  Hoewel er veel andere fietsen naast stonden en er die avond op De Keyserlei veel volk was, werd het kabelslot toch doorgeknipt (zie foto).

Type fiets

Zwarte Brompton plooifiets (nieuw van maart 2012)
Brompton RN-versie (S6RN)
6 versnellingen (2 links, 3 rechts)

Typische herkenningspunten

  • S-Type stuur (dit is een T-vormig sport stuur)
    (Merk op dat de meeste andere Brompton fietsen een U-vormig stuur hebben, dus het stuur van mijn fiets zou moeten opvallen tussen de traditionele Bromptons).
  • Witte sticker 1 (zie foto):
    Serial No: 1201194029

  • Witte sticker 2 (zie foto):
    BS 6102-1:1992
    EN 14764:2005
  • Ingegraveerd frame-nummer: 324088


  • Naamsticker van 'Vlerick Fietsen' bevindt zich bovenaan op de bovenbuis.
  • Helaas had ik deze fiets nog niet laten merken bij de politie :-(

Contact

Indien je mijn fiets toevallig vindt, te koop aangeboden krijgt of op een tweedehands website ziet, gelieve mij dan te contacteren via het emailadres Bart.Vandewoestyne@telenet.be of via mijn GSM-nummer +32 478 397 697.
Alle tips zijn meer dan welkom!

Friday, September 28, 2012

Book review: The Art of Debugging with GDB, DDD and Eclipse (Chapter 6).

Special Topics

What if it doesn't even compile or load?

Phantom line numbers in syntax error messages

Sometimes, the line number from the compiler error message is not very informative. Typically, the problem is a missing closing brace or semicolon. To locate it, you can start by commenting out the function where you suspect the problem to be. Don't be surprised by linker errors if you do this, but stay cool and use binary search principles to locate the location of the problem.

Missing Libraries

If you have a program that uses functions from another .o file, you can get 'undefined reference to f' errors from the linker.

A library can be static (functions become part of the resulting executable file) or dynamic (the functions are not physically attached to the calling code until the program is actually executed).

To create a static library and compile your main program with it:

  gcc -g -c b.c
  ar rc lib88.a b.o
  gcc -g a.c -l88 -Lz
With the -L option, you tell the linker in what directories other than the current one it should look for the functions.

To create a dynamic library (to avoid space-wasting separate copies of the same library) and then link to it, use:

gcc -fPIC -c b.c
gcc -shared -o lib88.so b.o
gcc -g a.c -l88 -Lz
The resulting program executable will merely contain a notation that this program makes use of the library lib88.so. The linking itself will now occur at runtime. With the ldd command, you can check which libraries a program needs, and where the OS finds them:
  ldd a.out
To add a library to the OS's normal library search path, in bash you can do:
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/Debug/z
  export LD_LIBRARY_PATH

For missing library problems, ofteh the root of the problem lies in a program called pkgconfig. The default directory that pkgconfig searches for .pc files depends on the location of pkgconfig itself, and must sometimes be adapted by setting the environment variable PKG_CONFIG_PATH.

Debugging GUI programs

The example will be for the curses library, but the applied principles are valid for other GUI libraries as well.

Debugging Curses Programs

For debugging curses programs, you must tell GDB to have the program execute in a different terminal window than the one that GDB is running in with the tty command. First, go to another window and run the tty command there to determine the ID for that window. Then, in the GDB window you type:

  tty /dev/pts/8
You must also type something like
  sleep 10000
in the execution window, so that your keyboard input to that window wil go to that program rather than to the shell.

In DDD, you can arrange a separate window for execution of the program by choosing 'View | Execution Window'. Don't type the sleep command into that window, as DDD does that for you.

In Eclipse, you can use the option 'C/C++ Attach to Local Application'. First start your program in a separate shel window, then select Run | Open Debug Dialog and from the list, choose the process you wish GDB to attach.

Tuesday, September 11, 2012

Book review: The Art of Debugging with GDB, DDD and Eclipse (Chapter 5).

Debugging in a multiple-activities context

Debugging Client/Server Network Programs

This section presents only a short example. The most important tricks to remember are:

GDB had a jump command, but in general you should use this command with caution.

Including errno.h can be useful for your debugging, as is the use of the strace program for checking the result of system calls.

In really complex network debugging cases, you might want to use a program to track individual TCP/IP packets.

Debugging threaded code

The POSIX standard Pthreads is used for the example in this section.

Modern operating systems use timesharing to manage multiple running programs in such a way that they appear to the user to execute simultaneously. After a certain timeslice, processes are preempted and a context switch occurs. Because you do not know the order in which threads will be scheduled, the debugging is more difficult.

Threads vs. processes: a thread is designed to occupy less memory and its context switch time is less than that for processes. Threads are therefore also sometimes called leightweight processes.

The global variables of the parent program in a threaded environment are shared by all threads and serve as the main method of communication between the threads.

Preemptive thread management policy: a thread in a program can be interrupted at any time by another thread. This makes bugs not always reproducible.

Each time a new thread is created, GDB announces it. To know what each thread is doing, you can use the GDB info threads command. The asterisk in the output shows you what thread you're in. You can inspect the stack of any thread by switching to that thread and then issuing the bt command:

  thread 3
  bt
Some other examples which should speak for themselves:
  break 88 thread 3
  break 88 thread 3 if x==y

In DDD, select Status | Threads, and a window will pop up, displaying all threads in the manner of the GDB info threads. You can click a thread to switch the debugger's focus to it. In DDD, you cannot make a breakpoint thread-specific, so you have to use the DDD Console and issue GDB commands.

Eclipse constantly displays your thread list, as opposed to having to request it, as in DDD. The call stack is shown in the thread list. In Eclipse, you can set a breakpoint for a specific thread: right-click and select 'Filtering'.

Debugging parallel applications

  • Shared memory: Multiple CPUs all have access to some common physical memory.
  • Message passing: code running on each CPU can only access that CPU’s local memory, and it communicates with the others by sending messages.
Message-Passing Systems

The book's examples use MPI.

GDB allows you to dynamically attach the debugger to an already-running process, using the process number: first find process number, then

  gdb programname 2776

Shared-memory systems

  • True Shared Memory: OpenMP, internally makes use of threads.
  • Software Distributed Shared-Memory Systems
Quite some difficulties arise when debugging this kind of programs. Pay attention!

Extended Example

Most important message from this example: pay attention with line numbers! They are not always what you think they are! For the rest, nothing too interesting here...